PDF找出文本是不是带下划线或表格单元格
Posted
技术标签:
【中文标题】PDF找出文本是不是带下划线或表格单元格【英文标题】:PDF find out if text is underlined or a table cellPDF找出文本是否带下划线或表格单元格 【发布时间】:2012-12-06 14:19:18 【问题描述】:我一直在玩 PdfBox 和 PDFTextStripperByArea 方法。
如果文本是粗体或斜体,我能够提取信息,但我无法获得下划线信息。
据我在PDF中的理解,下划线是通过画线来完成的。所以理论上我应该能够获得一些关于文本周围某处线条的信息。提供此信息后,我可以确定其中一个文本是带下划线还是在表格中。
到目前为止,这是我的代码:
List<TextPosition> textPos = charactersByArticle.get(index);
for (TextPosition t : textPos)
if (t.getFont().getFontDescriptor() != null)
if (t.getFont().getFontDescriptor().getFontWeight() > BOLD_WEIGHT ||
t.getFont().getFontDescriptor().isForceBold())
isBold = true;
if (t.getFont().getFontDescriptor().isItalic())
isItalic = true;
我试图玩弄在 PDFStreamEngine 类的 processEncodedText 方法中处理的 PDGraphicsState 对象,但没有找到那里的行信息。
有什么建议可以从中检索到这些信息吗?
【问题讨论】:
Drejc:好问题。当我使用 pdfbox 将 pdf 转换为 html 时,我遇到了同样的问题。但我通过将下划线视为背景图像的一部分解决了这个问题。我认为这不适用于您的情况。如果我们得到了线条的 x,y 坐标,那就太好了 我建议你尝试另一个 PDF 处理库。下划线不是字体的属性,例如字体粗体(粗体)或形状(斜体),而是放在文本下方的图形对象。我一直在阅读 PDFBox API,看起来您可以获得所有图形对象。因此,您必须编写一个程序来计算看起来像一条线的东西的坐标,然后查看它是否在某些文本下方。那比较乏味。但我之前从未使用过 PDFBox,所以我不是专家。 我知道线条不是文本的一部分,而是图形对象的一部分。切换库不是一种选择,而且替代方案也不提供此功能(据我所知)。我可以在提取文本的同时调整 PdfBox 以获取图形,但这需要大量的工作和大量的反复试验。我希望有人已经这样做了。 @Neeraj 当您提供赏金时,您可能会想到某些类型的下划线。我刚刚查看了 MS Word 生成的 PDF,它们实际上使用填充的细长矩形而不是线条来下划线或删除线。也许您的 PDF 使用不同的技术。因此,您(或 Drejc)应该发布一些示例文档,您希望在其中识别下划线......(但请注意,这仍然是一个不安全的事情,因为矩形除了它们在页面上的位置之外没有任何其他方式链接到他们下划线的单词) @Neeraj 如果您真的想识别理论上可以创建此类线条的任何可能方式,您还必须考虑属于某些背景位图图像的线条。因此,您又回到了图像分析,这是您不想做的事情。另一方面,如果能够识别出足够多的传播软件实际使用的下划线就足够了,事情就容易多了,但必须定义要考虑哪些软件来考虑我们要考虑哪些 pdf。 【参考方案1】:根据apigetfont()返回字体大小。
您可以使用getStyle() 方法,它将返回STYLE_UNDERLINE
用于下划线字体。因此您可以检索下划线样式。
【讨论】:
在使用 PDFStreamEngine 提取文本时,字体描述符中没有可用的此类属性。需要将下划线(和表格线)提取为图形对象,然后以某种方式绑定到文本流。仅仅阅读在线文档是行不通的。【参考方案2】:这是我目前发现的:
PDFBox 使用资源文件将 PDF 运算符/指令绑定到某些类,然后这些类处理信息。
如果我们看一下 PDFTextStripper.properties 资源文件:
pdfbox\src\main\resources\org\apache\pdfbox\resources\
我们可以看到例如 BT 操作符绑定到 org.apache.pdfbox.util.operator.BeginText 类等等。
下的PDFTextStripperpdfbox\src\main\java\org\apache\pdfbox\util\
考虑到这一点,并利用此类处理 PDF。
但所有图形对象都被忽略,因此没有下划线或表格结构的信息!
现在,如果我们看一下 PageDrawer.properties 资源文件,我们可以看到该资源文件绑定到几乎所有可用的运算符。由
下的 PageDrawer 类使用pdfbox\src\main\java\org\apache\pdfbox\pdfviewer\
现在的“诀窍”是找出哪些图形运算符代表下划线和表格,并将它们与 PDFTextStripper 结合使用。
现在这意味着阅读 PDF 文件规范,这是目前很多工作的方式。
如果有人知道哪些操作员负责绘制下划线和表格线的哪些操作,请告诉我。
【讨论】:
PDF 格式是这样的——这就是问题所在。它代表图形实现,而不是语义。甚至重构句子也很困难——单词甚至单个字符被定位,“空格”或“换行符”必须通过算法重构。简而言之,Adobe 就是个坑。 但是,您可以完成您的要求——如果您愿意投入 12-20 小时的工作。复制 PDFBox 类和扩展内部通常是一个很好的起点。除了按位置检测外,下划线通常会在我期望的文本之后立即发出! 还可以尝试用带下划线的文本构建一个简单的两行 PDF,看看你能把什么钩回来!在那里应该很容易看到。享受吧。 我执行的任务是读入和转换。除了表格和下划线,我几乎把所有东西都弄好了。特殊字符(如重音字符)也很痛苦,所以我有一些根据文档类型起作用的启发式方法。不能完成的事情现在是手工编辑的(因为总是需要最后的视觉检查)。我已经放弃了线条功能,因为时间与收益太低了。【参考方案3】:您可以使用 Itext 生成 pdf 报告。
通过使用 itext,您可以轻松地放置线条。
试试下面的。
document.add(new LineSeparator(0.5f, 50, null, 0, 198));
以上代码用于生成pdf报告中的行。并根据您的选择设置尺寸。
希望这会对你有所帮助。
【讨论】:
目的是阅读下划线而不是创建下划线。我看过 iText 但也找不到这个功能。另外,我的代码库目前绑定到 PdfBox。【参考方案4】:据我了解 pdfbox,没有选项可以让您阅读下划线。也许您可以为此尝试使用 itextpdf。
【讨论】:
【参考方案5】:正如您提到的——PDFBox 使用资源文件,将 PDF 操作符/说明绑定到将处理信息的访问者。
您最好先将 PDFBox 的现有访问者复制到您自己的源文件夹中,然后从那里添加/扩展实现。
我很久以前的 PostScript 经验回忆起 'moveto' 和 'lineto' 运算符。由于 PDF 大致基于 PS,因此您会寻找类似的东西。
http://learnpostscript.wordpress.com/category/lineto/
PDF 格式很糟糕——它是 HTML,做错了。它代表图形实现,而不是语义。甚至重构句子也很困难——单词甚至单个字符被定位,“空格”或“换行符”必须通过算法重构。简而言之,Adobe 是个坑。而 Reader 是一头不符合人体工程学、漏洞百出、不安全、臃肿的猪。
但是,您可以满足您的要求 - 如果您愿意投入 12 小时以上的工作。除了按位置检测外,下划线通常会在 PDF 中的文本之后立即发出。所以您可以通过 PDF 文档顺序锁定您的检测,而不仅仅是页面位置。
另外,尝试用带下划线的文本构建一个简单的两行 PDF。然后看看你能做什么,把它解析回来!下划线应该像狗的香蕉一样突出,一旦你能察觉到这一点,你就会顺利进行。
PDFBox 的可扩展性不是很好,主要是一堆算法。因此,只需从那里复制 PDFTextStripper 源代码(可能还有 PageDrawer 供参考)和原型。
希望这会有所帮助!
【讨论】:
确实如此……我已经玩过它了。 PDFBox 代码真的很乱,我感觉有些操作被执行了多次,没有明显的原因。目前涉及提取简单下划线的工作量很大,将代码移植到其他库是一种选择,但也超出了范围。 我不认为你会从任何其他图书馆中得到更多的快乐。如果你这样做了,我会感到惊讶。甚至在 PDF 中识别 单词 也很困难。格式设计得非常糟糕。以上是关于PDF找出文本是不是带下划线或表格单元格的主要内容,如果未能解决你的问题,请参考以下文章
为啥在 iOS 中显示为 PDF 时,具有居中文本的底部表格单元格会被截断?
自定义表格视图单元格中的 UITextField。点击单元格/文本字段时显示选择器视图