This is what I have currently:
User submits form data and gets a "download PDF" link.
The link points to script which generates an XFDF file on the fly and outputs the XFDF file after setting the appropriate headers, etc.
The XFDF file points to a password-protected PDF, which is the generic PDF form that uses the XFDF data to fill in the fields.
What I would like:
User clicks the "download PDF" link.
XFDF is generated on the fly (no file written to server).
PDF and XFDF are merged server-side using generic PDF. Contents of final PDF are output to user same as XFDF was originally.
Neither the XFDF nor the final PDF are ever saved to server.
I was looking at pdftk, which has a few options for dealing with FDF/XFDF files, but all of which assume that a) the original XFDF file exists as a file on the server and b) that the resulting PDF should be output as a file on the server.
Also, pdftk is 4 years old.
I was wondering if:
a) there was a newer equivalent to pdftk out there?
b) if there was a way, using a newer pdftk-like tool or using pdftk, to use dynamic paths so that the data never has to exist in file form on the server?
I recently learned about the built-in input/output streams using php://
but I'm still really fuzzy on how to use it, but maybe this would be a good place for this?
I took khkremer's advice myself and built a small .net exe in C# to create a PDF from an xfdf file based on the itextsharp library. It will still need to be called using passthru, but it's nice and tiny. My version also has the option to insert a hidden field into a pdf since I needed that functionality for my project.
You will need to download and add the reference to the iTextSharp.text.pdf assembly.
Hope it helps!
using System;
using System.IO;
using iTextSharp.text.pdf;
namespace PDFBrain
{
class Program
{
// args:
// 0 => template
// 1 => xfdf
// 2 => outputfile
// 3 => flatten output file?
static void Main(string[] args)
{
if (args == null)
{
Console.Out.WriteLine("No arguments were provided. Exiting.");
return;
}
if (args[0] == "create")
{
if (args.Length != 5)
{
Console.Out.WriteLine("Wrong number of arguments were provided. Exiting.");
return;
}
CreatePDF(args[1], args[2], args[3], args[4]);
}
if (args[0] == "hidden")
{
if (args.Length != 3)
{
Console.Out.WriteLine("Wrong number of arguments were provided. Exiting.");
return;
}
InsertHiddenIdField(args[1], args[2]);
}
}
public static void CreatePDF(string templ, string xfdf, string output, string flatten)
{
PdfReader template = new PdfReader(templ);
XfdfReader xfdfReader = new XfdfReader(xfdf);
PdfStamper stamper = new PdfStamper(template, new FileStream(output, FileMode.Create));
stamper.AcroFields.SetFields(xfdfReader);
stamper.FormFlattening = flatten == "true" ? true : false;
stamper.Writer.CloseStream = false;
stamper.Close();
}
public static void InsertHiddenIdField(string templ, string output)
{
PdfReader template = new PdfReader(templ);
PdfStamper stamper = new PdfStamper(template, new FileStream(output, FileMode.Create));
TextField clientID = new TextField(stamper.Writer, new iTextSharp.text.Rectangle(10,750,60,770), "hdnClientID");
clientID.Visibility = BaseField.HIDDEN;
stamper.AddAnnotation(clientID.GetTextField(),1);
stamper.Close();
}
}
}
There are commercial applications that do that (you can find some at pdfstore.com), but with some programming, you can create your own using the same library that pdftk is using to process PDF files: iText (http://itextpdf.com/) There is also a .NET version - iTextSharp.
By doing that, you can access your data from your Java or .NET program, and it never needs to exist in file form, you could get it out of the database directly.
You can also recompile pdftk with a newer version of iText - that way, you can the latest PDF processing capabilities and the ease of use that you have with pdftk. You would still need a XFDF file however.
"you can access your data from your Java" - easy to say hard to do :)))))
I wrote a command line utility in Java, and a php example how to fill pdf forms dynamically on-the-fly (no files written to disk) on the sever side and serve filled in pdf documents to the browser:
https://sourceforge.net/projects/pdfformfiller2/
Its input format is much simpler than XFDF.
Escaping (encoding) function are provided in the php example.
It fixes a bug in Adobe Reader UTF-8 support.