How to load a PDF from a stream and add a file attachment?

When I save stream to file, the resulting PDF is not correct. The file attachment will always be an XML file, which I need to create in memory and never will be in file system. How can I do this with iText?

31st May 2016
admin-marketing

I'm using a MS SQL Report Server web service to generate reports in the PDF format:

 

byte[] Input;
   ReportServer report = new ReportServer(
    serverUrl + @"/ReportExecution2005.asmx", reportPath);
Input = report.RenderToPDF(reportParamNames, reportParamValues);
This service returns a byte array with pdf file and I need this byte array load to iTextSharp:

 

using (MemoryStream ms = new MemoryStream(Input)) {
       Document doc = new Document();
       PdfWriter writer = PdfWriter.GetInstance(doc, ms);
       doc.Open();
    ...
}
This seems ok, but then I am trying to add an attachment to this PDF:

 

PdfFileSpecification pfs = PdfFileSpecification.FileEmbedded(writer, xmlInputFile, xmlFileDisplayName, null);
writer.AddFileAttachment(pfs);
This seems OK too, but when I save stream to file, the resulting PDF is not correct.

Note that the file attachment will always be an XML file, which I need to create in memory and never will be in file system. How can I do this with iTextSharp?

Posted on StackOverflow on Jan 29, 2015 by Davecz

In iText 7 this can be done in the following way:

IRandomAccessSource source = new RandomAccessSourceFactory().createSource(pdf_bytes.toByteArray());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfDocument pdfDoc = new PdfDocument(new PdfReader(source, new ReaderProperties()), new PdfWriter(baos));

byte[] xmlInputFile;
String xmlFileDisplayName;
PdfFileSpec pfs;
for (String s : ATTACHMENTS) {
    xmlInputFile = String.format("Some test: %s", s).getBytes();
    xmlFileDisplayName = String.format("%s.xml", s);
    pfs = PdfFileSpec.createEmbeddedFileSpec(pdfDoc,
                xmlInputFile, null, xmlFileDisplayName, null, null, null, true);
    pdfDoc.addFileAttachment(xmlFileDisplayName, pfs);
}
pdfDoc.close();

As you see, we create a PdfDocument instance using the bytes that were kept in memory (pdf_bytes). We then add five file attachments. ATTACHMENTS is the array of Strings:

public static final String[] ATTACHMENTS = {"hello", "world", "what", "is", "up"};

If you need to return a byte array, try this: return baos.toByteArray();

Click this link if you want to see how to answer this question in iText 5.



Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now