iTextSharp-覆盖文本

本文关键字:文本 覆盖 iTextSharp- | 更新日期: 2023-09-27 18:27:15

在下面的代码中,我试图在现有文本上放置一层文本(通过用白色字体书写原始现有文本,将其"隐藏";它用作此替换过程的占位符)。下面的代码在很大程度上依赖于Chris Haas在这篇文章中提供的代码:

Itextsharp 中使用ITextExtractionStrategy和LocationTextExtractionStrategie获取字符串坐标

然而,我的文本位置的"左"位置很好,但"底部"低于我试图覆盖的文本(即使字体相同)。如何更改此项以获得原始文档中文本的正确坐标?原始文档是使用表格进行布局创建的,所以这会影响"覆盖"过程吗?

byte[] content;
string tmppath = @"C:'Junk'MSE_1.pdf";
using (MemoryStream output = new MemoryStream())
{
    PdfReader pdf_rdr = new PdfReader(tmppath);
    PdfStamper stamper = new PdfStamper(pdf_rdr, output);
    for (int i = 1; i < pdf_rdr.NumberOfPages; i++)
    {
        //Create an instance of our strategy
        var t = new MyLocationTextExtractionStrategy("stuff");
        if (t != null)
        {
            //Parse the page of the document above
            //(if the text was found)
            var ex = PdfTextExtractor.GetTextFromPage(pdf_rdr, i, t);
            //Loop through each chunk found
            foreach (var p in t.myPoints)
            {
                Console.WriteLine(string.Format("Found text {0} at {1} x {2} on page {3}", p.Text, p.Rect.Left, p.Rect.Bottom, i.ToString()));
                PdfContentByte pcb = stamper.GetOverContent(i);
                pcb.BeginText();
                try
                {
                    BaseFont bf = BaseFont.CreateFont(@"C:'Junk'FontFiles'georgia.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
                    pcb.SetFontAndSize(bf, 10);
                    pcb.SetTextMatrix(p.Rect.Left, p.Rect.Bottom);
                    //pcb.SetTextRise(3);
                    pcb.ShowText("STUFF");
                }
                finally
                {
                    pcb.EndText();
                }
            }
        }
    }
    // Set the flattening flag to true, as the editing is done
    stamper.FormFlattening = true;
    // close the pdf stamper
    stamper.Close();
    //close the PDF reader
    pdf_rdr.Close();
    //put the output into the byte array
    content = output.ToArray();
}
//write the content to a PDF file
using (FileStream fs = File.Create(@"C:'Junk'MSE_REPLACED.pdf"))
{
    fs.Write(content, 0, (int)content.Length);
    fs.Flush();
}

iTextSharp-覆盖文本

Chris’MyLocationTextExtractionStrategy只考虑文本片段的下降线和上升线,因为它对字符串使用的区域感兴趣。

不过,对于您的任务,您需要基线,因为文本绘制操作使用当前位置作为基线起点。

因此,您应该创建Chris类的一个变体,它管理文本的基线,而不是/除了它的上升和下降线。

PS:OP在评论中询问

恐怕我不熟悉使用基线。你有什么可以分享的例子吗?

如果你看看你提到的Chris的代码,你会看到这个RenderText实现:

public override void RenderText(TextRenderInfo renderInfo) {
    base.RenderText(renderInfo);
    //Get the bounding box for the chunk of text
    var bottomLeft = renderInfo.GetDescentLine().GetStartPoint();
    var topRight = renderInfo.GetAscentLine().GetEndPoint();
    //Create a rectangle from it
    var rect = new iTextSharp.text.Rectangle(
                                            bottomLeft[Vector.I1],
                                            bottomLeft[Vector.I2],
                                            topRight[Vector.I1],
                                            topRight[Vector.I2]
                                            );
    //Add this to our main collection
    this.myPoints.Add(new RectAndText(rect, renderInfo.GetText()));
}

正如你所看到的,他存储的矩形左下角在下降线的起点,右上角是上升线的终点。

如果更换

    //Get the bounding box for the chunk of text
    var bottomLeft = renderInfo.GetDescentLine().GetStartPoint();
    var topRight = renderInfo.GetAscentLine().GetEndPoint();

通过

    //Get the bounding box for the chunk of text above the baseline
    var bottomLeft = renderInfo.GetBaseline().GetStartPoint();
    var topRight = renderInfo.GetAscentLine().GetEndPoint();

重写代码应该可以正常工作。