是否可以证明 PDFBOX 中的文本是合理的?

Posted

技术标签:

【中文标题】是否可以证明 PDFBOX 中的文本是合理的?【英文标题】:Is it possible to justify text in PDFBOX? 【发布时间】:2014-01-07 22:43:21 【问题描述】:

PDFBOX API 中是否有任何功能可以使文本对齐或我们必须手动执行?如果手动,那么如何使用 java(背后的逻辑)证明文本的合理性

【问题讨论】:

确切的问题是什么?不清楚你在问什么。 【参考方案1】:

This older answer 展示了如何将字符串分解为适合给定width 的子字符串。要使示例代码以填充整个线宽的方式绘制子字符串,请替换如下(取决于 PDFBox 版本):

PDFBox 1.8.x

替换最后的循环

for (String line: lines)

    contentStream.drawString(line);
    contentStream.moveTextPositionByAmount(0, -leading);

有了这个更详细的:

for (String line: lines)

    float charSpacing = 0;
    if (line.length() > 1)
    
        float size = fontSize * pdfFont.getStringWidth(line) / 1000;
        float free = width - size;
        if (free > 0)
        
            charSpacing = free / (line.length() - 1);
        
    
    contentStream.appendRawCommands(String.format("%f Tc\n", charSpacing).replace(',', '.'));
            
    contentStream.drawString(line);
    contentStream.moveTextPositionByAmount(0, -leading);

(来自BreakLongString.java 测试testBreakStringJustified for PDFBox 1.8.x)

如果您想知道replace(',', '.') in

contentStream.appendRawCommands(String.format("%f Tc\n", charSpacing).replace(',', '.'));

...我的语言环境使用逗号作为小数分隔符,在我的第一次测试运行导致页面内容中有逗号后,我有点懒惰,只是添加了替换来解决问题...

PDFBox 2.0.x

替换最后的循环

for (String line: lines)

    contentStream.showText(line);
    contentStream.newLineAtOffset(0, -leading);

有了这个更详细的:

for (String line: lines)

    float charSpacing = 0;
    if (line.length() > 1)
    
        float size = fontSize * pdfFont.getStringWidth(line) / 1000;
        float free = width - size;
        if (free > 0)
        
            charSpacing = free / (line.length() - 1);
        
    
    contentStream.setCharacterSpacing(charSpacing);
    
    contentStream.showText(line);
    contentStream.newLineAtOffset(0, -leading);

(来自BreakLongString.java 测试testBreakStringJustified for PDFBox 2.0.x)


此解决方案仅使用额外的字符间距(运算符 Tc)来说明理由。您可以改为使用额外的字间距(运算符 Tw),它只扩展空格字符,或两者的组合;但请注意:字间距不适用于所有字体编码。有关这些操作数的更多信息,请参阅。 PDF 规范ISO 32000-1 中的表 105 文本状态运算符、第 9.3.2 节 字符间距 和第 9.3.3 节 字间距 p>

取代前者

你现在得到

如您所见,仍有一个小缺陷,段落的最后一行显然不应该被证明是合理的。因此,在最后一行中,请改用 0 字符间距:

    contentStream.appendRawCommands("0 Tc\n"); // PDFBox 1.8.x

    contentStream.setCharacterSpacing(0); // PDFBox 2.0.x

PS 我刚刚偶然发现setCharacterSpacing 目前(2016 年 11 月)仅在 2.1.0-SNAPSHOT 开发版本中,而不是 2.0.x 发布版本中。因此,在 2.0.x 中,您可能不得不转而使用 appendRawCommands,即使它已被标记为已弃用。

【讨论】:

对于“不应该被证明”的最后一行,我只在if(line.length() >= <something>)时设置CharacterSpacing,否则设置为0。这样,任何低于特定长度(以字符为单位)的行都不会被证明是合理的。就我而言,我使用lines.get(0).length() / 1.5 作为参考(假设lines.get(0) 存在) 万岁,非常感谢这个答案,它帮助我在我的 Pdfbox 文件中获得了我希望的对齐 :-) (PdfBox 2.0.21)

以上是关于是否可以证明 PDFBOX 中的文本是合理的?的主要内容,如果未能解决你的问题,请参考以下文章

Python:证明 NumPy 数组的合理性

使用 Bootstrap v4 证明导航药丸的合理性

如何压缩一行中的文本以适应它?

来自身份证明文件检测和 ocr 的模糊文本

html Flexbox证明了内容的合理性

文本对齐证明不起作用