Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

PDF::API2 Questions

by akwe-xavante (Novice)
on Mar 13, 2012 at 21:52 UTC ( #959471=perlquestion: print w/replies, xml ) Need Help??
akwe-xavante has asked for the wisdom of the Perl Monks concerning the following question:

Hoping for a little Advice before i start!

To start i'm not a programmer at all really, however i do manage and i'm in need of a little initial guidance on a new and challenging project. I have a html webform to get data which is sent to a perl script for processing, a few sums, a little formatting then the script prints a html page to the browser for printing. At the same time the same data is sent by email as a html email.

I want to improve on this and challenge myself a little further and instead i hope to use the same html webform and its data to create a nice little pdf document and send it as an attachment by email and either open a new tab as a pdf document for saving and or for printing or if that's pushing my luck then simply print html data to the browser as a webpage for printing.

I have a silly little script already proving that on my Linux box i can create a PDF document and send it as an atachment in an email

The document will be a one page invoice basically.


How many options are there regarding the creation of the PDF document?

What's the best way to go about this?

Is it possible to create a nice little PDF Document or some other file type as a template incorporating VariableNames where required, open this document and somehow import data into those variables then SaveAs a new document ready for the next process?

Or will it be best to create each and every document from scratch every time?

Thank you in advance

Replies are listed 'Best First'.
Re: PDF::API2 Questions
by Eliya (Vicar) on Mar 13, 2012 at 22:45 UTC
    Or will it be best to create each and every document from scratch every time?

    For one, it depends on the complexity of the document.  With simple/short documents it's probably "best" to create them from scratch every time — in case you want to operate at the PDF level yourself (like you would when using PDF::API2), and not use some higher level layout package like latex.

    As for working with PDF templates, you should be aware that PDF is not a language for laying out documents, but rather a language for low-level description/rendering of drawing instructions, like "print those glyphs or lines at position x,y".  In other words, it doesn't do automatic paragraph layout, text block wrapping, page breaks, etc.

    Also, the format doesn't lend itself particularly well to being templated directly, as it typically contains compressed content streams (which you could only modify in uncompressed form), and because the PDF file holds an index table specifying the byte offset of every "object" in the file (not the document index you see in a PDF viewer, but an internal one). When you modify one object in size, all offsets of the objects that follow in the document will have to be adjusted accordingly.

    In case you really want to do templating directly at the PDF level, I'd suggest you use pdftk in combination with a template in uncompressed form.  In this case, you could essentially use any text templating module (though it would of course require a reasonable understanding of how PDF works), and pdftk would then handle compressing the document and recomputing the internal object offsets.  I wouldn't recommend this approach, however, unless you are (or want to become) familiar with the guts of PDF, and are making only minor changes, like filling in a few names or addresses, etc.

      Thank you for your reply

      Much of your words don't mean much at all at this point, but Iím sure they will at some point in the future.

      My knowledge of PDF::API2 at this moment is restricted to creating a one page PDF document with just one centralised line of text, that's the full extent of my knowledge right now

      My assumption is that my PDF document will be a simple one right now. Billing address aligned left, my details aligned right but opposite each other. An invoice number and date. Details about the service or repair carried out. A list of parts / materials used and costs involved. A total, a box where i can add cautionary notes, comments and observations the customer should be aware of etc, in other words a box where additional text can be added at the bottom. An image / logo perhaps, a clickable link to visit my website.

      I don't want make things unnecessarily complex at this early stage.

      I receive many an automatically created PDF receipt on a daily basis from my suppliers, i suppose i should analyse them to see what's achievable and work on that, perhaps use LibreOffice and M$ office to create something as a goal to aim for! Then for now explore PDF::API2 to see what i can achieve.

      Meanwhile if anybody else can offer a little advice that would be good too, Iím sure Iíll be back with Oooodles of questions and problems to resolve in the near future.

Re: PDF::API2 Questions
by roboticus (Chancellor) on Mar 14, 2012 at 10:07 UTC


    CPAN has many modules for creating and altering PDF files. I've never tried it, but since you're doing html already, perhaps PDF::FromHTML might be a good starting point for you.


    When your only tool is a hammer, all problems look like your thumb.

Re: PDF::API2 Questions
by MidLifeXis (Monsignor) on Mar 14, 2012 at 13:07 UTC

    See also PDF::Template and PDF. If you use HTML::Template data structures, you can use them to drive PDF::Template (with a new template file, of course). Write your logic once, and display generate render it to multiple output formats.


Re: PDF::API2 Questions
by flexvault (Monsignor) on Mar 14, 2012 at 10:35 UTC


    I just did this last week, and I have to say it was quite complicated. I haven't had to move the "cursor" on paper since plotter days. Not to discourage you, but you are taking on a difficult task.

    Since you're on Linux and your creating the html already, why not use a system utility to convert the html to pdf. I 'googled' and '' and found several linux utilities that convert html to pdf. If you test it from the command line, then you could call the 'system' function or 'qx//' then use the output(file) to attach in the email.

    I did use PDF::API2 and it worked great. I created a template by using an array:

    my @document = ( " ", " ", "Email Address: $Email", "Company Name: $Company", ... );
    Each element in the array represents a line in the pdf document. That way the subroutine could process each line in a while loop. All the variables were initialized before the call to the PDF_Create subroutine, which is what I think you want to do.

    Good Luck

    "Well done is better than well said." - Benjamin Franklin

Re: PDF::API2 Questions
by CountZero (Bishop) on Mar 14, 2012 at 20:48 UTC
    I regularly have to make PDF-documents based upon some templates and configuration or data files.

    As templating engine I use Template Toolkit, as lay-out engine I use LaTeX.

    My Perl script reads the configuration file, collects the data (from spreadsheets, text files or a database), the templating engine combines data and template and produces a LaTeX file that gets compiled into a PDF-file thanks to the LaTeX processor.


    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
Re: PDF::API2 Questions
by kcott (Chancellor) on Mar 15, 2012 at 08:19 UTC

    I see lots of good advice already.

    You may find PDF::API2::Simple to be a gentler introduction. I successfully used it a couple of years ago to achieve something similar to what you describe here. It's a wrapper around PDF::API2, so you still have access all the functionality of that module.

    There's also a number of example (examples/*) and user contributed (contrib/*) scripts listed in the PDF::API2 MANIFEST that may prove useful.

    -- Ken

      Thank you everybody for your input and advice.

      Already spent a good few hours working out how to get data from a HTML Webform into the CGI script then getting that info into a simple unstructured / formatted PDF document and then attaching the PDF document to an email using user info such as the persons name and email address and all's working a treat so far.

      The mail recipient is recieving the email and the attachment with the data i put into the PDF document.

      Very Happy So Far

      I've decided that i will need to get roughly a minimum of 43 bits of data into the PDF document and upto a maximum of 53 parts of info, this includes one perhaps two images / logo's. Some of the data is blocks of text. I haven't tried to get an image in yet, that's todays task

      Today's task is also to find out how to get clickable links in there, "Go to MyWebsite" "send MeAnEmail"

      Today's task is also to work out / research how to position this data in a specific location on the page

      Wish me luck!

        Some of the data is blocks of text...

        Don't know whether you've already come across PDF::TextBlock (based on PDF::API2) — it can make life easier with respect to automatic text wrapping/justification, etc.

Re: PDF::API2 Questions
by Anonymous Monk on Mar 16, 2012 at 13:21 UTC
    Hello guys, I am trying to open pdf and write something to it and save new pdf. There is a problem when i am writing text to the pdf encoded in utf8. The text doesn't look as it should.
    my $utftext=qq(SOme UTF text); #$utftext=encode("utf8", decode("cp1251", $utftext) ) ; #$utftext=encode("utf8", $utftext ) ; my $pdf; $pdf = PDF::API2->open('first.pdf'); my $page_number = 1; my $page = $pdf->openpage($page_number); my $font = $pdf->corefont('Verdana');# ,-encoding => 'utf8' my $text = $page->text(); $text->font($font, 30); $text->translate(359, 713); $text->text("$utftext"); $pdf->saveas('mysaved.pdf');

      I'm having another formatting issue or probably an issue placing data onto the page in the PDF document.

      I have a column of numbers with decimal places, in each row the number may have a different number of decimal places before the Dot

      Data is placed on the page achored in the bottom left corner so the vertical alignment of the numbers do not line up

      Is there a simple way for me to get these numbers aligned vertically about the dot in the column of numbers

      Not sure i described my problem very well but hoping somebody knows what i'm trying to achieve and help somehow

        Worked it out

        $txt->text_right(Hello World);
Re: PDF::API2 Questions
by clanrbr (Novice) on Mar 22, 2012 at 14:09 UTC
    Is there any way to print the content of a pdf on a webpage without saving the new pdf you have made on the hard drive ? For example. You are making a new PDF , write smth to it and after you are done except saveas is there any other way to display or write it the another $string and print it out after that. Like print "Content-type: application/pdf\n\n"; I am talking about using AIP2.

      Have you looked at the ->saveas method in the PDF::API2 documentation? Documented right below it is the ->stringify method which is documented as

      Returns the document as a string.

      Have you tried using that method? How could that documentation be made more clear?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://959471]
Approved by Corion
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2018-06-23 05:16 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (125 votes). Check out past polls.