Skip to main content
Skip table of contents

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?

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 How to load a PDF from a stream and add a file attachment? if you want to see how to answer this question in iText 5.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.