是否可以在PDFBOX中对齐文本?

2022-09-03 10:07:44

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


答案 1

这个较旧的答案显示了如何将字符串分解为适合给定的子字符串。要使示例代码以填充整个行宽的方式绘制子字符串,请按如下方式替换(取决于 PDFBox 版本):width

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 testBreakStringJustized for PDFBox 1.8.x)

如果你想知道在replace(',', '.')

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 test TestBreakStringJustified for PDFBox 2.0.x)


此解决方案仅使用额外的字符间距(运算符 Tc)进行对齐。您可以改为使用额外的单词间距(运算符Tw),它仅扩展空格字符,或两者的组合;但要小心:字间距不适用于所有字体编码。有关这些操作数的详细信息,请参阅 PDF 规范 ISO 32000-1 中的表 105 文本状态运算符、第 9.3.2 节字符间距和第 9.3.3 节单词间距

而不是前者

non-justified

您现在得到

enter image description here

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

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

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

附言我只是偶然发现,目前(2016年11月)只有2.1.0-SNAPSHOT开发版本,而不是2.0.x发布版本。因此,在 2.0.x 中,您可能必须回退到使用,即使它已被标记为已弃用。setCharacterSpacingappendRawCommands


答案 2

推荐