我有一个旧的Perl脚本,该脚本生成一个.pdf文件,该文件可以打印在穿孔的卡片上(例如Avery模板28878)。我正在将该脚本转换为Java,并选择使用iTextPDF7。到目前为止,我可以毫无问题地生成10张“卡片”(使用绝对位置)。

我试图将文本添加到每个“卡”中的绝对位置,并根据字体大小的宽度设置该文本的字体大小。

至于字体大小部分,我正在旧的Perl脚本中执行以下操作,并且与PDF :: API2一起使用时效果很好

# Font size 16 width = 184.832
$nameText->font($fonts->{'times'}, $nameFontSize);
while(int($nameText->advancewidth($name)) > 185){
    $nameFontSize--;
    $nameText->font($fonts->{'times'}, $nameFontSize);
}


为了实际设置绝对位置,我在Perl中执行以下操作

my $nameText = $pdfPage->text();
$nameText->translate(($xCoord + 151), ($yCoord + 73));
$nameText->text_center($name);


我无法弄清楚如何使用iTextPDF 7将其转换为Java。

所以,我该如何使用iTextPDF 7
将文字设置为绝对位置?

获取该文本对象的当前宽度?

最佳答案

我给你的代码既高层次又低层次。它是高级的,因为它允许设置非常高级的属性,例如单词/字符间距,对齐方式,使用复杂的脚本等,而无需修改字体大小计算方法。另一方面,它是低级别的,因为您将进行很多通常在后台进行的手动布局工作。

请注意,这只是您要实现的目标的一种方法。我至少可以想到另外两个。您可以去寻找iText7示例以寻找灵感。

PdfDocument pdfDocument = new PdfDocument(new PdfWriter("..."));
pdfDocument.addNewPage();
int pageNumber = 1;
PdfPage page = pdfDocument.getPage(pageNumber);

String text = "Hello World! This is an answer to a SO question";
Paragraph paragraph = new Paragraph(text).
      setMargin(0).
      setMultipliedLeading(1).
      setFont(PdfFontFactory.createFont(FontConstants.TIMES_ROMAN));

float fontSize = 50;
paragraph.setFontSize(fontSize);
paragraph.setBackgroundColor(Color.RED); // Just to see that text is aligned correctly
float allowedWidth = 185;

Canvas canvas = new Canvas(new PdfCanvas(page), pdfDocument, page.getMediaBox());
RootRenderer canvasRenderer = canvas.getRenderer();
while (paragraph.createRendererSubTree().setParent(canvasRenderer).layout(new LayoutContext(new LayoutArea(pageNumber, new Rectangle(allowedWidth, fontSize * 2)))).getStatus() != LayoutResult.FULL) {
    paragraph.setFontSize(--fontSize);
}
float xCoord = 151;
float yCoord = 73;

paragraph.setWidth(allowedWidth);
canvas.showTextAligned(paragraph, xCoord, yCoord, TextAlignment.CENTER);
canvas.close();
pdfDocument.close();


这是输出的样子:java - iTextPDF 7在绝对位置添加文本-LMLPHP
请注意,我们添加了红色背景,以使文本居中。

10-06 15:24