简体   繁体   English

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

[英]Is it possible to justify text in PDFBOX?

Is there any function in PDFBOX API to make text justified or we have to do it manually?? PDFBOX API 中是否有任何功能可以使文本对齐,或者我们必须手动完成?? and if manually then how to justify text using java(logic behind it)如果手动,那么如何使用 java(背后的逻辑)对齐文本

This older answer shows how to break a string into substrings fitting into a given width . 这个较旧的答案显示了如何将字符串分解为适合给定width子字符串。 To make the sample code there draw the substrings in a manner to fill the whole line widths, replace as follows (depending on the PDFBox version):要使示例代码以填充整个线宽的方式绘制子字符串,请按如下方式替换(取决于 PDFBox 版本):

PDFBox 1.8.x PDFBox 1.8.x

Replace the final loop替换最后的循环

for (String line: lines)
{
    contentStream.drawString(line);
    contentStream.moveTextPositionByAmount(0, -leading);
}

with this more elaborate one:有了这个更详细的:

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);
}

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

If you are wondering about the replace(',', '.') in如果您想知道replace(',', '.')

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

... my locale uses a comma as decimals separator, and after my first test run resulted in commas in the page content, I was a bit lazy and simply added that replace to fix things... ...我的语言环境使用逗号作为小数分隔符,在我的第一次测试运行导致页面内容中出现逗号之后,我有点懒惰,只是添加了替换来解决问题...

PDFBox 2.0.x PDFBox 2.0.x

Replace the final loop替换最后的循环

for (String line: lines)
{
    contentStream.showText(line);
    contentStream.newLineAtOffset(0, -leading);
}

with this more elaborate one:有了这个更详细的:

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);
}

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


This solution merely uses extra character spacing (operator Tc ) for justification.此解决方案仅使用额外的字符间距(运算符Tc )进行调整。 You might instead use extra word spacing (operator Tw ) which only expands space characters, or a combination of both;您可以改为使用仅扩展空格字符的额外字间距(运算符Tw ),或两者的组合; beware, though: word spacing does not work with all font encodings.但要注意:字间距不适用于所有字体编码。 For more information on these operands cf.有关这些操作数的更多信息,请参见。 Table 105 Text state operators , section 9.3.2 Character Spacing , and section 9.3.3 Word Spacing in the PDF specification ISO 32000-1表 105文本状态运算符,PDF 规范ISO 32000-1中的第 9.3.2 节字符间距和第 9.3.3 节字间距

Instead of the former而不是前者

不合理的

you now get你现在得到

在此处输入图片说明

As you see there is still one minor deficit, the last line of a paragraph obviously should not be justified.如您所见,仍有一个小缺陷,段落的最后一行显然不应该是合理的。 In the last line, therefore, use a 0 character spacing instead:因此,在最后一行中,使用0字符间距代替:

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

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

PS I just stumbled across the fact that the setCharacterSpacing currently (November 2016) only is in the 2.1.0-SNAPSHOT development version and not the 2.0.x release versions yet. PS我只是偶然发现setCharacterSpacing当前(2016 年 11 月)仅在 2.1.0-SNAPSHOT 开发版本中,而不是 2.0.x 发布版本。 Thus, in 2.0.x you might have to fall back to using appendRawCommands instead, even if it had been marked deprecated.因此,在 2.0.x 中,您可能不得不改用appendRawCommands ,即使它已被标记为已弃用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM