Barium Scoorge
Barium Scoorge

Reputation: 2028

Apache Pdfbox flattening fails when source is loaded from using ClassLoader

I'm facing a strange issue with pdfbox 2.0.19 inside a Spring application.

The following code fills a pdf document with forms inputs.

The template is loaded through pdfIn :

Any clue on with this ?

The class code :

    @Override
    public File generateFeeInvoice(InvoiceData invoiceData) {
        //Load file using ClassLoader
        ClassLoader classLoader = this.getClass().getClassLoader();
        File pdfIn = new File(classLoader.getResource("invoice.pdf").getFile());

        //Load file through filesystem
        //String pathDoc = "~/Documents/invoice.pdf";
        //File pdfIn = Paths.get(pdfInPath).toFile();

        File pdfOut = Files.createTempFile(PDF_OUT_PREFIX, PDF_OUT_SUFFIX).toFile();
        PDDocument pDDocument = PDDocument.load(pdfIn);
        PDAcroForm form = pDDocument.getDocumentCatalog().getAcroForm();

        setFields(form, feeInvoiceData);

        List<PDField> fields = new ArrayList<>(form.getFields());

        //Below code fails when using pdfIn from a resource
        form.flatten(fields, true);

        pDDocument.save(pdfOut);
        pDDocument.close();

        return pdfOut;
    }

    private void setFields(PDAcroForm form, InvoiceData invoiceData) {
        String blackText = BLACK_TEXT;
        String whiteText = WHITE_TEXT;

        setField(form, blackText, FIELD_CLIENT_CODE,
                invoiceData.getClientCode());
    }

    private void setField(PDAcroForm form, String da, String fieldName, String fieldValue) throws IOException {
        PDVariableText field = (PDVariableText) form.getField(fieldName);
        field.setDefaultAppearance(da);
        field.setValue(fieldValue);
    }

Exception stacktrace :

    java.io.IOException: java.util.zip.DataFormatException: invalid block type
        at org.apache.pdfbox.filter.FlateFilter.decode(FlateFilter.java:58)
        at org.apache.pdfbox.filter.Filter.decode(Filter.java:87)
        at org.apache.pdfbox.cos.COSInputStream.create(COSInputStream.java:84)
        at org.apache.pdfbox.cos.COSStream.createInputStream(COSStream.java:246)
        at org.apache.pdfbox.cos.COSStream.createInputStream(COSStream.java:234)
        at org.apache.pdfbox.pdmodel.common.PDStream.createInputStream(PDStream.java:236)
        at org.apache.pdfbox.pdmodel.font.PDTrueTypeFont.<init>(PDTrueTypeFont.java:198)
        at org.apache.pdfbox.pdmodel.font.PDFontFactory.createFont(PDFontFactory.java:89)
        at org.apache.pdfbox.pdmodel.PDResources.getFont(PDResources.java:146)
        at org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.validateAndEnsureAcroFormResources(AppearanceGeneratorHelper.java:143)
        at org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.<init>(AppearanceGeneratorHelper.java:104)
        at org.apache.pdfbox.pdmodel.interactive.form.PDTextField.constructAppearances(PDTextField.java:263)
        at org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm.refreshAppearances(PDAcroForm.java:430)
        at org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm.flatten(PDAcroForm.java:295)

Upvotes: 1

Views: 572

Answers (1)

Barium Scoorge
Barium Scoorge

Reputation: 2028

Thanks to Tilman, this exception is caused by maven resource filtering which altering the pdf template.

I managed to exclude from filtering all resources except NEED_FILTERING_DIRECTORY where i put all my properties with filtering needed, see the following pom.xml part :

    <resources>
        <resource>
            <filtering>false</filtering>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>NEED_FILTERING_DIRECTORY/**</exclude>
            </excludes>
        </resource>
        <resource>
            <filtering>true</filtering>
            <directory>src/main/resources/NEED_FILTERING_DIRECTORY</directory>
        </resource>
    </resources>

Upvotes: 2

Related Questions