You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过PDFBox库为PDF设置wordSpacing(Tw)

如何通过PDFBox库为PDF设置wordSpacing(Tw)

刚好遇到过类似的问题,我来给你拆解下原因和解决办法:

问题根源

你设置的wordSpacing(也就是PDF里的Tw参数)只对PDF内容中实际存在的空格字符(U+0020)生效,但PDFBox的showText()方法在处理带空格的文本时,尤其是使用TrueType这类复合字体时,会自动把空格当成文本分隔符,不会将空格字符编码到最终的Tj指令里——你贴出的PDF指令里看不到空格,就是这个原因,自然Tw就没效果了。

解决方案

这里给你两种可行的办法,根据你的字体需求选就行:

方案一:改用Type1内置字体(最简单)

PDFBox内置的Type1字体(比如PDType1Font.HELVETICA、PDType1Font.TIMES_ROMAN)默认编码包含空格字符,showText()会正确保留空格,此时setWordSpacing()就能直接生效。修改你的代码:

try (PDPageContentStream stream = new PDPageContentStream(
                pdf,
                page,
                PDPageContentStream.AppendMode.APPEND,
                false,
                true)
        ) {
            stream.saveGraphicsState();
            // 替换成Type1字体,这里用Helvetica举例
            PDType1Font font = PDType1Font.HELVETICA;
            float fontSize = 12; // 按需调整字号
            stream.setFont(font, fontSize);
            stream.setNonStrokingColor(Color.BLACK); // 按需调整颜色
            stream.beginText();
            stream.newLineAtOffset(100, 100);
            stream.setWordSpacing(50); // 字间距设置现在会生效
            stream.showText("HELLO WORLD");
            stream.endText();
            stream.restoreGraphicsState();
}

方案二:手动处理空格(适用于必须用自定义字体的场景)

如果你一定要用TrueType这类复合字体,可以手动拆分文本并输出空格,或者直接编码带空格的字符串用原始指令输出,确保PDF里有实际的空格字符:

try (PDPageContentStream stream = new PDPageContentStream(
                pdf,
                page,
                PDPageContentStream.AppendMode.APPEND,
                false,
                true)
        ) {
            stream.saveGraphicsState();
            stream.setFont(font, fontSize);
            stream.setNonStrokingColor(color);
            stream.beginText();
            stream.newLineAtOffset(100, 100);
            stream.setWordSpacing(50);
            
            // 方法1:拆分文本,手动输出空格
            stream.showText("HELLO");
            // 用字体编码空格,确保能被PDF识别
            byte[] spaceBytes = font.encode(" ");
            stream.addRawCommand(String.format("(%s) Tj", new String(spaceBytes)));
            stream.showText("WORLD");
            
            // 方法2:直接编码整个带空格的字符串,用原始指令输出
            // byte[] fullTextBytes = font.encode("HELLO WORLD");
            // stream.addRawCommand(String.format("(%s) Tj", new String(fullTextBytes)));
            
            stream.endText();
            stream.restoreGraphicsState();
}

验证效果

修改后你再查看PDF的内容指令,应该能看到包含空格的Tj片段,比如:

BT
  78.3975 777.75494 Td
  50 Tw
  (HELLO) Tj
  ( ) Tj
  (WORLD) Tj
ET

这时候Tw参数就会作用在空格上,实现你想要的字间距调整效果。

备注:内容来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:05:29