Another way to version javascript, CSS and other such files (say background images), is to add a parameter on the URL that they link to - for example edit.js?ver=1
.
When the version changes, you update the parameter - ver=2
. This ensures that it will be re-fetched.
An added bonus is that you can easily search for ?ver=
in your source code and possibly do a global replace.
I'm always disappointed when I read "we are using iText 2.1" because that's really not a wise choice as explained here, but this is a question about design, so here is a possible approach:
You create a new document Document document = new Document();
(step 1), you create a PdfWriter
instance (step 2), you open the document (step 4), and you add content in a loop (step 4):
- You have different templates, and by templates we mean: existing PDF documents with fillable fields (AcroForms). You fill them out using
PdfStamper
and AcroFields
(see your code on StackOverflow). This results in separate "flattened" form snippets kept in memory.
- If you want to keep these snippets together, you can do so by creating a
Document
/PdfWriter
instance to create a new PDF in memory that combines all the snippets that belong together. You get a snippet like this: PdfImportedPage snippet = writer.getImportedPage(reader, 1);
and you add the snippet
to the writer
using the addTemplate()
method.
- You get the combined result using
PdfImportedPage combined = writer.getImportedPage(reader, 1);
, you wrap the result in an image like this: Image image = Image.getInstance(combined);
You add the image to the document: document.add(image);
Step 2 could be omitted. You could add the different snippets straight to the document
that is initially created. Repeats steps 1 to 3 as many times as needed, and close the document (step 5).
Omitting step 2 will result in a lower XObject nesting count, but keeping step 2 isn't problematic.
In pseudo code, we'd have:
[1.] The outer loop (the large part to the right of the schema, marked PdfWriter
)
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, os);
// step 3
document.open();
// step 4
for (int i = 0; i < parameters.length; i++)
document.add(getSnippetCombination(writer, parameters[i]));
// step 5
document.close();
[2.] The creation of one unit (the arrow marked PdfWriter
in the middle)
public Image getSnippetCombination(PdfWriter w, Parameters parameters) {
// step 1
Document document = new Document();
// step 2
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document, baos);
// step 3
document.open();
// step 4
PdfContentByte canvas = writer.getDirectContent();
for (int i = 0; i < parameters.getNumberOfSnippets(); i++)
canvas.addTemplate(getSnippet(writer, parameters.getSnippet(i)),
parameters.getX(i), parameters.getY(i));
// step 5
document.close();
// Convert PDF in memory to From XObject wrapped in Image object
PdfReader reader = new PdfReader(baos.toByteArray());
PdfImportedPage page = w.getImportedPage(reader, 1);
return Image.getInstance(page);
}
[3.] Filling out data in separate snippets (the arrows marked PdfStamper
)
public PdfTemplate getSnippet(PdfWriter w, Snippet snippet) {
// Using PdfStamper to fill out the fields
PdfReader reader = new PdfReader(snippet.getBytes());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, baos);
stamper.setFormFlattening(true);
AcroFields form = stamper.getAcroFields();
// fill out the fields; you've already implemented this
stamper.close();
// return the template
PdfReader reader = new PdfReader(baos.toByteArray());
return w.getImportedPage(reader, 1);
}
There may be better solutions, for instance involving XFA, but I don't know if that's feasible as I don't know if the templates (the light blue part in my schema) are always the same. It would also involve creating new templates in the XML Forms Architecture.
Best Answer
For web application, to access user's Certificate store (or Digital Signature in USB Token or Smartcard through Certificate store), from modern browsers, which no more supports java applest or activeX, using Browser extension is the solution.
One such free browser extension is Signer.Digital. Working can be checked at https://web.signer.digital. Links to extension, sample project, libs etc is also available.
You may use any server side pdf library with this extension to add signature to pdf.
For PHP, if more choices of native pdf library is not available, you may also run java library on Tomcat in Javabridge and proxy it from Apache.