如何使用Apache PDFBox加载STSongStd-Light字体生成PDF文档?
问题描述
原有基于旧版iText的Java代码可生成含中文的PDF:
BaseFont baseFont = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", NOT_EMBEDDED); content.setFontAndSize(baseFont, 15);
因授权问题改用Apache PDFBox,但尝试手动构建CIDFont时遇到困难,且加载STSong-Light.ttf字体文件时抛出异常:
Exception in thread "main" java.io.IOException: head is mandatory at org.apache.fontbox.ttf.TTFParser.parseTables(TTFParser.java:197) at org.apache.fontbox.ttf.TTFParser.parse(TTFParser.java:165) at org.apache.fontbox.ttf.TTFParser.parse(TTFParser.java:91) at org.apache.pdfbox.pdmodel.font.PDTrueTypeFont.load(PDTrueTypeFont.java:93)
解决方案
1. 排查字体文件有效性
异常head is mandatory说明你使用的STSong-Light.ttf文件损坏或不是标准TrueType格式。请确认字体文件来源可信(如系统字体库、官方授权渠道),确保文件完整无损坏。
2. 正确加载中文字体的PDFBox实现
不需要手动构建复杂的CIDFont底层结构,PDFBox提供了PDType0Font类,可直接加载支持中文的TrueType字体,对应iText中CID字体的使用方式:
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDType0Font; import java.io.File; import java.io.IOException; public class ChinesePdfGenerator { public static void main(String[] args) throws IOException { try (PDDocument document = new PDDocument()) { PDPage page = new PDPage(); document.addPage(page); // 加载STSong-Light.ttf,自动处理CID字符映射 // 第三个参数设为false可关闭字体嵌入,对应iText的NOT_EMBEDDED PDType0Font font = PDType0Font.load(document, new File("path/to/STSong-Light.ttf"), false); try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) { contentStream.beginText(); contentStream.setFont(font, 15); contentStream.newLineAtOffset(50, 700); // 设置文本起始位置 contentStream.showText("这是用PDFBox生成的中文测试文本"); contentStream.endText(); } document.save("chinese_output.pdf"); } } }
关键说明
PDType0Font会自动将TrueType字体包装为Type0/CID字体,完美支持中文等大字符集,对应iText中UniGB-UCS2-H编码的使用场景- 若需要嵌入字体(保证在无该字体的机器上正常显示),去掉
load方法的第三个参数即可(默认值为true) - 避免手动操作
COSDictionary、PDCIDFontType2等底层类,PDFBox的高层API已封装好字体加载逻辑
内容的提问来源于stack exchange,提问作者manji369
相关产品推荐
相关产品推荐

