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);
using (MemoryStream ms = new MemoryStream(Input)) { Document doc = new Document(); PdfWriter writer = PdfWriter.GetInstance(doc, ms); doc.Open(); ... }
PdfFileSpecification pfs = PdfFileSpecification.FileEmbedded(writer, xmlInputFile, xmlFileDisplayName, null); writer.AddFileAttachment(pfs);
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
I read:
This service returns a byte array with pdf file and I need this byte array load to iTextSharp:
{line-numbers=off,lang=csharp}
using (MemoryStream ms = new MemoryStream(Input))
{
Document doc = new Document();
PdfWriter writer = PdfWriter.GetInstance(doc, ms);
doc.Open();
...
}
this seems ok
This is not OK. You want to add an attachment to an existing PDF file, however, you are using Document
and PdfWriter
which are classes to create a new PDF document from scratch. You need to use a combination of PdfReader
and PdfStamper
instead:
PdfReader
: Reads PDF files. You pass an instance of this class to one of the other PDF manipulation classes.
PdfStamper
: Manipulates one (and only one) PDF document. Can be used to add content at absolute positions, to add extra pages, or to fill out fields. All interactive features are preserved, except when you explicitly remove them (for instance, by flattening a form).
Please take a look at some examples:
PdfReader reader = new PdfReader(pdf_bytes);
using (var ms = new MemoryStream()) {
using (PdfStamper stamper = new PdfStamper(reader, ms)) {
PdfFileSpecification pfs = PdfFileSpecification.FileEmbedded(
stamper.Writer, xmlInputFile, xmlFileDisplayName, null);
stamper.AddFileAttachment(pfs);
}
reader.Close();
return ms.ToArray();
}
As you can see, we create a PdfReader
instance using the bytes that were kept in memory. We then use PdfStamper
to create a new MemoryStream
of which we use the bytes.