Search in sources :

Example 1 with PDAcroForm

use of com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm in project PdfBox-Android by TomRoush.

the class PDDocument method getSignatureFields.

/**
 * Retrieve all signature fields from the document.
 *
 * @return a <code>List</code> of <code>PDSignatureField</code>s
 * @throws IOException if no document catalog can be found.
 */
public List<PDSignatureField> getSignatureFields() throws IOException {
    List<PDSignatureField> fields = new ArrayList<PDSignatureField>();
    PDAcroForm acroForm = getDocumentCatalog().getAcroForm();
    if (acroForm != null) {
        for (PDField field : acroForm.getFieldTree()) {
            if (field instanceof PDSignatureField) {
                fields.add((PDSignatureField) field);
            }
        }
    }
    return fields;
}
Also used : PDField(com.tom_roush.pdfbox.pdmodel.interactive.form.PDField) ArrayList(java.util.ArrayList) COSArrayList(com.tom_roush.pdfbox.pdmodel.common.COSArrayList) PDSignatureField(com.tom_roush.pdfbox.pdmodel.interactive.form.PDSignatureField) PDAcroForm(com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm)

Example 2 with PDAcroForm

use of com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm in project PdfBox-Android by TomRoush.

the class PDDocument method addSignature.

/**
 * This will add a signature to the document. If the 0-based page number in the options
 * parameter is smaller than 0 or larger than max, the nearest valid page number will be used
 * (i.e. 0 or max) and no exception will be thrown.
 * <p>
 * Only one signature may be added in a document. To sign several times,
 * load document, add signature, save incremental and close again.
 *
 * @param sigObject is the PDSignatureField model
 * @param signatureInterface is an interface whose implementation provides
 * signing capabilities. Can be null if external signing if used.
 * @param options signature options
 * @throws IOException if there is an error creating required fields
 * @throws IllegalStateException if one attempts to add several signature
 * fields.
 */
public void addSignature(PDSignature sigObject, SignatureInterface signatureInterface, SignatureOptions options) throws IOException {
    if (signatureAdded) {
        throw new IllegalStateException("Only one signature may be added in a document");
    }
    signatureAdded = true;
    // Reserve content
    // We need to reserve some space for the signature. Some signatures including
    // big certificate chain and we need enough space to store it.
    int preferredSignatureSize = options.getPreferredSignatureSize();
    if (preferredSignatureSize > 0) {
        sigObject.setContents(new byte[preferredSignatureSize]);
    } else {
        sigObject.setContents(new byte[SignatureOptions.DEFAULT_SIGNATURE_SIZE]);
    }
    // Reserve ByteRange, will be overwritten in COSWriter
    sigObject.setByteRange(RESERVE_BYTE_RANGE);
    signInterface = signatureInterface;
    // Create SignatureForm for signature and append it to the document
    // Get the first valid page
    int pageCount = getNumberOfPages();
    if (pageCount == 0) {
        throw new IllegalStateException("Cannot sign an empty document");
    }
    int startIndex = Math.min(Math.max(options.getPage(), 0), pageCount - 1);
    PDPage page = getPage(startIndex);
    // Get the AcroForm from the Root-Dictionary and append the annotation
    PDDocumentCatalog catalog = getDocumentCatalog();
    PDAcroForm acroForm = catalog.getAcroForm();
    catalog.getCOSObject().setNeedToBeUpdated(true);
    if (acroForm == null) {
        acroForm = new PDAcroForm(this);
        catalog.setAcroForm(acroForm);
    } else {
        acroForm.getCOSObject().setNeedToBeUpdated(true);
    }
    PDSignatureField signatureField = null;
    if (!(acroForm.getCOSObject().getDictionaryObject(COSName.FIELDS) instanceof COSArray)) {
        acroForm.getCOSObject().setItem(COSName.FIELDS, new COSArray());
    } else {
        COSArray fieldArray = (COSArray) acroForm.getCOSObject().getDictionaryObject(COSName.FIELDS);
        fieldArray.setNeedToBeUpdated(true);
        signatureField = findSignatureField(acroForm.getFieldIterator(), sigObject);
    }
    if (signatureField == null) {
        signatureField = new PDSignatureField(acroForm);
        // append the signature object
        signatureField.setValue(sigObject);
        // backward linking
        signatureField.getWidgets().get(0).setPage(page);
    } else {
        sigObject.getCOSObject().setNeedToBeUpdated(true);
    }
    // TODO This "overwrites" the settings of the original signature field which might not be intended by the user
    // better make it configurable (not all users need/want PDF/A but their own setting):
    // to conform PDF/A-1 requirement:
    // The /F key's Print flag bit shall be set to 1 and
    // its Hidden, Invisible and NoView flag bits shall be set to 0
    signatureField.getWidgets().get(0).setPrinted(true);
    // Set the AcroForm Fields
    List<PDField> acroFormFields = acroForm.getFields();
    acroForm.getCOSObject().setDirect(true);
    acroForm.setSignaturesExist(true);
    acroForm.setAppendOnly(true);
    boolean checkFields = checkSignatureField(acroForm.getFieldIterator(), signatureField);
    if (checkFields) {
        signatureField.getCOSObject().setNeedToBeUpdated(true);
    } else {
        acroFormFields.add(signatureField);
    }
    // Get the object from the visual signature
    COSDocument visualSignature = options.getVisualSignature();
    // Distinction of case for visual and non-visual signature
    if (visualSignature == null) {
        prepareNonVisibleSignature(signatureField);
        return;
    }
    prepareVisibleSignature(signatureField, acroForm, visualSignature);
    // Create Annotation / Field for signature
    List<PDAnnotation> annotations = page.getAnnotations();
    // Make /Annots a direct object to avoid problem if it is an existing indirect object:
    // it would not be updated in incremental save, and if we'd set the /Annots array "to be updated"
    // while keeping it indirect, Adobe Reader would claim that the document had been modified.
    page.setAnnotations(annotations);
    // take care that page and acroforms do not share the same array (if so, we don't need to add it twice)
    if (!(annotations instanceof COSArrayList && acroFormFields instanceof COSArrayList && ((COSArrayList<?>) annotations).toList().equals(((COSArrayList<?>) acroFormFields).toList()) && checkFields)) {
        PDAnnotationWidget widget = signatureField.getWidgets().get(0);
        // use check to prevent the annotation widget from appearing twice
        if (checkSignatureAnnotation(annotations, widget)) {
            widget.getCOSObject().setNeedToBeUpdated(true);
        } else {
            annotations.add(widget);
        }
    }
    page.getCOSObject().setNeedToBeUpdated(true);
}
Also used : PDField(com.tom_roush.pdfbox.pdmodel.interactive.form.PDField) PDAnnotation(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation) COSDocument(com.tom_roush.pdfbox.cos.COSDocument) PDAcroForm(com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm) COSArrayList(com.tom_roush.pdfbox.pdmodel.common.COSArrayList) COSArray(com.tom_roush.pdfbox.cos.COSArray) PDAnnotationWidget(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget) PDSignatureField(com.tom_roush.pdfbox.pdmodel.interactive.form.PDSignatureField)

Example 3 with PDAcroForm

use of com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm in project PdfBox-Android by TomRoush.

the class PDDocument method addSignatureField.

/**
 * This will add a list of signature fields to the document.
 *
 * @param sigFields are the PDSignatureFields that should be added to the document
 * @param signatureInterface is an interface whose implementation provides
 * signing capabilities. Can be null if external signing if used.
 * @param options signature options
 * @throws IOException if there is an error creating required fields
 * @deprecated The method is misleading, because only one signature may be
 * added in a document. The method will be removed in the future.
 */
@Deprecated
public void addSignatureField(List<PDSignatureField> sigFields, SignatureInterface signatureInterface, SignatureOptions options) throws IOException {
    PDDocumentCatalog catalog = getDocumentCatalog();
    catalog.getCOSObject().setNeedToBeUpdated(true);
    PDAcroForm acroForm = catalog.getAcroForm();
    if (acroForm == null) {
        acroForm = new PDAcroForm(this);
        catalog.setAcroForm(acroForm);
    }
    COSDictionary acroFormDict = acroForm.getCOSObject();
    acroFormDict.setDirect(true);
    acroFormDict.setNeedToBeUpdated(true);
    if (!acroForm.isSignaturesExist()) {
        // 1 if at least one signature field is available
        acroForm.setSignaturesExist(true);
    }
    List<PDField> acroformFields = acroForm.getFields();
    for (PDSignatureField sigField : sigFields) {
        sigField.getCOSObject().setNeedToBeUpdated(true);
        // Check if the field already exists
        boolean checkSignatureField = checkSignatureField(acroForm.getFieldIterator(), sigField);
        if (checkSignatureField) {
            sigField.getCOSObject().setNeedToBeUpdated(true);
        } else {
            acroformFields.add(sigField);
        }
        // Check if we need to add a signature
        if (sigField.getSignature() != null) {
            sigField.getCOSObject().setNeedToBeUpdated(true);
            if (options == null) {
            // TODO ??
            }
            addSignature(sigField.getSignature(), signatureInterface, options);
        }
    }
}
Also used : PDField(com.tom_roush.pdfbox.pdmodel.interactive.form.PDField) COSDictionary(com.tom_roush.pdfbox.cos.COSDictionary) PDAcroForm(com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm) PDSignatureField(com.tom_roush.pdfbox.pdmodel.interactive.form.PDSignatureField)

Example 4 with PDAcroForm

use of com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm in project PdfBox-Android by TomRoush.

the class PDFMergerUtility method mergeAcroForm.

/**
 * Merge the contents of the source form into the destination form for the
 * destination file.
 *
 * @param cloner the object cloner for the destination document
 * @param destAcroForm the destination form
 * @param srcAcroForm the source form
 * @throws IOException If an error occurs while adding the field.
 */
