【问题标题】:Find last line in PDF using iTextSharp使用 iTextSharp 在 PDF 中查找最后一行
【发布时间】:2016-10-05 14:04:47
【问题描述】:

我正在使用下面的代码使用 iTextSharp 在 PDF 中查找最后一行 y 坐标

Dim pdfReader As New PdfReader("D:/sample.pdf")
Dim y_cordinate as integer
Dim parser As New PdfReaderContentParser(pdfReader)
Dim finder As TextMarginFinder
finder = parser.ProcessContent(pagen0, New TextMarginFinder())
y_cordinate = finder.GetLly()

如果是直接 PDF,我可以得到正确的 y 坐标 但在其他情况下,我将 MS Word 文档转换为 PDF 并在该 PDF 上尝试上述代码 然后它在 PDF 中获取 Word 文档位置的边距(y 坐标) 请帮助找到 PDF 中文本结尾的正确 y 坐标。(Word 较早)。 请找到从 Word 转换的 PDF 的链接。 https://www.dropbox.com/s/ha1vrk58umuv3h7/PACACH0123.pdf?dl=0

【问题讨论】:

标签: asp.net vb.net pdf itextsharp


【解决方案1】:

您的示例文档的每一页都包含文本绘制说明,这些说明使用 y 坐标 39 处的基线绘制空格字符:

BT
/F2 14.04 Tf
1 0 0 1 72.024 39.024 Tm
[( )] TJ
ET
BT
1 0 0 1 306.05 39.024 Tm
[( )] TJ
ET
BT
1 0 0 1 397.63 39.024 Tm
[( )] TJ
ET

没有低于这个

因此,您的代码将正确返回 39 + descent 作为最后一行的底部。


要解决此问题,您可以使用this answer to "TextMarginFinder to verify printability" 中的 Java/iText 中解释和概述的方法,即在计算文本边界框时忽略所有空格字符:

using (PdfReader pdfReader = new PdfReader(source))
{
    System.Console.Write("\n*\n*\n* Filtered last lines per page of {0}\n*\n*\n", source);
    for (int page = 1; page <= pdfReader.NumberOfPages; page++)
    {
        PdfReaderContentParser parser = new PdfReaderContentParser(pdfReader);
        TextMarginFinder finder = new TextMarginFinder();
        FilteredRenderListener filtered = new FilteredRenderListener(finder, new SpaceFilter());
        parser.ProcessContent(page, new TextRenderInfoSplitter(filtered));
        System.Console.Write("Page {0}, Bottom y {1}\n", page, finder.GetLly());
    }
}

使用这两个辅助类

class TextRenderInfoSplitter : IRenderListener
{
    public TextRenderInfoSplitter(IRenderListener strategy) {
        this.strategy = strategy;
    }

    public void RenderText(TextRenderInfo renderInfo) {
        foreach (TextRenderInfo info in renderInfo.GetCharacterRenderInfos()) {
            strategy.RenderText(info);
        }
    }

    public void BeginTextBlock() {
        strategy.BeginTextBlock();
    }

    public void EndTextBlock() {
        strategy.EndTextBlock();
    }

    public void RenderImage(ImageRenderInfo renderInfo) {
        strategy.RenderImage(renderInfo);
    }

    IRenderListener strategy;
}

class SpaceFilter : RenderFilter
{
    public override bool AllowText(TextRenderInfo renderInfo)
    {
        return renderInfo != null && renderInfo.GetText().Trim().Length > 0;
    }
}

您的示例文档的输出是:

*
*
* Filtered last lines per page of PACACH0123.pdf
*
*
Page 1, Bottom y 81,92254
Page 2, Bottom y 413,1685
Page 3, Bottom y 688,4785

这看起来更像你所追求的数字。

【讨论】:

  • 非常感谢,给的坐标是正确的,请分享itextsharp的完整源代码。请分享。
  • 它的前 2 页非常适合,在第 3 页有一个图像,我认为它也忽略了图像。请建议。
  • 请分享 itextsharp 的完整源代码。 - 你还缺少什么?... 我认为它也忽略了图像 - 是的,之后所有你都在使用TextMarginFinder...
  • 您可以轻松编写更通用的MarginFinder,它还考虑了位图和矢量图形,参见。 MarginFinder.java 来自 this answer。它是用 Java 编写的,但应该很容易翻译成 c#。
  • @Satish 你能把 iText/Java MarginFinder 翻译成 .Net/iTextSharp 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多