Adding a pdf attachment to the PDF using pdfBox

271 Views Asked by At

I'm currently working on an api which generate a pdf file with some customer report and contain some pdf atatchments related to the report. I am adding an attachment to the PDF using PDFBox library in Java by referring to the code snippet, Adding a File Attachment

I successfully attached the document created using ByteArrayInputStream to the attachment. However, when I try to open the attachment in the document using Adobe reader or any PDF viewer tool I am getting the error as in the screenshot. enter image description here

If I use the ef.setSubtype("text/plain") and file extension as '.txt' I am able to open the attachment successfully. The code snippet I used is as below,

@GetMapping("/generate-pdf")
public ResponseEntity<InputStreamResource> generatePDFWithAttachment() {
    try {
        final PDDocument doc = new PDDocument();
        PDPage page = new PDPage();
        doc.addPage(page);

        PDPageContentStream contentStream = new PDPageContentStream(doc, page);

        contentStream.beginText();
        contentStream.setFont(PDType1Font.HELVETICA, 15);
        contentStream.newLineAtOffset(100, 700);
        contentStream.setNonStrokingColor(Color.red);
        contentStream.showText("Go to Document -> File Attachments to View Embedded Files");

        Map<String, String> keyValueMap = new HashMap<>();
        keyValueMap.put("file1.pdf", "test element 1");
        keyValueMap.put("file2.pdf", "test element 2");

        //------- start attachment section
        // embedded files are stored in a named tree
        // create a new tree node and add the embedded file
        PDEmbeddedFilesNameTreeNode efTree = new PDEmbeddedFilesNameTreeNode();
        Map<String, PDComplexFileSpecification> treeNodeMap = new HashMap<>();

        for (Map.Entry<String, String> entry : keyValueMap.entrySet()) {

            // first create the file specification, which holds the embedded file
            PDComplexFileSpecification fs = new PDComplexFileSpecification();
            fs.setFile(entry.getKey());
            // create a dummy file stream, this would probably normally be a FileInputStream
            byte[] data = entry.getValue().getBytes();
            ByteArrayInputStream fakeFile = new ByteArrayInputStream(data);
            // now lets some of the optional parameters
            PDEmbeddedFile ef = new PDEmbeddedFile(doc, fakeFile);
            ef.setSubtype("application/pdf");
            ef.setSize(data.length);
            ef.setCreationDate(Calendar.getInstance());
            fs.setEmbeddedFile(ef);
            treeNodeMap.put(entry.getKey(), fs);
        }

        efTree.setNames(treeNodeMap);
        PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog());
        names.setEmbeddedFiles(efTree);
        doc.getDocumentCatalog().setNames(names);
        //------- end attachment section
        contentStream.endText();

        contentStream.close();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        doc.save(outputStream);
        doc.close();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_PDF);
        headers.setContentDispositionFormData("attachment", "sample.pdf");

        InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(outputStream.toByteArray()));

        return ResponseEntity.ok()
                .headers(headers)
                .body(resource);


    } catch (IOException e) {
        System.err.println("Exception while trying to create pdf document - " + e);
    }
    return null;
}

I assume attachments can contain file of type .pdf. I also tried by providing the charset parameter to UTF_8 byte[] data = entry.getValue().getBytes(StandardCharsets.UTF_8); and that also didn't helps

0

There are 0 best solutions below