private void mergeAcroForm(PDFCloneUtility cloner, PDDocumentCatalog destCatalog, PDDocumentCatalog srcCatalog) throws IOException {
    try {
        PDAcroForm destAcroForm = destCatalog.getAcroForm();
        PDAcroForm srcAcroForm = srcCatalog.getAcroForm();
        if (destAcroForm == null && srcAcroForm != null) {
            destCatalog.getCOSObject().setItem(COSName.ACRO_FORM, cloner.cloneForNewDocument(srcAcroForm.getCOSObject()));
        } else {
            if (srcAcroForm != null) {
                if (acroFormMergeMode == AcroFormMergeMode.PDFBOX_LEGACY_MODE) {
                    acroFormLegacyMode(cloner, destAcroForm, srcAcroForm);
                } else if (acroFormMergeMode == AcroFormMergeMode.JOIN_FORM_FIELDS_MODE) {
                    acroFormJoinFieldsMode(cloner, destAcroForm, srcAcroForm);
                }
            }
        }
    } catch (IOException e) {
        // if we are not ignoring exceptions, we'll re-throw this
        if (!ignoreAcroFormErrors) {
            throw new IOException(e);
        }
    }
}
Also used : PDAcroForm(com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm) IOException(java.io.IOException)

Example 5 with PDAcroForm

use of com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm in project PdfBox-Android by TomRoush.

the class MainActivity method fillForm.

/**
 * Fills in a PDF form and saves the result
 */
public void fillForm(View v) {
    try {
        // Load the document and get the AcroForm
        PDDocument document = PDDocument.load(assetManager.open("FormTest.pdf"));
        PDDocumentCatalog docCatalog = document.getDocumentCatalog();
        PDAcroForm acroForm = docCatalog.getAcroForm();
        // Fill the text field
        PDTextField field = (PDTextField) acroForm.getField("TextField");
        field.setValue("Filled Text Field");
        // Optional: don't allow this field to be edited
        field.setReadOnly(true);
        PDField checkbox = acroForm.getField("Checkbox");
        ((PDCheckBox) checkbox).check();
        PDField radio = acroForm.getField("Radio");
        ((PDRadioButton) radio).setValue("Second");
        PDField listbox = acroForm.getField("ListBox");
        List<Integer> listValues = new ArrayList<>();
        listValues.add(1);
        listValues.add(2);
        ((PDListBox) listbox).setSelectedOptionsIndex(listValues);
        PDField dropdown = acroForm.getField("Dropdown");
        ((PDComboBox) dropdown).setValue("Hello");
        String path = root.getAbsolutePath() + "/FilledForm.pdf";
        tv.setText("Saved filled form to " + path);
        document.save(path);
        document.close();
    } catch (IOException e) {
        Log.e("PdfBox-Android-Sample", "Exception thrown while filling form fields", e);
    }
}
Also used : PDField(com.tom_roush.pdfbox.pdmodel.interactive.form.PDField) PDCheckBox(com.tom_roush.pdfbox.pdmodel.interactive.form.PDCheckBox) ArrayList(java.util.ArrayList) PDComboBox(com.tom_roush.pdfbox.pdmodel.interactive.form.PDComboBox) PDAcroForm(com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm) IOException(java.io.IOException) PDDocumentCatalog(com.tom_roush.pdfbox.pdmodel.PDDocumentCatalog) PDRadioButton(com.tom_roush.pdfbox.pdmodel.interactive.form.PDRadioButton) PDDocument(com.tom_roush.pdfbox.pdmodel.PDDocument) PDTextField(com.tom_roush.pdfbox.pdmodel.interactive.form.PDTextField) PDListBox(com.tom_roush.pdfbox.pdmodel.interactive.form.PDListBox)

Aggregations

PDAcroForm (com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm)14 PDField (com.tom_roush.pdfbox.pdmodel.interactive.form.PDField)8 PDDocument (com.tom_roush.pdfbox.pdmodel.PDDocument)6 PDSignatureField (com.tom_roush.pdfbox.pdmodel.interactive.form.PDSignatureField)4 File (java.io.File)4 Test (org.junit.Test)4 COSDictionary (com.tom_roush.pdfbox.cos.COSDictionary)2 PDDocumentCatalog (com.tom_roush.pdfbox.pdmodel.PDDocumentCatalog)2 PDPage (com.tom_roush.pdfbox.pdmodel.PDPage)2 COSArrayList (com.tom_roush.pdfbox.pdmodel.common.COSArrayList)2 PDAnnotation (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation)2 PDAnnotationWidget (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget)2 PDTextField (com.tom_roush.pdfbox.pdmodel.interactive.form.PDTextField)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 ArrayList (java.util.ArrayList)2 AffineTransform (com.tom_roush.harmony.awt.geom.AffineTransform)1 COSArray (com.tom_roush.pdfbox.cos.COSArray)1 COSDocument (com.tom_roush.pdfbox.cos.COSDocument)1 COSName (com.tom_roush.pdfbox.cos.COSName)1