我从网上得到了一些代码,他们为我提供了字体大小。我不明白 TextRenderInfo 如何读取文本。我尝试使用 renderInfo.GetText()) ,它给出随机数量的字符,有时是 3 个字符,有时是 2 个字符或更多或更少。我需要知道 renderInfo 如何读取数据?

我的目的是将pdf中的每一行和段落分开,并单独阅读它们的属性,例如字体大小、字体样式等。如果您有任何建议,请提及它们。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iTextSharp.text.pdf.parser;
using iTextSharp.text.pdf;

namespace FontSizeDig1
{
class Program
{
    static void Main(string[] args)
    {
        // reader ==>                 http://itextsupport.com/apidocs/itext5/5.5.9/com/itextpdf/text/pdf/PdfReader.html#pdfVersion
        PdfReader reader = new PdfReader(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "document.pdf"));
        TextWithFontExtractionStategy S = new TextWithFontExtractionStategy();//strategy==> http://itextsupport.com/apidocs/itext5/5.5.9/com/itextpdf/text/pdf/parser/TextExtractionStrategy.html
    //    for (int i = 1; i <= reader.NumberOfPages; i++)
    //   {
            string F = iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(reader, 1/*i*/, S);
            //  PdfTextExtractor.GetTextFromPage(reader, 6, S) ==>>    http://itextsupport.com/apidocs/itext5/5.5.9/com/itextpdf/text/pdf/parser/PdfTextExtractor.html
            Console.WriteLine(F);


      //  }
        Console.ReadKey();
        //this.Close();
    }
}


public class TextWithFontExtractionStategy : iTextSharp.text.pdf.parser.ITextExtractionStrategy
{

    //HTML buffer
    private StringBuilder result = new StringBuilder();

    //Store last used properties
    private Vector lastBaseLine;
    private string lastFont;
    private float lastFontSize;

    //http://api.itextpdf.com/itext/com/itextpdf/text/pdf/parser/TextRenderInfo.html
    private enum TextRenderMode
    {
        FillText = 0,
        StrokeText = 1,
        FillThenStrokeText = 2,
        Invisible = 3,
        FillTextAndAddToPathForClipping = 4,
        StrokeTextAndAddToPathForClipping = 5,
        FillThenStrokeTextAndAddToPathForClipping = 6,
        AddTextToPaddForClipping = 7
    }



    public void RenderText(iTextSharp.text.pdf.parser.TextRenderInfo renderInfo)
    {
        string curFont = renderInfo.GetFont().PostscriptFontName;  // http://itextsupport.com/apidocs/itext5/5.5.9/com/itextpdf/text/pdf/parser/TextRenderInfo.html#getFont--
        //Check if faux bold is used
        if ((renderInfo.GetTextRenderMode() == 2/*(int)TextRenderMode.FillThenStrokeText*/))
        {
            curFont += "-Bold";
        }

        //This code assumes that if the baseline changes then we're on a newline
        Vector curBaseline = renderInfo.GetBaseline().GetStartPoint();
        Vector topRight = renderInfo.GetAscentLine().GetEndPoint();
        iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(curBaseline[Vector.I1], curBaseline[Vector.I2], topRight[Vector.I1], topRight[Vector.I2]);
        Single curFontSize = rect.Height;



        //See if something has changed, either the baseline, the font or the font size
        if ((this.lastBaseLine == null) || (curBaseline[Vector.I2] != lastBaseLine[Vector.I2]) || (curFontSize != lastFontSize) || (curFont != lastFont))
        {
            //if we've put down at least one span tag close it
            if ((this.lastBaseLine != null))
            {
                this.result.AppendLine("</span>");
            }
            //If the baseline has changed then insert a line break
            if ((this.lastBaseLine != null) && curBaseline[Vector.I2] != lastBaseLine[Vector.I2])
            {
                this.result.AppendLine("<br />");
            }
            //Create an HTML tag with appropriate styles
            this.result.AppendFormat("<span style=\"font-family:{0};font-size:{1}\">", curFont, curFontSize);
        }

        //Append the current text

        this.result.Append(renderInfo.GetText());
        Console.WriteLine("me=" + renderInfo.GetText());//by imtiaj




        //Set currently used properties
        this.lastBaseLine = curBaseline;
        this.lastFontSize = curFontSize;
        this.lastFont = curFont;
    }

    public string GetResultantText()
    {
        //If we wrote anything then we'll always have a missing closing tag so close it here
        if (result.Length > 0)
        {
            result.Append("</span>");
        }
        return result.ToString();
    }

    //Not needed
    public void BeginTextBlock() { }
    public void EndTextBlock() { }
    public void RenderImage(ImageRenderInfo renderInfo) { }


}

}

最佳答案

看看这个PDF:

asp.net - TextRenderInfo 如何在 iTextSharp 中工作?-LMLPHP

你看到了什么?

我懂了:



现在,让我们解析这个文件?你能指望什么?

您可能期望:



我不。

这就是你我不同的地方,这种不同解释了你问这个问题的原因。

我期待什么?

好吧,我将首先查看 PDF 内部,更具体地说是第一页的内容流:

asp.net - TextRenderInfo 如何在 iTextSharp 中工作?-LMLPHP

我在内容流中看到 4 个字符串: ldWorlloHe (按此顺序)。我也看到坐标。使用这些坐标,我可以组成显示的内容:



我没有立即在任何地方看到“Hello People”,但我确实看到了对名为 /Xf1 的 Form XObject 的引用,所以让我们检查一下 Form XObject:

asp.net - TextRenderInfo 如何在 iTextSharp 中工作?-LMLPHP

呜呼!我很幸运,“Hello People”作为单个字符串值存储在文档中。我不需要查看坐标来组成我可以用人眼看到的实际文本。

现在回答你的问题。您说“我需要知道 renderInfo 如何读取数据”,现在您知道了:默认情况下,iText 将按照出现的顺序从页面中读取所有字符串: ldWorlloHeHello People

根据 PDF 的创建方式,您可以拥有易于阅读的输出 ( Hello People ) 或难以阅读的输出 ( ldWorlloHe )。 iText 带有重新排序所有这些片段的“策略”,以便 [ ld , Wor , llo , He ] 显示为 [ He , llo , Wor , ld ],但要检测这些行中的哪一行,哪些部分属于这些行属于同一段,是你必须做的事情。

注意:在 iText Group 的 ,我们已经有大量的封闭源代码可以为您节省大量时间。由于我们是 iText 库的版权所有者,因此我们可以向该封闭源代码要钱。如果您免费使用 iText(因为 AGPL),这通常是您无法做到的。但是,如果您是 iText 的客户,我们可能可以公开更多的源代码。不要指望我们免费提供该代码,因为该代码具有太大的商业值(value)。

关于asp.net - TextRenderInfo 如何在 iTextSharp 中工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47389144/

10-13 08:02