84

The title sums it all.

I want to add a text to an existing PDF file using iTextSharp, however i can't find how to do it anywhere in the web...

PS: I cannot use PDF forms.

Tony
  • 2,473
  • 3
  • 23
  • 32
  • The edit was meaningful but removed the itextsharp tag so that's why I rejected it. But now even if I add the tag it gets removed automatically. – Tony Apr 26 '19 at 12:23
  • It has been merged with itext. [Look at the synonyms](https://stackoverflow.com/tags/itext/synonyms) – Zoe Apr 26 '19 at 12:24

5 Answers5

117

I found a way to do it (dont know if it is the best but it works)

string oldFile = "oldFile.pdf";
string newFile = "newFile.pdf";

// open the reader
PdfReader reader = new PdfReader(oldFile);
Rectangle size = reader.GetPageSizeWithRotation(1);
Document document = new Document(size);

// open the writer
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write);
PdfWriter writer = PdfWriter.GetInstance(document, fs);
document.Open();

// the pdf content
PdfContentByte cb = writer.DirectContent;

// select the font properties
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252,BaseFont.NOT_EMBEDDED);
cb.SetColorFill(BaseColor.DARK_GRAY);
cb.SetFontAndSize(bf, 8);

// write the text in the pdf content
cb.BeginText();
string text = "Some random blablablabla...";
// put the alignment and coordinates here
cb.ShowTextAligned(1, text, 520, 640, 0);
cb.EndText();
cb.BeginText();
text = "Other random blabla...";
// put the alignment and coordinates here
cb.ShowTextAligned(2, text, 100, 200, 0);
cb.EndText();

// create the new page and add it to the pdf
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);

// close the streams and voilá the file should be changed :)
document.Close();
fs.Close();
writer.Close();
reader.Close();

I hope this can be usefull for someone =) (and post here any errors)

jrcs3
  • 2,790
  • 1
  • 19
  • 35
Tony
  • 2,473
  • 3
  • 23
  • 32
  • 10
    Some random blablablabla - such music to my ears! – Pinch Apr 17 '13 at 20:16
  • 3
    my oldfile.pdf contains 2 pages, but newfile.pdf contains only first page of oldfile.pdf. So where is second page?? – Nurlan May 11 '13 at 18:26
  • 6
    @Nurlan Kenzhebekov, add following code for the second page: document.NewPage(); PdfImportedPage page2 = writer.GetImportedPage(reader, 2); cb.AddTemplate(page2, 0, 0); //and so on for the next pages. – Bronek Jul 17 '13 at 10:19
  • The AddTemplate part should take care of the rotation, if there is one in the source document - see [here](http://stackoverflow.com/a/13943059/444469) – Matthieu May 06 '14 at 21:41
  • 3
    @Tony S. Unfortunately this doesn't print over images. Do you perhaps have a solution for this? – Maiken Roskilde Mar 11 '16 at 17:51
  • 2
    It works, but the text That I added is placed below the existing pdf images. How can I fix this? – onder Dec 24 '16 at 17:51
  • I have use this code in my application but previously added text removing by using this code i want to keep both is there any way to do – Jignesh.Raj May 03 '17 at 06:50
  • I have pdf file stored in database tables and also I have signature as byte in database. So how can I insert that signature in pdf? – Hitesh Jan 30 '18 at 09:51
  • Hi Code works fine for only one page. If there are more pages then it write word on first page only and new file also has one page. – Hitesh Feb 01 '18 at 10:33
  • Unfortunately, I keep getting "Object reference not set to an instance of an object." exception on ShowTextAligned method. – Junaid Jul 13 '20 at 08:11
  • Just move the region `//create the new page and add it to the pdf` just after `PdfContentByte cb = writer.DirectContent;` would fix the text after older pdf. – 高鵬翔 Dec 15 '20 at 05:45
30

In addition to the excellent answers above, the following shows how to add text to each page of a multi-page document:

 using (var reader = new PdfReader(@"C:\Input.pdf"))
 {
    using (var fileStream = new FileStream(@"C:\Output.pdf", FileMode.Create, FileAccess.Write))
    {
       var document = new Document(reader.GetPageSizeWithRotation(1));
       var writer = PdfWriter.GetInstance(document, fileStream);

       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, 12);

          var multiLineString = "Hello,\r\nWorld!".Split('\n');

          foreach (var line in multiLineString)
          {
             contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, line, 200, 200, 0);
          }

          contentByte.EndText();
          contentByte.AddTemplate(importedPage, 0, 0);
       }

       document.Close();
       writer.Close();
    }
 }
Matthew Lock
  • 13,144
  • 12
  • 92
  • 130
