Reputation: 549
I've been able to write a code to create a new PDF or open an existing PDF and append. What I want to achieve now is to insert another PDF into it. Below is the sample code I've written so far to append PDF.
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
document.open();
PdfContentByte cb = writer.getDirectContent();
PdfReader reader = new PdfReader(templateInputStream);
PdfImportedPage page = writer.getImportedPage(reader, 1);
document.newPage();
cb.addTemplate(page, 0, 0);
// Append sample line
document.add(new Paragraph("my timestamp"));
document.close();
As per my knowledge Adobe reader does support inserting documents. Not sure if the same can be achieved using Java code too.
EDIT:
Below is the code I've written to embed PDF inside PDF. I'm getting error while I click and open embedded pdf/attachment.
public class AddEmbeddedFile {
public static final String SRC = "C:\\Users\\User\\Desktop\\testSource.pdf";
public static final String Embed = "C:\\Users\\User\\Desktop\\testEmbed.pdf";
public static final String DEST = "C:\\Users\\User\\Desktop\\testDest.pdf";
public static void main(String[] args) throws IOException, DocumentException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new AddEmbeddedFile().manipulatePdf(SRC, DEST, Embed);
}
public void manipulatePdf(String src, String dest, String embed) throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfReader reader2 = new PdfReader(embed);
int n = reader2.getNumberOfPages();
reader2.close();
ByteArrayOutputStream boas;
byte[] PDFContent = null;
byte[] PDFContent2 = new byte[0];
for (int i = 0; i < n; ) {
reader2.selectPages(String.valueOf(++i));
boas = new ByteArrayOutputStream();
PdfStamper stamper2 = new PdfStamper(reader2, boas);
PDFContent = boas.toByteArray();
byte[] c = new byte[PDFContent.length + PDFContent2.length];
System.arraycopy(PDFContent, 0, c, 0, PDFContent.length);
System.arraycopy(PDFContent2, 0, c, PDFContent.length, PDFContent2.length);
PDFContent2 = c;
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
PdfFileSpecification fs = PdfFileSpecification.fileEmbedded(
stamper.getWriter(), null, "tests.pdf", PDFContent2, "pdf", null, 0);
stamper.addFileAttachment("some test file", fs);
stamper.close();
}
}
This is the error I'm receiving:
Upvotes: 1
Views: 12417
Reputation: 1
Update:
PdfFileSpecification fileSpecification = PdfFileSpecification.fileEmbedded(pdfWriter,
pdfAttach.getAbsolutePath(), pdfAttach.getName(), null);
pdfWriter.addFileAttachment("Sample Attachment", fileSpecification);
Upvotes: -2
Reputation: 77528
The code you're using in your question is wrong. If you imported PdfImportedPage
objects into a PdfWriter
, you lose all interactivity that may exist in the original document. You need to use PdfStamper
instead.
There are two different ways to add an attachment to an existing PDF. One was already mentioned in the comments where you are referred to the AddEmbeddedFile example:
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
PdfFileSpecification fs = PdfFileSpecification.fileEmbedded(
stamper.getWriter(), null, "test.txt", "Some test".getBytes());
stamper.addFileAttachment("some test file", fs);
stamper.close();
}
You have an existing PDF src
in which you embed a text file. It should be fairly easy to adapt the example so that you add PDF bytes instead of plain text. In this case, the end user will only see the PDF if he opens the attachments panel.
Another way to attach a file is to use an attachment annotation:
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
PdfFileSpecification fs = PdfFileSpecification.fileEmbedded(
stamper.getWriter(), null, "test.txt", "Some test".getBytes());
Rectangle rect = new Rectangle(36, 770, 72, 806);
PdfAnnotation attachment = dfAnnotation.createFileAttachment(
stamper.getWriter(), rect, "My attachment", fs);
stamper.addAnnotation(attachment, 1);
stamper.close();
}
This will add a visible annotation on the first page of the existing PDF on the coordinates defined by rect
.
It is also possible that you are using the concept "attaching a file" incorrectly. Maybe you mean to see concatenating one file to another. This is explained in my answer to the following question: How to merge documents correctly?
Update:
You are using this method to create a PdfFileSpecification
instance:
fileEmbedded(
PdfWriter writer,
String filePath,
String fileDisplay,
byte[] fileStore,
String mimeType,
PdfDictionary fileParameter,
int compressionLevel)
But your parameters are all wrong:
PdfFileSpecification fs = PdfFileSpecification.fileEmbedded(
stamper.getWriter(), // correct
null, // should be "C:\\Users\\User\\Desktop\\testEmbed.pdf"
"tests.pdf", // correct
PDFContent2, // this is completely wrong!!!
"pdf", // should be "application/pdf"
null, // OK
0); // choosing 0 means that you don't want to compress the attachment. Why not?
The way you creat PdfContent2
is completely wrong. It is hard to imagine what you are trying to achieve here. You are concatenating PDF bytes in ways that are completely in violation with the PDF reference.
Upvotes: 6