Why don't the iText 7 form field values print?

2019-09-18 23:19发布

问题:

I have a PDF with forms that was generated with iText 7. However, when I fill out the form and attempt to print, the form values do not show up; only the form outline shows. How do I generate form fields that will display the value when printed?

A sample form generator:

import java.io.FileNotFoundException;
import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfFormField;
import com.itextpdf.forms.fields.PdfTextFormField;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.border.Border;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.renderer.CellRenderer;
import com.itextpdf.layout.renderer.DrawContext;

/**
 * @author Lucas Vander Wal
 *
 */
public final class TestForm {

    private static final Logger log = LoggerFactory.getLogger(TestForm.class);

    private static final PageSize LETTER_SIZE = new PageSize(612, 792),
            LETTER_SIZE_LANDSCAPE = LETTER_SIZE.rotate();

    private static final PdfFont FONT;
    static {
        try {
            FONT = PdfFontFactory.createFont();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static final float FONT_SIZE_12 = 12;

    /**
     * @param args
     */
    public static void main(String[] args) {
        log.info("Running pdf generation...");
        new TestForm().generate("formTest.pdf");
        log.info("Done with pdf generation.");
    }

    private Document doc;
    private PdfDocument pdfDoc;
    private PdfAcroForm form;

    public TestForm() {
    }

    /**
     * Generates the timesheet pdf and saves it to the given file location
     * 
     * @param outputFile
     */
    public void generate(String outputFile) {
        try {
            pdfDoc = new PdfDocument(new PdfWriter(outputFile));
            doc = new Document(pdfDoc, LETTER_SIZE_LANDSCAPE);
            // set document properties
            doc.setFontSize(10);
            float marginSize = doc.getTopMargin();
            doc.setMargins(marginSize / 2, marginSize, marginSize / 2, marginSize);

            form = PdfAcroForm.getAcroForm(pdfDoc, true);

            // build the form
            buildUserInfo();
            // close the document
            doc.close();

        } catch (FileNotFoundException e) {
            log.warn("Unable to save to file: " + outputFile, e);
        }

    }

    private void buildUserInfo() {
        // build the user info table
        Table userTable = new Table(4).setBorder(Border.NO_BORDER).setWidthPercent(100).setMargin(0).setPadding(0);
        // add 4 text entry fields
        this.addFieldToTable(userTable, "nameEmployee", "Name of Employee:");

        // add the table to the document
        this.doc.add(userTable);

    }

    private void addFieldToTable(Table t, String fieldName, String fieldLabel) {
        t.addCell(new Cell().add(fieldLabel).setPadding(5));
        Cell cell = new Cell().setPadding(5);
        cell.setNextRenderer(new CellRenderer(cell) {

            @Override
            public void draw(DrawContext drawContext) {
                super.draw(drawContext);
                PdfTextFormField field = PdfFormField.createText(
                        drawContext.getDocument(), getOccupiedAreaBBox().decreaseHeight(5), fieldName, "",
                        FONT, FONT_SIZE_12);
                form.addField(field);
            }

        });
        t.addCell(cell);
    }
}

回答1:

PDF form fields have a visibility setting that affects the ability to print. See this Adobe page for more information.

The form fields need to be set to 'VISIBLE', using the setVisibility() method on PdfFormField objects. This iText 7 documentation explains how to set forms to 'HIDDEN','VISIBLE_BUT_DOES_NOT_PRINT', and 'HIDDEN_BUT_PRINTABLE', however it doesn't mention setting to visible, and in fact, visible is not one of the static options in PdfFormField.

The three values listed above correspond to the integers 1, 2, and 3, and on a hunch, I set the visibility to 0, and the form field displayed when printed!

In summary, call PdfFormField.setVisibility(0) to create form fields that are printable.