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

如何解决PDFBox提取文本时的无Unicode映射编码错误?

解决PDFBox提取Adobe压缩PDF文本为空的GBK字体映射问题

问题原因

报错org.apache.pdfbox.pdmodel.font.PDType0Font [422] | | No Unicode mapping for CID+63 (63) in font BFLONM+SimSun,Bold-GBK-EUC-H的核心原因是:Adobe压缩PDF时对BFLONM+SimSun,Bold-GBK-EUC-H字体做了精简处理,仅保留了GBK编码的字形数据,未嵌入完整的CID到Unicode映射表,导致PDFBox无法将字体的CID字符转换为可识别的Unicode文本。

解决方案

1. 自定义PDFTextStripper补全GBK映射

扩展PDFTextStripper类,重写getUnicode方法,在遇到无映射的CID时,手动通过GBK编码转换为Unicode字符:

import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.text.PDFTextStripper;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

public class GBKCompatibleTextStripper extends PDFTextStripper {
    public GBKCompatibleTextStripper() throws IOException {
        super();
    }

    @Override
    protected String getUnicode(PDType0Font font, int cid) throws IOException {
        try {
            // 先尝试默认映射
            return super.getUnicode(font, cid);
        } catch (IllegalArgumentException e) {
            // 针对带GBK标识的字体,尝试GBK编码转换
            if (font.getName().contains("GBK-EUC-H")) {
                // 将CID转换为GBK双字节编码(需确认CID与GBK码位的对应关系,此处为通用逻辑)
                byte[] gbkBytes = {(byte) ((cid >> 8) & 0xFF), (byte) (cid & 0xFF)};
                try {
                    return new String(gbkBytes, "GBK");
                } catch (UnsupportedEncodingException ex) {
                    return "?";
                }
            }
            // 非GBK字体抛出原异常
            throw e;
        }
    }
}

使用时替换原PDFTextStripper:

PDDocument doc = PDDocument.load(new File("your.pdf"));
GBKCompatibleTextStripper stripper = new GBKCompatibleTextStripper();
String text = stripper.getText(doc);
doc.close();

2. 预处理PDF修复字体映射

通过工具重新生成PDF,强制嵌入完整的字体映射信息:

  • Adobe Acrobat:打开PDF后选择「另存为其他」→「优化PDF」,在字体设置中勾选「嵌入所有字体」并取消「子集化字体」,保存后即可修复映射。
  • Ghostscript命令行:执行以下命令重新生成PDF:
gs -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -dEmbedAllFonts=true -dSubsetFonts=false -o fixed.pdf input.pdf

3. 替换有问题的GBK字体

使用PDFBox将缺失映射的字体替换为系统中带完整Unicode映射的SimSun Bold字体:

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.cos.COSName;
import java.io.File;
import java.io.IOException;

public class FontReplacer {
    public static void main(String[] args) throws IOException {
        PDDocument document = PDDocument.load(new File("input.pdf"));
        for (PDPage page : document.getPages()) {
            PDResources resources = page.getResources();
            for (COSName fontName : resources.getFontNames()) {
                PDFont font = resources.getFont(fontName);
                if (font.getName().contains("BFLONM+SimSun,Bold-GBK-EUC-H")) {
                    // 加载系统中的SimSun Bold字体文件(需替换为实际路径)
                    PDType0Font newFont = PDType0Font.load(document, new File("C:/Windows/Fonts/simsunb.ttf"));
                    resources.put(fontName, newFont);
                }
            }
        }
        document.save("fixed.pdf");
        document.close();
    }
}

验证方法

处理完成后,重新用PDFTextStripper提取文本,检查输出内容是否正常,同时查看日志是否仍存在"No Unicode mapping"类错误。

内容的提问来源于stack exchange,提问作者yiCarlos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 10:37:27