问题现象:
使用pdfbox,将PDF转成图片后,其中的中文显示乱码(方块□□□□□)
控制台日志如下:
2020-08-18 00:41:12.388 WARN 2848 --- [nio-8081-exec-7] o.a.pdfbox.pdmodel.font.PDCIDFontType0 : Using fallback MalgunGothic-Semilight for CID-keyed font STSong-Light
2020-08-18 00:41:12.499 WARN 2848 --- [nio-8081-exec-7] o.a.pdfbox.rendering.CIDType0Glyph2D : No glyph for 37197 (CID 0ba5) in font STSong-Light
2020-08-18 00:41:12.502 WARN 2848 --- [nio-8081-exec-7] o.a.pdfbox.rendering.CIDType0Glyph2D : No glyph for 22871 (CID 0e2a) in font STSong-Light
2020-08-18 00:41:12.504 WARN 2848 --- [nio-8081-exec-7] o.a.pdfbox.rendering.CIDType0Glyph2D : No glyph for 22269 (CID 0753) in font STSong-Light
2020-08-18 00:41:12.504 WARN 2848 --- [nio-8081-exec-7] o.a.pdfbox.rendering.CIDType0Glyph2D : No glyph for 32593 (CID 0ea9) in font STSong-Light
分析:
Using fallback MalgunGothic-Semilight for CID-keyed font STSong-Light
解读此行日志,先识别字体为STSong-Light,但系统中没有找到此字库,所以默认匹配到了MalgunGothic-Semilight。此字库为韩语字库,无法显示出中文,所以中文显示为□□□□□。
解决:
进入pdfbox包内的如下文件
找到如下位置,可以看到substitutes内的一个映射关系,我们可以将STSong-Light映射到另一已存在的字体
FontMapperImpl() {
this.substitutes.put("Courier", Arrays.asList("CourierNew", "CourierNewPSMT", "LiberationMono", "NimbusMonL-Regu"));
this.substitutes.put("Courier-Bold", Arrays.asList("CourierNewPS-BoldMT", "CourierNew-Bold", "LiberationMono-Bold", "NimbusMonL-Bold"));
this.substitutes.put("Courier-Oblique", Arrays.asList("CourierNewPS-ItalicMT", "CourierNew-Italic", "LiberationMono-Italic", "NimbusMonL-ReguObli"));
this.substitutes.put("Courier-BoldOblique", Arrays.asList("CourierNewPS-BoldItalicMT", "CourierNew-BoldItalic", "LiberationMono-BoldItalic", "NimbusMonL-BoldObli"));
this.substitutes.put("Helvetica", Arrays.asList("ArialMT", "Arial", "LiberationSans", "NimbusSanL-Regu"));
this.substitutes.put("Helvetica-Bold", Arrays.asList("Arial-BoldMT", "Arial-Bold", "LiberationSans-Bold", "NimbusSanL-Bold"));
this.substitutes.put("Helvetica-Oblique", Arrays.asList("Arial-ItalicMT", "Arial-Italic", "Helvetica-Italic", "LiberationSans-Italic", "NimbusSanL-ReguItal"));
this.substitutes.put("Helvetica-BoldOblique", Arrays.asList("Arial-BoldItalicMT", "Helvetica-BoldItalic", "LiberationSans-BoldItalic", "NimbusSanL-BoldItal"));
this.substitutes.put("Times-Roman", Arrays.asList("TimesNewRomanPSMT", "TimesNewRoman", "TimesNewRomanPS", "LiberationSerif", "NimbusRomNo9L-Regu"));
this.substitutes.put("Times-Bold", Arrays.asList("TimesNewRomanPS-BoldMT", "TimesNewRomanPS-Bold", "TimesNewRoman-Bold", "LiberationSerif-Bold", "NimbusRomNo9L-Medi"));
this.substitutes.put("Times-Italic", Arrays.asList("TimesNewRomanPS-ItalicMT", "TimesNewRomanPS-Italic", "TimesNewRoman-Italic", "LiberationSerif-Italic", "NimbusRomNo9L-ReguItal"));
this.substitutes.put("Times-BoldItalic", Arrays.asList("TimesNewRomanPS-BoldItalicMT", "TimesNewRomanPS-BoldItalic", "TimesNewRoman-BoldItalic", "LiberationSerif-BoldItalic", "NimbusRomNo9L-MediItal"));
this.substitutes.put("Symbol", Arrays.asList("Symbol", "SymbolMT", "StandardSymL"));
this.substitutes.put("ZapfDingbats", Arrays.asList("ZapfDingbatsITC", "Dingbats", "MS-Gothic"));
Iterator var1 = Standard14Fonts.getNames().iterator();
先按照这个FontMapperImpl类在自己的项目中建立一个和这个路径完全一致的FontMapperImpl类,代码内容复制过来。
并在substitutes中增加一个STSong-Light的映射关系,映射到我的环境中已有的AdobeSongStd-Light字体。
this.substitutes.put("STSong-Light", Arrays.asList("AdobeSongStd-Light","DengXian"));
启动项目,即可显示中文。