Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在使用ApachePDFBox添加文本时移到下一行_Java_Pdf_Pdf Generation_Pdfbox - Fatal编程技术网

Java 如何在使用ApachePDFBox添加文本时移到下一行

Java 如何在使用ApachePDFBox添加文本时移到下一行,java,pdf,pdf-generation,pdfbox,Java,Pdf,Pdf Generation,Pdfbox,我刚刚开始使用ApachePDFBox,并一直在尝试我发现的各种示例 但是,在添加文本时,我无法找到一种简单的方法来移动到下一行 例如 要在下面添加另一行文本,我必须反复试验moveTextPositionByAmount中的y值,直到它不覆盖前一行 有没有更直观的方法来计算下一行的坐标 TIAPDFBox API允许生成低级内容。这意味着您必须自己做(但也有能力做)大部分布局工作,其中包括决定要向下移动多少才能到达下一个基线 这种距离(在本文中称为领先)取决于许多因素: 使用的字体大小(显然

我刚刚开始使用ApachePDFBox,并一直在尝试我发现的各种示例

但是,在添加文本时,我无法找到一种简单的方法来移动到下一行

例如

要在下面添加另一行文本,我必须反复试验
moveTextPositionByAmount
中的y值,直到它不覆盖前一行

有没有更直观的方法来计算下一行的坐标


TIA

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:看起来在2.0.0版本中,
moveTextPositionByAmount
将被弃用,并被
NewlineToffset
取代

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

可以使用
appendrawscommands((float)leading)轻松地实现外部助手方法,从而实现等效功能;附加命令(“TL”)
追加命令(“T*”)

添加一条y轴偏移的新线,如下所示

PDPageContentStream content = new PDPageContentStream(document, page);
PDFont font = PDType1Font.HELVETICA;
content.beginText();
content.setFont(font, 12);
// by default y = 0 pdf text start in the left bottom corner 
//  so you may need to put y = 700 or something to see the new line below 
content.moveTextPositionByAmount(x, y);
content.drawString("Some text.");
content.newLineAtOffset(0, -15);
content.drawString("some text ");
content.endText();

感谢@mkl的回复。没有名为setLeading的PDPageContentStream方法。我使用的是PDFBox版本1.8.8。您能解释一下@mkl向内容流添加原始命令的实际含义吗?向内容流添加原始命令的实际含义是什么?PDF文件包含页面内容,作为一系列基本操作(例如,绘制文本、设置文本前导或按当前文本前导前进)。添加原始命令意味着直接将数据(操作及其操作数)添加到该序列中。如果文本包含10000行,是否意味着应该调用drawString 10000次?
PDPageContentStream content = new PDPageContentStream(document, page);
PDFont font = PDType1Font.HELVETICA;
content.beginText();
content.setFont(font, 12);
// by default y = 0 pdf text start in the left bottom corner 
//  so you may need to put y = 700 or something to see the new line below 
content.moveTextPositionByAmount(x, y);
content.drawString("Some text.");
content.newLineAtOffset(0, -15);
content.drawString("some text ");
content.endText();