PDFBOX API中是否有任何功能可以使文本合理,或者我们必须手动执行?如果手动然后如何使用java(背后的逻辑)来证明文本的合理性
答案 0 :(得分:22)
This older answer显示了如何将字符串分解为适合给定width
的子字符串。要制作示例代码,请以填充整个行宽的方式绘制子字符串,替换如下(取决于PDFBox版本):
替换最后一个循环
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 test testBreakStringJustified
for PDFBox 1.8.x)
如果您想知道
中的replace(',', '.')
contentStream.appendRawCommands(String.format("%f Tc\n", charSpacing).replace(',', '.'));
...我的语言环境使用逗号作为小数点分隔符,在我的第一次测试运行后在页面内容中产生了逗号,我有点懒,只是添加了替换来修复...
替换最后一个循环
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 ),它只会扩展空格字符或两者的组合;但请注意:字间距不适用于所有字体编码。有关这些操作数的更多信息,请参阅表105 文本状态运算符,第9.3.2节字符间距,以及PDF规范ISO 32000-1中的9.3.3 字间距
而不是前者
你现在得到了
如你所见,仍有一个小的赤字,一段的最后一行显然不应该是合理的。因此,在最后一行中,请使用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
,即使它已被标记为已弃用。