【问题标题】:PDF Table StructurePDF 表结构
【发布时间】:2017-11-20 04:39:32
【问题描述】:

我有一个表格结构的 PDF 文件,但我无法将它存储在数据库中,因为 PDF 文件是 Mangal 字体。

所以我遇到了两个问题:

  1. 从 PDF 中提取表格数据
  2. 文字是马拉地语

我已经使用以下代码为英语做到了这一点:

ITextExtractionStrategy strategy = new LocationTextExtractionStrategy(); 
string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, i+1, strategy); 
text.Append(currentText); 
string rawPdfContent = Encoding.UTF8.GetString(Encoding.Convert(Encoding.UTF8, Encoding.UTF8, pdfReader.GetPageContent(i + 1)));

此编码提供表格结构但仅适用于英文字体,想知道马拉地语。

【问题讨论】:

  • PDF 是带标签的 PDF 吗?如果不是,那么这就解释了为什么您不能提取表数据。创建文档的人是否在制作连字时将正确提取马拉地语文本所需的信息存储在 PDF 中?如果不是,您认为任何软件如何能够以正确的顺序提取正确的字节?

标签: c# pdf itext hindi


【解决方案1】:

有趣的是,没有要求。 1其实是最难的。

为了理解原因,您需要稍微了解一下 PDF。 PDF 不是所见即所得的格式。如果您在记事本(或 notepad++)中打开 PDF 文件,您会发现它似乎不包含任何人类可读的信息。

事实上,PDF 包含告诉查看器程序(如 Adob​​e)如何呈现 PDF 的说明。

因此,其中没有一个实际的表格(就像您在 HTML 文档中所期望的那样),它将包含以下内容:

  • 从 .. 到 .. 画一条线
  • 去位置..
  • 绘制字符'123'
  • 将字体设置为 Helvetica 粗体
  • 去位置..
  • 从 .. 到 .. 画一条线
  • 绘制字符“456”

另见How does TextRenderInfo work in iTextSharp?

为了从 PDF 中提取表格,您需要做几件事。

  • 实现 IEventListener(这是一个可以附加到 Parser 实例的类,Parser 将遍历整个页面,并将 TextRenderInfo、ImageRenderInfo 和 PathRenderInfo 事件等事件通知所有侦听器)
  • 注意 PathRenderInfo 事件
  • 构建跟踪正在绘制的路径的数据结构
  • 一旦检测到大约 90° 角的线簇,您就可以假设正在绘制一张表格
  • 确定适合线簇的最大边界框(这称为凸包问题,解决它的算法称为礼品包装算法)
  • 现在您有了一个矩形,可以告诉您表格的位置(在页面上)。
  • 您现在可以在表中递归地应用相同的逻辑来确定行和列
  • 您还可以跟踪 TextRenderInfo 事件,并根据适合表格中每个单独单元格的矩形将它们分类到 bin 中

这是很多工作。这一切都不是微不足道的。事实上,这就是人们写博士论文的内容。

iText 以pdf2Data tool 的形式很好地实现了大多数这些算法。

【讨论】:

  • “有趣的是,第 1 项要求实际上是最难的。” - 实际上有很多文件没有第 1 项要求。 2 也很难,有效地迫使一个人诉诸 OCR...
  • 我为 iText 实现了 OCR,为 iText 实现了结构识别。随时给我 OCR :)
  • 我已经提取了 pdf 的表格结构,但问题是我能够提取没有表格结构的文本,或者如果提取了表格结构则无法提取马拉地语字体..请帮帮我
  • 就像我在上面的答案中所说的那样,PDF 通常不会保留允许您提取哪一段文本位于哪一行/哪一列的内部状态。因此,您将无法以这种方式提取文本。
  • 不要在 cmets 中添加代码。它不清晰。
【解决方案2】:

代码:

ITextExtractionStrategy strategy = new LocationTextExtractionStrategy(); 
string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, i+1, strategy); 
string rawPdfContent = Encoding.UTF8.GetString(Encoding.Convert(Encoding.UTF8, Encoding.UTF8, pdfReader.GetPageContent(i + 1)));

然后我从 PDF 中识别出线条(水平和垂直)。至于行 PDF 有 re 或 m 和 l 关键字。

然后我为从 iTextSharp 获得的马拉地语文本工作。

然后我将两者合并到所需的位置我使用代码提取文本-

Int64 width = Convert.ToInt64(linesVertical[5].StartPoint.X) - Convert.ToInt64(linesVertical[2].StartPoint.X);
                Int64 height = Convert.ToInt64(linesVertical[2].EndPoint.Y) - (Convert.ToInt64(linesVertical[2].StartPoint.Y));
System.util.RectangleJ rect = new System.util.RectangleJ(Convert.ToInt64(linesVertical[2].StartPoint.X), (800 - Convert.ToInt64(linesVertical[2].EndPoint.Y) + 150), width, height);
                RenderFilter[] renderFilter = new RenderFilter[1];
                renderFilter[0] = new RegionTextRenderFilter(rect);
                ITextExtractionStrategy textExtractionStrategy = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), renderFilter);
                Owner_Name = PdfTextExtractor.GetTextFromPage(reader, 1, textExtractionStrategy);

【讨论】:

    猜你喜欢
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    相关资源
    最近更新 更多