Cara mengisi anotasi kotak teks PDF

Aug 21 2020

Saya dapat mengisi anotasi kotak teks dengan kode berikut, tetapi teks tidak akan muncul di pembaca tertentu seperti Adobe Acrobat, meskipun itu muncul di Chrome dan peramban berbasis Webkit lainnya. PDF yang saya coba isi tidak menggunakan AcroForms atau FDF. Saya menggunakan Apache PDFBox, tetapi saya tidak percaya ada banyak perbedaan dalam pustaka PDF, bahkan di seluruh bahasa / platform.

// edited for brevity
PDAnnotation annotation = doc.getPages().get(0).getAnnotations().get(0);
COSDictionary cosObject = annotation.getCOSObject();
cosObject.setString(COSName.V, content);

Dokumen contoh adalah IRS formulir W-4 .

Apa yang sudah saya coba sejauh ini

Saya telah mencoba membandingkan keluaran PDF saya dengan dokumen yang diisi di Chrome, tetapi satu-satunya perbedaan yang saya lihat adalah di properti tampilan default (DA). Saya sudah mencoba mengatur konten teks tampilan default seperti ini, tetapi tidak berhasil:

COSString defaultAppearance = (COSString)cosObject.getItem(COSName.DA);
COSString newAppearance = new COSString(defaultAppearance.getString() + "0 0 Td (" + value + ") Tj");
cosObject.setItem(COSName.DA, newAppearance);

Saya juga mengotak-atik beberapa bendera yang kedengarannya menjanjikan:

int FLAG_PRINT = 4;
int FLAG_READ_ONLY = 64;
annotation.setAnnotationFlags(annotation.getAnnotationFlags() | FLAG_PRINT | FLAG_READ_ONLY);

Saya juga mencoba properti lain:

cosObject.setString(COSName.CONTENTS, content);

Saya yakin bagian yang relevan dalam spesifikasi PDF 1.7 adalah 12.7.4.3.


Apa yang saya lewatkan?

Jawaban

TilmanHausherr Aug 21 2020 at 01:12

PDF Anda memang menggunakan bidang acroform. Anotasi widget adalah representasi visual dari lapangan. Yang ingin Anda lakukan adalah menyetel bidangnya. Berikut contoh SetField.java dari unduhan kode sumber. Sebut saja dengan parameter berikut: nama file, nama kolom (nama depan adalah "topmostSubform [0] .Page1 [0] .Step1a [0] .f1_01 [0]") dan nilai.

Untuk mendapatkan nama bidang, unduh PDFDebugger dan arahkan mouse ke bidang yang ingin Anda setel.

Dan inilah tampilan bidang setelah disetel:

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.pdfbox.examples.interactive.form;

import java.io.File;
import java.io.IOException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDCheckBox;
import org.apache.pdfbox.pdmodel.interactive.form.PDComboBox;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDListBox;
import org.apache.pdfbox.pdmodel.interactive.form.PDRadioButton;
import org.apache.pdfbox.pdmodel.interactive.form.PDTextField;

/**
 * This example will take a PDF document and set a form field in it.
 *
 * @author Ben Litchfield
 *
 */
public class SetField
{
    /**
     * This will set a single field in the document.
     *
     * @param pdfDocument The PDF to set the field in.
     * @param name The name of the field to set.
     * @param value The new value of the field.
     *
     * @throws IOException If there is an error setting the field.
     */
    public void setField(PDDocument pdfDocument, String name, String value) throws IOException
    {
        PDDocumentCatalog docCatalog = pdfDocument.getDocumentCatalog();
        PDAcroForm acroForm = docCatalog.getAcroForm();
        PDField field = acroForm.getField(name);
        if (field != null)
        {
            if (field instanceof PDCheckBox)
            {
                if (value.isEmpty())
                    ((PDCheckBox) field).unCheck();
                else
                    ((PDCheckBox) field).check();
            }
            else if (field instanceof PDComboBox)
            {
                field.setValue(value);
            }
            else if (field instanceof PDListBox)
            {
                field.setValue(value);
            }
            else if (field instanceof PDRadioButton)
            {
                field.setValue(value);
            }
            else if (field instanceof PDTextField)
            {
                field.setValue(value);
            } 
        }
        else
        {
            System.err.println("No field found with name:" + name);
        }
    }

    /**
     * This will read a PDF file and set a field and then write it the pdf out
     * again. <br>
     * see usage() for commandline
     *
     * @param args command line arguments
     *
     * @throws IOException If there is an error importing the FDF document.
     */
    public static void main(String[] args) throws IOException
    {
        SetField setter = new SetField();
        setter.setField(args);
    }

    private void setField(String[] args) throws IOException
    {
        PDDocument pdf = null;
        try
        {
            if (args.length != 3)
            {
                usage();
            }
            else
            {
                SetField example = new SetField();
                pdf = PDDocument.load(new File(args[0]));
                example.setField(pdf, args[1], args[2]);
                pdf.save(args[0]);
            }
        }
        finally
        {
            if (pdf != null)
            {
                pdf.close();
            }
        }
    }

    /**
     * This will print out a message telling how to use this example.
     */
    private static void usage()
    {
        System.err.println("usage: org.apache.pdfbox.examples.interactive.form.SetField <pdf-file> <field-name> <field-value>");
    }
}