PDFBox API 允许生成低级内容。这意味着您必须自己完成(但您也可以完成)大部分布局工作,其中包括决定向下移动多少才能到达下一个基线。
该距离(在此上下文中称为领先)取决于许多因素:
- 使用的字体大小(显然)
- 文本的间距应该是多紧还是松散
- 所涉及的行上存在位于常规行之外的元素,例如上标、下标、公式……
标准是这样安排的,对于以 1 号绘制的字体,紧密间隔的文本行的标称高度为 1 个单位。因此,通常您将使用 1 的前导。 .1.5 倍字体大小,除非线条上有超出它的材料。
顺便说一句,如果您必须经常以相同的数量转发到下一行,您可以使用PDPageContentStream 方法setLeading 和newLine 的组合,而不是moveTextPositionByAmount:
content.setFont(font, 12);
content.setLeading(14.5f);
content.moveTextPositionByAmount(x, y);
content.drawString("Some text.");
content.newLine();
content.drawString("Some more text.");
content.newLine();
content.drawString("Still some more text.");
PS:看起来moveTextPositionByAmount 将在 2.0.0 版本中被弃用并被newLineAtOffset 取代。
PPS:正如 OP 在评论中指出的那样,
没有称为 setLeading 的 PDPageContentStream 方法。我使用的是 PDFBox 1.8.8 版。
确实,我正在查看当前的 2.0.0-SNAPSHOT 开发版本。它们目前是这样实现的:
/**
* Sets the text leading.
*
* @param leading The leading in unscaled text units.
* @throws IOException If there is an error writing to the stream.
*/
public void setLeading(double leading) throws IOException
{
writeOperand((float) leading);
writeOperator("TL");
}
/**
* Move to the start of the next line of text. Requires the leading to have been set.
*
* @throws IOException If there is an error writing to the stream.
*/
public void newLine() throws IOException
{
if (!inTextMode)
{
throw new IllegalStateException("Must call beginText() before newLine()");
}
writeOperator("T*");
}
使用appendRawCommands((float) leading); appendRawCommands(" TL"); 和appendRawCommands("T*"); 可以轻松实现外部辅助方法