Chris Schiffhauer
  • 17,102
  • 15
  • 79
  • 88
  • The AddTemplate part should take care of the rotation, if there is one in the source document - see [here](http://stackoverflow.com/a/13943059/444469) – Matthieu May 06 '14 at 21:42
  • 1
    What type of references are you making for those? – Si8 May 29 '14 at 13:52
  • 1
    this one actually handles multiple pages – Matthew Lock Jun 11 '15 at 03:15
  • @Chris Schiffhauer is there a way to add text to a particular page. Say for eg. I wish to add text only to second last page of my PDF. Any ideas? – Jestino Sam Jan 17 '17 at 13:29
  • This worked great, except I had an issue with multi-line text overwriting itself. My fix: var verticalOffset = 50; foreach (var line in multiLineString) { contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, line, 15, verticalOffset, 0); verticalOffset -= 15; } – Jim Carr Aug 23 '21 at 18:06
12

This worked for me and includes using OutputStream:

PdfReader reader = new PdfReader(new RandomAccessFileOrArray(Request.MapPath("Template.pdf")), null);
    Rectangle size = reader.GetPageSizeWithRotation(1);
    using (Stream outStream = Response.OutputStream)
    {
        Document document = new Document(size);
        PdfWriter writer = PdfWriter.GetInstance(document, outStream);

        document.Open();
        try
        {
            PdfContentByte cb = writer.DirectContent;

            cb.BeginText();
            try
            {
                cb.SetFontAndSize(BaseFont.CreateFont(), 12);
                cb.SetTextMatrix(110, 110);
                cb.ShowText("aaa");
            }
            finally
            {
                cb.EndText();
            }

                PdfImportedPage page = writer.GetImportedPage(reader, 1);
                cb.AddTemplate(page, 0, 0);

        }
        finally
        {
            document.Close();
            writer.Close();
            reader.Close();
        }
    }
jpsnow72
  • 965
  • 2
  • 15
  • 45
12

Here is a method that uses stamper and absolute coordinates showed in the different PDF clients (Adobe, FoxIt and etc. )

public static void AddTextToPdf(string inputPdfPath, string outputPdfPath, string textToAdd, System.Drawing.Point point)
    {
        //variables
        string pathin = inputPdfPath;
        string pathout = outputPdfPath;

        //create PdfReader object to read from the existing document
        using (PdfReader reader = new PdfReader(pathin))
        //create PdfStamper object to write to get the pages from reader 
        using (PdfStamper stamper = new PdfStamper(reader, new FileStream(pathout, FileMode.Create)))
        {
            //select two pages from the original document
            reader.SelectPages("1-2");

            //gettins the page size in order to substract from the iTextSharp coordinates
            var pageSize = reader.GetPageSize(1);

            // PdfContentByte from stamper to add content to the pages over the original content
            PdfContentByte pbover = stamper.GetOverContent(1);

            //add content to the page using ColumnText
            Font font = new Font();
            font.Size = 45;

            //setting up the X and Y coordinates of the document
            int x = point.X;
            int y = point.Y;

            y = (int) (pageSize.Height - y);

            ColumnText.ShowTextAligned(pbover, Element.ALIGN_CENTER, new Phrase(textToAdd, font), x, y, 0);
        }
    }
5

Here is a method To print over images: taken from here. Use a different layer for your text you're putting over the images, and also make sure to use the GetOverContent() method.

            string oldFile = "FileWithImages.pdf";
            string watermarkedFile = "Layers.pdf";
            // Creating watermark on a separate layer
            // Creating iTextSharp.text.pdf.PdfReader object to read the Existing PDF Document
            PdfReader reader1 = new PdfReader(oldFile);
            using (FileStream fs = new FileStream(watermarkedFile, FileMode.Create, FileAccess.Write, FileShare.None))
            // Creating iTextSharp.text.pdf.PdfStamper object to write Data from iTextSharp.text.pdf.PdfReader object to FileStream object
            using (PdfStamper stamper = new PdfStamper(reader1, fs))
            {
                // Getting total number of pages of the Existing Document
                int pageCount = reader1.NumberOfPages;

                // Create New Layer for Watermark
                PdfLayer layer = new PdfLayer("Layer", stamper.Writer);
                // Loop through each Page
                for (int i = 1; i <= pageCount; i++)
                {
                    // Getting the Page Size
                    Rectangle rect = reader1.GetPageSize(i);

                    // Get the ContentByte object
                    PdfContentByte cb = stamper.GetOverContent(i);

                    // Tell the cb that the next commands should be "bound" to this new layer
                    cb.BeginLayer(layer);
                    
                    BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
                    cb.SetColorFill(BaseColor.RED);
                    cb.SetFontAndSize(bf, 100);

                    cb.BeginText();
                    cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Some random blablablabla...", rect.Width / 2, rect.Height / 2, - 90);
                    cb.EndText();

                    // Close the layer
                    cb.EndLayer();
                }
            }
  • While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – rizerphe Jun 28 '20 at 20:11
  • Thank you! This helped me write text on top of my current PDF document. – Meneghini Mar 22 '23 at 22:51