在 C# 中使用 ITextSharp 在现有 pdf 的右上角添加一个文本框

adding a textbox to the right corner of the existing pdf using ITextSharp in C#

我想用 c# 在现有 pdf 的右上角添加一个文本框,但我无法完成它。我写了下面的代码,但是对解决问题没有帮助,有哪位大神可以推荐一下吗

using (MemoryStream stream = new MemoryStream())
{
        PdfReader reader = new PdfReader(bytes);               
        PdfReader.unethicalreading = true;
        Paragraph p = new Paragraph();
        Document doc = new Document();

        using (PdfStamper stamper = new PdfStamper(reader, stream))
        {
            PdfContentByte canvas = stamper.GetOverContent(1);
            iTextSharp.text.Rectangle size = reader.GetPageSizeWithRotation(1);


            //PdfContentByte cb = null;
            //PdfImportedPage page;
            int pages = reader.NumberOfPages;                    
            for (int i = 1; i <= pages; i++)
            {
                var size1 = reader.GetPageSize(i);
                w = size1.Width;
                h = size1.Height;
                stamper.FormFlattening = true;

                TextField tf = new TextField(stamper.Writer, new iTextSharp.text.Rectangle(0, 0, 300, 100), displaytext);
                //Change the orientation of the text
                tf.Rotation = 0;
                stamper.AddAnnotation(tf.GetTextField(), i);
            }
        }
        bytes = stream.ToArray();
}
File.WriteAllBytes(str, bytes);

正如 OP 在对问题的评论中澄清的那样,他想要

  • 在页面右下角添加文字作为页面内容
  • 之前存在的页面内容将被删除。

一个简单的实现包括

  • 首先用填充矩形覆盖现有页面内容,然后
  • 然后在那里写文字。

这些任务可以通过这些辅助方法来完成:

void EmptyTextBoxSimple(PdfStamper stamper, int pageNumber, Rectangle boxArea, BaseColor fillColor)
{
    PdfContentByte canvas = stamper.GetOverContent(pageNumber);
    canvas.SaveState();
    canvas.SetColorFill(fillColor);
    canvas.Rectangle(boxArea.Left, boxArea.Bottom, boxArea.Width, boxArea.Height);
    canvas.Fill();
    canvas.RestoreState();
}

ColumnText GenerateTextBox(PdfStamper stamper, int pageNumber, Rectangle boxArea)
{
    PdfContentByte canvas = stamper.GetOverContent(pageNumber);
    ColumnText columnText = new ColumnText(canvas);
    columnText.SetSimpleColumn(boxArea);
    return columnText;
}

例如像这样:

using (PdfReader reader = new PdfReader(source))
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create)))
{
    Rectangle cropBox = reader.GetCropBox(1);
    Rectangle bottomRight = new Rectangle(cropBox.GetRight(216), cropBox.Bottom, cropBox.Right, cropBox.GetBottom(146));
    EmptyTextBoxSimple(stamper, 1, bottomRight, BaseColor.WHITE);
    ColumnText columnText = GenerateTextBox(stamper, 1, bottomRight);
    columnText.AddText(new Phrase("Some test text to draw into a text box in the lower right corner of the first page"));
    columnText.Go();
}

对于此源页面

示例代码生成这个

附录

OP 在评论中指出

it is working for all files but for some pdf files it is displaying in the middle

最终他提供了一个 sample file 问题发生的原因。事实上,使用此文件可以重现该问题。

问题的原因是示例文件中的页面使用了页面旋转,iText(仅)部分允许用户忽略这一点。特别是 iText 在旋转后自动将文本旋转为直立并转换坐标,但是在检索页面的裁剪框时,仍然必须在使用坐标之前应用旋转。因此,一个更完整的例子是这样的:

using (PdfReader reader = new PdfReader(source))
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create)))
{
    Rectangle cropBox = reader.GetCropBox(1);
    int rotation = reader.GetPageRotation(1);
    while (rotation > 0)
    {
        cropBox = cropBox.Rotate();
        rotation -= 90;
    }
    Rectangle bottomRight = new Rectangle(cropBox.GetRight(216), cropBox.Bottom, cropBox.Right, cropBox.GetBottom(146));
    EmptyTextBoxSimple(stamper, 1, bottomRight, BaseColor.WHITE);
    ColumnText columnText = GenerateTextBox(stamper, 1, bottomRight);
    columnText.AddText(new Phrase("Some test text to draw into a text box in the lower right corner of the first page"));
    columnText.Go();
}