Editable .pdf fields disappear (but visible on fie

2019-01-25 21:47发布

问题:

First off, let me thank the SO community for helping me so many times in the past; you guys are an amazing resource!

At my job I work on a web application that uses PDF templates created in Scribus and the iText Java library to populate the templates with data from our database. Sometimes, a user-supplied field is required and not touched by iText. When the .pdf is downloaded, a field is edited, and a copy is saved with Evince the resulting file will not display the edited text upon reopen. However, upon focus of an edited field it will show the saved text. Unfocus, text disappears. Cut the text, paste back into field; it stays visible - until you save and reopen the document. After save and reopen the original problem manifests. I've found many extremely similar posts regarding this problem, but none of the solutions to which seem to work for me.

Also, the problem is quirky. If I open the Scribus template (the .pdf file untouched by iText) with Evince, then edit fields and save, they will show up properly upon reopen. Once the library touches the template, however, the problem occurs. Similarly, I can reproduce the issue with PDF files I have found while searching for the cause of this problem; like this one:

http://www.quask.com/samples/pdfforms/pcpurchase.pdf

This leads me to believe that the misbehaving files may be corrupted in some way, and that iText may be the cause of my problem, but iText isn't the only avenue in which I can reproduce the issue so I'm not sure what to think. I can't seem to find a working solution among the many I've seen. Is anybody familiar enough with this issue to be able to tell me where I can get to the bottom of this or offer some insight regarding the tools I'm using? Chances are good that if you search for the issue using google I've seen it..

I'm using Ubuntu 12.04 (precise), Evince 3.4.0, iText 2.1.5, and can try to fill you in on any other relevant details upon request. I'm apprehensive to post any code as I'm not sure it is Kosher, and it works fine for constructing forms except with this particular issue; let alone the fact that I can reproduce the problem without the use of our webapp.

This is my first post here, and I am a novice programmer (still in school!) so please do let me know if I have violated any conventions or could improve my future inquiries in any way.

Thanks for any help you can offer!

回答1:

An inspection of the files supplied by jbowman in the comments to his question --- with special regard to the password field (which is one of the fields entually filled in by evince) --- shows:

Template.pdf

  • is the original form which was generated by Scribus PDF Library 1.4.1.svn;
  • contains an AcroForm with 9 fields and the flag NeedAppearances set to true;
  • has the password field (named passwordField) which contains an empty value and a normal appearance stream painting a rectangle with an empty text.

after_itext.pdf

  • is the original form edited by iText 2.1.5, unfortunately not in append mode which would have made analysis easier;
  • contains an Acroform with 8 fields (the member number field has been filled in and flattened) without a NeedAppearances flag;
  • has the password field (named passwordField:u4woYY1FK9) value and appearances left untouched.

after_itext_edited.pdf

  • is the form formerly edited by iText now edited by some other software (evince) in append mode;
  • contains an Acroform with 8 fields without a NeedAppearances flag; the only changes have been made to the fields passwordField:u4woYY1FK9 and memberPrefix:u4woYY1FK9:
  • has the password field (named passwordField:u4woYY1FK9) with a new associated value asdf but has left its appearances untouched;
  • has the member prefix field (named memberPrefix:u4woYY1FK9) with a new associated value asdf but has left its appearances untouched.

Thus, the observed behavior that the value by default is not shown, is to be expected:

The final Acroform has no NeedAppearances flag. This flag is defined in the specification ISO 32000-1:2008 as:

A flag specifying whether to construct appearance streams and appearance dictionaries for all widget annotations in the document (see 12.7.3.3, “Variable Text”). Default value: false.

Thus, your PDF document in its final form says: No appearances for widgets (e.g. AcroForm field visualizations) need to be generated, take the appearances from the document.

The appearance of the password field from the document is the original one, the rectangle with the empty text.

So you see this empty rectangle.

When you click into the field, the PDF viewer prepares for editing its contents and therefore displays the value as it sees fit.

If editing PDF files with evince is intended to have visible results, evince upon changing the value of the fields must also add updated appearance streams or make sure the AcroForm NeddAppearances flag is set. Therefore, this is where evince failed.



回答2:

I have accepted mkl's answer as it hits the nail on the head regarding why the fields do not display properly, and contains much more information than I can provide regarding the issue. However, the suggested fix in the answer's comments did not work because the documents are generated (in this particular case) using iText 2.1.5's PdfCopyFields, which does not respect (strips) the original document's NeedAppearances flag, and calling setNeedAppearances(true) for AcroForm did not solve the issue because of this.

Hacking the createAcroForms() method in PdfCopyFieldsImp to include the line

form.put(PdfName.NEEDAPPEARANCES, PdfBoolean.PDFTRUE);

is what ultimately seems to have solved the issue for me. With this addition, evince properly displays changes to fields after saving and reopening the document.