【问题标题】:ITextSharp insert text to an existing pdfITextSharp 将文本插入现有的 pdf
【发布时间】:2011-04-28 21:39:15
【问题描述】:

标题概括了一切。

我想使用 iTextSharp 向现有 PDF 文件添加文本,但是我在网络上的任何地方都找不到如何操作...

PS:我不能使用 PDF 表单。

【问题讨论】:

  • 编辑很有意义,但删除了 itextsharp 标签,所以这就是我拒绝它的原因。但是现在即使我添加了标签,它也会自动删除。
  • 已与 itext 合并。 Look at the synonyms

标签: c# asp.net pdf itext pdf-generation


【解决方案1】:

我找到了一种方法(不知道它是否是最好的,但它有效)

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();

我希望这对某人有用=)(并在此处发布任何错误)

【讨论】:

  • 一些随机的 blablablabla - 这样的音乐在我耳边!
  • 我的 oldfile.pdf 包含 2 页,但 newfile.pdf 仅包含 oldfile.pdf 的第一页。那么第二页在哪里??
  • @Nurlan Kenzhebekov,为第二页添加以下代码:document.NewPage(); PdfImportedPage page2 = writer.GetImportedPage(reader, 2); cb.AddTemplate(page2, 0, 0); //依此类推下一页。
  • @Tony S. 不幸的是,这不会打印在图像上。您可能对此有解决方案吗?
  • 它可以工作,但我添加的文本放在现有的 pdf 图像下方。我该如何解决这个问题?
【解决方案2】:

除了上面的优秀答案之外,下面展示了如何在多页文档的每一页中添加文本:

 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();
    }
 }

【讨论】:

  • AddTemplate 部分应该负责旋转,如果源文档中有一个 - 请参阅here
  • 您为这些提供什么类型的参考?
  • 这个实际上处理多个页面
  • @Chris Schiffhauer 有没有办法将文本添加到特定页面。比如说。我希望仅将文本添加到我的 PDF 的倒数第二页。有什么想法吗?
  • 这很好用,但我遇到了多行文本覆盖本身的问题。我的修复: var verticalOffset = 50; foreach (var line in multiLineString) { contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, line, 15, verticalOffset, 0);垂直偏移-= 15; }
【解决方案3】:

这是一种使用不同 PDF 客户端(AdobeFoxIt 等)中显示的压模和绝对坐标的方法

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);
        }
    }

【讨论】:

  • 你能告诉我们如何在你的方法中使用参数“point”吗?
【解决方案4】:

这对我有用,包括使用 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();
        }
    }

【讨论】:

  • 旧 pdf 文件包含 2 页,但新生成的 pdf 仅包含旧 pdf 文件的第一页。那么第二页在哪里??
  • AddTemplate 部分应该负责旋转,如果源文档中有一个 - 请参阅here
  • “请求”和“响应”分别位于哪个库中?
  • 响应是 System.Web 的一部分。它在 Page 类中。
【解决方案5】:

这是一种在图像上打印的方法: 取自here。 为您放置在图像上的文本使用不同的图层,并确保使用 GetOverContent() 方法。

            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();
                }
            }

【讨论】:

  • 虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提出问题的人。请edit您的答案添加解释并说明适用的限制和假设。
猜你喜欢
  • 2017-05-10
  • 2016-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
相关资源
最近更新 更多