Link to home
Start Free TrialLog in
Avatar of bennybutler
bennybutler

asked on

Fill a pre-existing PDF with info from database

I'm writing a web based custom replacement for Act for my company.  Currently we do a lot of mail merging from Act to Word.  I need to duplicate this functionality, and I think using PDF's is going to be the only option.

I've found plenty of info on using PHP to create PDF's but frankly that would take AGES to program all of the PDF's I need.  I need PHP to be able to FILL the fields in a PDF that I create in windows.

I've found FPDI, which is close, but not really what's needed.  I'm going to take all my word docs, and print them as pdf's.  Then I'm going to take adobe designer, or whatever it's called, and add form fields.  I need PHP to be able to fill in those fields.

ORRR, I've written my own simple templating system with HTML before, by just using str_replace and a bunch of ##FNAME##, ##LNAME## sections...

Thoughts?
Avatar of m1tk4
m1tk4
Flag of United States of America image

Have you considered creating PDFs as forms and using XFDF to fill in the data? This is how I do PDF-based invoices.

http://partners.adobe.com/public/developer/en/xml/xfdf_2.0_draft.pdf

Let me know if you have to know besides everything that's in the spec is to set content-type to vnd.adobe.xfdf and make sure you are passing an exact content-length. I.e. after you build the data in $xfdf,

        header ("Content-Type: application/vnd.adobe.xfdf");
        header ("Content-Length: ". strlen($xfdf));
        header ('Content-Disposition: inline; filename="form.xfdf"');
        header ("Cache-Control:");
        echo $xfdf;
ASKER CERTIFIED SOLUTION
Avatar of Eddie Shipman
Eddie Shipman
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here's the link http://65.98.60.178/~austin1/eddie/fdftest.php

here's the source:

<?

// Here, you can also get your results from a database...
$firstname = "Eddie";

/*
 All FDF/PDF form fields, no matter their type, are accessed by the
 Title(Name)(/T)
 followed by the Value (/V) keys. For List Boxes & Combo Boxes,
 you only need to refer to
 the Option fields when you are populating the boxes with new data
 using the /Opt key.
 form field Titles and Values are case sensitive. If you misspell or use
 incorrect casing, the form field will be ignored, and you will not
 receive an error.
 The File (/F) key links this ASP (FDF) with a specific PDF file.
 You must specify a complete absolute URL.
 Unfortunately, relative URLs do not work as intended.
 After the Title (/T), Value (/V), Option (/Opt), and File (/F) keys,
 enter the respective "value" within parentheses, e.g., /T (txtFirstName).
 You may enter these values as literals or as an abbreviated Response.Write.
 e.g. /T (<% = strTitle (closing asp delimiter here)). The following
 ASP will provide examples of this.
*/

header("content-type: application/vnd.fdf");

echo <<<FDFstuff
%FDF-1.2
1 0 obj
<< 
/FDF
<< 
/Fields [
<< /T (txtFirstName) /V ($firstname) >> 
<< /T (txtExperience)
/V (9 months in HTML, 6 months in ASP & VBScript, 1 month in JavaScript & DHTML) >>
<< /T (chkVBS) /V (Yes) >> 
<< /T (radGender) /V (Male) >> 
<< /T (selSite) /V (microsoft.com) >> 
<< /T (selColor) /Opt [(#6699FF) (#0000CC) (#990033) (#000080) (#FFCC00)] /V (#000080) >> 
]
/F (http://65.98.60.178/~austin1/eddie/FormTest.pdf) >>
 >>
endobj
trailer
<<  /Root 1 0 R  >>
%%EOF
FDFstuff;
?>

BTW, there is javascript code in the PDF to submit the data to an
ASP script. this can be modified with Acrobat.
Avatar of bennybutler
bennybutler

ASKER

Not sure If I'm going to use this, but it is exactly the answer to my question.  The reason I might NOT use it is because the mail merges will need to generate the same letter, say 100 times, each on a different page... I know this will work for a single page, but not sure if it will do this.

The FORM part is not necessary at all, but it was the best way I could see to do it.  The output here is the final results, the data is NEVER submitted to anything.  If I could just do a str_replace() and replace parts of the PDF (safely) it would be fine, but I can't confirm that can be done yet.  

Thanks!
to use it for mail merges, you use a form and a loop to create the fdf. It is not that difficult.

The form would submit to itself and each time , it would read a value from the database and replace
the data you need to replace then you have a javascript function in your PDF to print it when it
is loaded.

No real hard work there.
>>say 100 times, each on a different page...

That's how I do the invoices - a batch would contain a PDF file that is a form and a hundred or so .xfdf files that are data. You then can print the .xfdf files directly from Windows Explorer - this will open Acrobat and load the template.
Well, XFDF is really only extending the FDF spec by making it XML format and adding some other
overhead.

This is similar to when Quicken's IIF was converted to OSX.
This would be the XFDF conversion for the FDF above, simple enough...
But what do how do we tell a web browser that is is downloading XFDF
instead of standard XML?


<?xml version="1.0" encoding="UTF-8"?>
  <xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
  <f href="http://65.98.60.178/~austin1/eddie/FormTest.pdf"/>
  <fields>
    <field name="txtFirstName">
      <value>$firstname</value>
    </field>
    <field name="txtExperience">
      <value>9 months in HTML, 6 months in ASP &amp; VBScript, 1 month in JavaScript &amp; DHTML</value>
    </field>
    <field name="chkVBS">
      <value>Yes</value>
    </field>
    <field name="radGender">
      <value>Male</value>
    </field>
    <field name="selSite">
      <value>microsoft.com</value>
    </field>
    <field name="selColor">
      <value>#000080</value>
    </field>
  </fields>
</xfdf>
Let me get this straight...

Eddie, your echo <<<FDFStuff line populates a single form (btw, I'm barely familiar with that <<< notation, I'll look it up later) and If I have one of those echo's for each of my recordsets, I will end up with with a PDF that has many copies of the same page, each with the recordset's correct data, then I can send that all to the printer at once?

Or Do I need a smaller loop, say just the fields[] section?


m1tk4 are you generating 100 xfdfs to print, or just one  that will do 100 pages in a SINGLE pdf?  I need a single pdf for the users to print, not a lot of separate ones.

Eddie, somewhere in my searches I saw the different header strings (filetype) that you send for a xfdf vs a fdf.  IE may be able to figure it out if you just tell it the name is just .xfdf.

Just as a test I created an empty .fdf and .xfdf files on the desktop and they both were associated to acro7.
[quote]I'm barely familiar with that <<< notation[/quote]

That is called a heredoc, check the php documentation.

Eddie, I am almost to a final solution.  I have pretty much decided on FDF because I have learned that using templates in my pdf files I can have a dynamic number of pages, I just tell, with an FDF call, the PDF which page to use and it will insert the page and populate it.

I know that in PHP to do that with the fdftoolkit I would use the fdf_add_template() function.  The problem is adobe no longer gives out the FDFToolkit api, so I can't compile PHP with it. I could spit out the FDF manually if I could just find an example of what the FDF looks like with a template called.  BUT I CAN'T FIND AN EXAMPLE.

I'd be fine with an example of how an xfdf calling an add_template would work as well.
I have never seen such a beast otherwise I'd post it here. The FDF that I posted is a simple
basci FDF. I have the FDFToolkit so let me look at the docs and see if I can find anything.
While searching for info on FDF and templates, I happened across this PHP script that does
exactly what you want...It merges and emails. You will probably have to modify it for your
own use.

http://mysite.verizon.net/vzep00rh/formhandler.html