如何用Java版iText将PDF中嵌入的TTF字体导出为TTF文件?
从PDF导出嵌入的TTF字体(iText实现)
要导出PDF中嵌入的TTF字体,核心是逆向你提供的嵌入流程——从字体字典中提取FontFile2对应的PdfStream,读取流中的原始字节并保存为TTF文件即可,不需要处理字形,也用不到PdfWriter。
具体实现步骤
- 遍历PDF页面的资源字典,定位到字体条目集合。
- 逐个检查字体字典,找到包含
FontFile2项的条目(TTF字体通常存储在FontFile2中)。 - 从
FontFile2对应的间接引用中取出PdfStream,读取流的原始字节。 - 将字节写入本地文件,后缀设为
.ttf。
代码示例
import com.itextpdf.kernel.pdf.*; import java.io.FileOutputStream; import java.io.IOException; public class ExtractEmbeddedFont { public static void main(String[] args) throws IOException { PdfDocument pdfDoc = new PdfDocument(new PdfReader("input.pdf")); // 遍历所有页面 for (int pageNum = 1; pageNum <= pdfDoc.getNumberOfPages(); pageNum++) { PdfPage page = pdfDoc.getPage(pageNum); PdfDictionary resources = page.getResources(); if (resources == null) continue; // 获取页面字体字典 PdfDictionary fonts = resources.getAsDictionary(PdfName.Font); if (fonts == null) continue; // 遍历每个字体条目 for (PdfName fontName : fonts.keySet()) { PdfObject fontObj = fonts.get(fontName); if (!(fontObj instanceof PdfIndirectReference)) continue; PdfDictionary fontDict = ((PdfIndirectReference) fontObj).getRefersTo().getAsDictionary(); if (fontDict == null) continue; // 获取TTF字体对应的流 PdfObject fontFileObj = fontDict.get(PdfName.FontFile2); if (!(fontFileObj instanceof PdfIndirectReference)) continue; PdfStream fontStream = ((PdfIndirectReference) fontFileObj).getRefersTo().getAsStream(); if (fontStream == null) continue; // 读取字体字节并保存 byte[] fontBytes = fontStream.getBytes(); String outputFileName = fontName.toString().replace("/", "") + ".ttf"; try (FileOutputStream fos = new FileOutputStream(outputFileName)) { fos.write(fontBytes); System.out.println("已导出字体:" + outputFileName); } } } pdfDoc.close(); } }
关键说明
- 关于PdfWriter:不需要使用,因为我们是读取现有PDF的资源,而非生成新PDF,仅需
PdfReader和PdfDocument完成读取操作。 - 关于字形处理:完全不需要。嵌入在
FontFile2中的流本身就是完整或子集化的TTF文件字节,直接保存即可得到可用的TTF文件(子集化字体仅能显示PDF中出现过的字符)。
内容的提问来源于stack exchange,提问作者Kube
相关产品推荐
相关产品推荐

