Adding text to existing multipage PDF document in memorystream using iTextSharp

c#, c#-4.0, itext, pdf, stream

Solution

The code below shows off a full-working example of creating a PDF in memory and then performing a second pass, also in memory. It does what @mkl says and closes all iText parts before trying to grab the raw bytes from the stream. It also uses `GetOverContent()` to draw "on top" of the previous pdf. See the code comments for more details.

//Bytes will hold our final PDFs
byte[] bytes;

//Create an in-memory PDF
using (var ms = new MemoryStream()) {
    using (var doc = new Document()) {
        using (var writer = PdfWriter.GetInstance(doc, ms)) {
            doc.Open();

            //Create a bunch of pages and add text, nothing special here
            for (var i = 1; i <= 10; i++) {
                doc.NewPage();
                doc.Add(new Paragraph(String.Format("First Pass - Page {0}", i)));
            }

            doc.Close();
        }
    }

    //Right before disposing of the MemoryStream grab all of the bytes
    bytes = ms.ToArray();
}

//Another in-memory PDF
using (var ms = new MemoryStream()) {
    //Bind a reader to the bytes that we created above
    using (var reader = new PdfReader(bytes)) {
        //Store our page count
        var pageCount = reader.NumberOfPages;

        //Bind a stamper to our reader
        using (var stamper = new PdfStamper(reader, ms)) {

            //Setup a font to use
            var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);

            //Loop through each page
            for (var i = 1; i <= pageCount; i++) {
                //Get the raw PDF stream "on top" of the existing content
                var cb = stamper.GetOverContent(i);

                //Draw some text
                cb.BeginText();
                cb.SetFontAndSize(baseFont, 18);
                cb.ShowText(String.Format("Second Pass - Page {0}", i));
                cb.EndText();
            }
        }
    }

    //Once again, grab the bytes before closing things out
    bytes = ms.ToArray();
}

//Just to see the final results I'm writing these bytes to disk but you could do whatever
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");
System.IO.File.WriteAllBytes(testFile, bytes);

Problem

I am trying to add text to an existing PDF file using iTextSharp. I have been reading many posts, including the popular thread here. I have some differences: - My PDF are X pages long - I want to keep everything in memory, and never have a file stored on my filesystem So I tried to modify the code, so it takes in a byte array and returns a byte array. I have come this far: - The code compiles and runs - My out byte array has a different length than my in byte array My problem: - I cannot see my added text when i later store the modified byte array and open it in my PDF reader I don't get why. From every StackOverflow post I have seen, I do the same. using the `DirectContent`, I use `BeginText` and write a text. However, i cannot see it, no matter how I move the position around. Any idea what is missing from my code? ``` public static byte[] WriteIdOnPdf(byte[] inPDF, string str) { byte[] finalBytes; // open the reader using (PdfReader reader = new PdfReader(inPDF)) { Rectangle size = reader.GetPageSizeWithRotation(1); using (Document document = new Document(size)) { // open the writer using (MemoryStream ms = new MemoryStream()) { using (PdfWriter writer = PdfWriter.GetInstance(document, ms)) { document.Open(); for (var i = 1; i <= reader.NumberOfPages; i++) { document.NewPage(); var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); var importedPage = writer.GetImportedPage(reader, i); var contentByte = writer.DirectContent; contentByte.BeginText(); contentByte.SetFontAndSize(baseFont, 18); var multiLineString = "Hello,\r\nWorld!"; contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, multiLineString,100, 200, 0); contentByte.EndText(); contentByte.AddTemplate(importedPage, 0, 0); } document.Close(); ms.Close(); writer.Close(); reader.Close(); } finalBytes = ms.ToArray(); } } } return finalBytes; } ```

Original source

Related problems