如何使用 PDFBox drawString 插入换行符

Posted

技术标签:

【中文标题】如何使用 PDFBox drawString 插入换行符【英文标题】:How to Insert a Linefeed with PDFBox drawString 【发布时间】:2011-11-27 17:25:13 【问题描述】:

我必须用表格制作 PDF。到目前为止它工作正常,但现在我想添加一个包装功能。所以我需要插入一个换行符。

contentStream.beginText();  
contentStream.moveTextPositionByAmount(x, y);  
contentStream.drawString("Some text to insert into a table.");  
contentStream.endText();  

我想在“插入”之前添加一个“\n”。我尝试了“\u000A”,这是换行的十六进制值,但 Eclipse 显示错误。

是否可以用drawString添加换行符?

【问题讨论】:

【参考方案1】:

PDF 格式允许换行,但 PDFBox 没有内置换行功能。

要在 PDF 中使用换行符,您必须使用 TL-operator 定义要使用的前导。 T*-操作符换行。 '-运算符将给定的文本写入下一行。 (有关更多详细信息,请参阅 PDF 规范,“文本”一章。没有那么多。)

这里有两个代码sn-ps。两者都做同样的事情,但第一个 sn-p 使用',第二个 sn-p 使用T*

private void printMultipleLines(
    PDPageContentStream contentStream,
    List<String> lines,
    float x,
    float y) throws IOException 
  if (lines.size() == 0) 
    return;
  
  final int numberOfLines = lines.size();
  final float fontHeight = getFontHeight();

  contentStream.beginText();
  contentStream.appendRawCommands(fontHeight + " TL\n");
  contentStream.moveTextPositionByAmount(x, y);
  contentStream.drawString(lines.get(0));
  for (int i = 1; i < numberOfLines; i++) 
    contentStream.appendRawCommands(escapeString(lines.get(i)));
    contentStream.appendRawCommands(" \'\n");
  
  contentStream.endText();


private String escapeString(String text) throws IOException 
  try 
    COSString string = new COSString(text);
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    string.writePDF(buffer);
    return new String(buffer.toByteArray(), "ISO-8859-1");
   catch (UnsupportedEncodingException e) 
    // every JVM must know ISO-8859-1
    throw new RuntimeException(e);
  

使用T* 换行:

private void printMultipleLines(
    PDPageContentStream contentStream,
    List<String> lines,
    float x,
    float y) throws IOException 
  if (lines.size() == 0) 
    return;
  
  final int numberOfLines = lines.size();
  final float fontHeight = getFontHeight();

  contentStream.beginText();
  contentStream.appendRawCommands(fontHeight + " TL\n");
  contentStream.moveTextPositionByAmount( x, y);
  for (int i = 0; i < numberOfLines; i++) 
    contentStream.drawString(lines.get(i));
    if (i < numberOfLines - 1) 
      contentStream.appendRawCommands("T*\n");
    
  
  contentStream.endText();

要获取字体的高度,您可以使用以下命令:

fontHeight = font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize;

您可能希望将它乘以一些线间距因子。

【讨论】:

是否还有理由继续使用现已弃用的drawString + appendRawCommands 而不是tutorialspoint.com/pdfbox/pdfbox_adding_multiple_lines.htm 中所述的showTextnewLine @Simon Sobisch 非常感谢,其他 cmets 现在已经快 10 岁了并且已经过时了,tutorialspoint 链接很有帮助。【参考方案2】:

由于 PDF 模型通常不是手头任务的最佳模型,因此为它编写一个包装器以增加对您案例中“缺失”的任何内容的支持通常是有意义的。阅读和写作都是如此。

【讨论】:

【参考方案3】:

pdf 格式不知道换行符。您必须使用 moveTextPositionByAmount 拆分字符串并将文本位置移动到下一行。

这不是一个特殊的“pdfbox-feature”,这是由于pdf格式的定义;所以drawString没有办法,也没有其他方法可以调用支持换行。

【讨论】:

@Erik:但是T*- 和'- 运算符是怎么回事? pdf-spec 对 T* 说:“移到下一行的开头”。并到':“移动到下一行并显示一个文本字符串”。但我找不到在 pdfBox 中使用 T* 或 ' 的方法。 (而且我不确定我对规范的理解是否正确。)

以上是关于如何使用 PDFBox drawString 插入换行符的主要内容,如果未能解决你的问题,请参考以下文章

PDFBOX 2.0.18 - 如何遍历 PDF 页面并检索特定字段

如何对齐 SpriteBatch.DrawString 绘制的文本?

drawString 方法如何用于编写对角线方式

PDFbox 1.7.0 - 如何在使用PDFBox添加新图像时保留现有图像?

如何使用 PDFBox 使文本居中

如何使用 pdfbox 用特定字体填写 PDF 表单?