PDF Processing with Perl
by Detlef GrothSeptember 21, 2007
Example Material
Although its capabilities are limited in this area, you can also use PDF::Reuse to create PDF documents. If you want to create more sophisticated documents you should investigate other PDF-packages like PDF::API2 from Alfred Reibenschuh or Text::PDF from Martin Hosken. However PDF::Reuse is sufficient to create a simple PDF to use in later examples. The following listing should be rather self explanatory.
# file: examples/create-pdfs.pl
use strict;
use PDF::Reuse;
mkdir "out" if (!-e "out") ;
foreach my $x (1..4) {
prFile("out/file-$x.pdf");
foreach my $y (1..10) {
prText(35,800,"File: file-$x.pdf");
prText(510,800,"Page: $y");
foreach my $z (1..15) {
prText(35,700-$z*16,"Line $z");
}
# add graphics with the prAdd function
# stroke color
prAdd("0.1 0.1 0.9 RG\n");
# fill color
prAdd("0.9 0.1 0.1 rg\n");
my $pos = 750 - ($y * 40);
prAdd("540 $pos 10 40 re\n");
prAdd("B\n");
if ($y < 10) {
prPage();
}
}
prEnd();
}
Open a new file with with prFile($filename) and close it with prEnd. Between those two calls, add text with the prText command. You can also draw graphics by using the low level command prAdd with plain PDF markup as parameter. Start a new page with prPage. prFile starts the first one automatically, so you need to add a new page only if your document has more than one page. Be aware that for the prText(x,y,Text) command the origin of the coordinate system is on the left bottom of the page.
As an example of adding PDF markup with prAdd, the code creates a red rectangle with blue borders. In case you would like to add more graphics or complex graphics to your PDF, you can study the examples of the PDF reference manual. If so, consider switching to PDF::API2 or Text::PDF instead of using prAdd, as they both provide a comfortable layer of abstraction over the PDF markup language.
Combining PDF Documents
PDF::Reuse's main strength is the modification and reassembling of existing PDF documents. The next example assembles a new file from the example material.
# file: examples/combine-pdfs.pl
use strict;
use PDF::Reuse;
prFile("out/resultat.pdf");
prDoc('out/file-1.pdf',1,4);
prDoc('out/file-2.pdf',2,9);
prDoc('out/file-3.pdf',8);
prDoc('out/file-4.pdf');
prEnd();
Again, prFile($filename) opens the file. Next, the prDoc($filename, $firstPage, $lastPage) calls add to the new file various page ranges from the example file. The arguments $firstPage and $lastPage are optional. Omit both to add the entire document. If only $firstPage is present, the call will add everything from that page to the end. Finally, prEnd closes the file.
Reusing Existing PDF Files
With PDF::Reuse it is possible to use existing PDF files as templates for creating new documents. Suppose that you have a file customer.txt containing a list of customers to whom to send a letter. You've used a tool to create a PDF document, such as OpenOffice.org or Adobe Acrobat, to produce the letter itself. Now you can write a short program to add the date and the names and addresses of your customers to the letter.
# file: examples/reuse-letter.pl
use PDF::Reuse;
use Date::Formatter;
use strict;
my $date = Date::Formatter->now();
$date->createDateFormatter("(DD).(MM). (YYYY)");
my $n = 1;
my $incr = 14;
my $infile = 'examples/customer.txt';
prFile("examples/sample-letters.pdf");
prCompress(1);
prFont('Arial');
prForm("examples/sample-letter.pdf");
open (my $fh, "<$infile") || die "Couldn't open $infile, $!\n aborts!\n";
while (my $line = <$fh>) {
my $x = 60;
my $y = 760;
my ($first, $last, $street, $zipCode, $city, $country) = split(/,/, $line);
last unless $country;
prPage() if $n++ > 1 ;
prText($x, $y, "$first $last");
$y -= $incr;
prText($x, $y, $street);
$y -= $incr;
prText($x, $y, $zipCode);
prText(($x + 40), $y, $city);
$y -= $incr;
prText($x, $y, $country);
prText(60, 600, "Dear $first $last,");
prText(400, 630, "Berlin, $date");
}
prEnd();
close $fh;
After opening the file with prFile, the call to prCompress(1) enables PDF compression. prFont sets the file's font. The always-available options are Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic, Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique, Helvetica, Helvetica-Bold, Helvetica-Oblique, and Helvetica-BoldOblique. Set the font size with prFontSize. The default font is Helvetica, with 12 pixel size.
The rest of the code is a simple loop over the file containing the customer data to filling the template with prText.

