我是否必须在PDFBox的每一行上设置偏移量或光标?

时间:2016-07-01 07:49:28

标签: java pdfbox

我正在尝试学习PDFBox v2.0,但似乎没有什么有用的示例和教程可以开始。

我想创建一个只带文字的简单PDF(没有图片和花哨的东西),它看起来如下:

1- Introduction
   This is an intro to the document

2- Data
   2.1- DataPart1
   This is some text here....
   2.2- DataPart2
   This is another text right here!

3- More Information
   Some important informational text here...

我写了以下代码:

       PDPage firstPage = getNewPage();
PDPageContentStream firstContentStream = new PDPageContentStream(document, firstPage);
firstContentStream.setFont(HEADING_FONT, HEADING_FONT_SIZE);
firstContentStream.setNonStrokingColor(Color.BLUE);
firstContentStream.beginText();
firstContentStream.newLineAtOffset(MARGIN, firstPage.getMediaBox().getHeight() - MARGIN);
firstContentStream.showText("1- Introduction");
firstContentStream.endText();

firstContentStream.setFont(TEXT_FONT, TEXT_FONT_SIZE);
firstContentStream.setNonStrokingColor(Color.BLACK);
firstContentStream.beginText();
firstContentStream.showText("This document lists all the impacts that have been observed during the QA validation of the version v3.1 build");
firstContentStream.endText();
firstContentStream.close();
document.addPage(firstPage);

文字"这是文件介绍"出现在页面的末尾!

我的问题:我是否必须在每一行设置光标或offset ???!

这似乎很辛苦。这是否意味着我必须计算字符串宽度并将其与页面宽度进行比较,并在文本填满整行时跳转到新行?

我真的不明白。

还有如何在当前页面已满时生成新页面?

请举一个简单的例子?提前致谢

我不能做类似的事情:

contentStream.addTextOnNewLine("Some text here...");

1 个答案:

答案 0 :(得分:1)

首先请注意,PDFBox只有一个非常低级的文本绘图API,即您直接调用的大多数方法都对应于PDF内容流中的单个指令。特别是PDFBox没有(公共可访问的)布局功能,但你必须在代码中进行布局。这既是一种自由(你不受现有机器的限制)和负担(你必须自己做所有事情)。

在您的情况下,这意味着:

  

这是否意味着我必须计算字符串宽度并将其与页面宽度进行比较,并在文本填满整行时跳转到新行?

是。给@Tilman链接的答案

并在stackoverflow上搜索更多内容,对该主题的不同变体有进一步的答案,例如:对于合理的文本块here

但是你的代码中有一个细节,在你的情况下,事情可能比必要的更难:

  

我的问题:我是否必须在每一行设置光标或偏移量???!

虽然你必须为每一个新行重新定位,但如果你仍然在同一个文本对象中,那么从上一行的开头偏移重新定位,即您尚未在中间调用endText()beginText()。 E.g:

PDPage firstPage = getNewPage();
PDPageContentStream firstContentStream = new PDPageContentStream(document, firstPage);
firstContentStream.setFont(HEADING_FONT, HEADING_FONT_SIZE);
firstContentStream.setNonStrokingColor(Color.BLUE);
firstContentStream.beginText();
firstContentStream.newLineAtOffset(MARGIN, firstPage.getMediaBox().getHeight() - MARGIN);
firstContentStream.showText("1- Introduction");
// removed firstContentStream.endText();

firstContentStream.setFont(TEXT_FONT, TEXT_FONT_SIZE);
firstContentStream.setNonStrokingColor(Color.BLACK);
// removed firstContentStream.beginText();
firstContentStream.newLineAtOffset(0, -TEXT_FONT_SIZE); // reposition, tightly packed text lines
firstContentStream.showText("This document lists all the impacts that have been observed during the QA validation of the version v3.1 build");
firstContentStream.endText();
firstContentStream.close();
document.addPage(firstPage);

newLineAtOffset(0, -TEXT_FONT_SIZE)将文本插入位置设置为与上一行的开头相同的x坐标,并将TEXT_FONT_SIZE单位设置为较低。

(在这里使用TEXT_FONT_SIZE会产生相当紧密的文本行;您可能需要使用更高的值,例如字体大小的1.4倍。)

考虑到您的描述,您可能希望在标题后使用正x偏移值。

  

页面末尾出现文本“这是文档介绍”!

这是因为firstContentStream.beginText()生成的PDF指令将文本插入位置重置为原点(0,0),默认情况下是左下角。

  

还有如何在当前页面已满时生成新页面?

嗯,这不会自动发生,当你想切换到新页面时,你必须明确地这样做。而且你或多或少地像创建你的第一页一样。