java代码pdfbox将PDF转图片后,中文乱码变成方框

文章讲述了在使用PDFBox将PDF转换为图片时遇到中文乱码的问题,通过分析日志发现是由于缺少STSong-Light字体。提供了两种解决方案:一是安装AdobeSongStd-Light字体,二是自定义FontMapperImpl类,将STSong-Light映射到已存在的AdobeSongStd-Light字体。
摘要由CSDN通过智能技术生成

问题现象:

使用pdfbox,将PDF转成图片后,其中的中文显示乱码(方块□□□□□)
控制台日志如下:

no glyph for 38472 (CID 04e7) in font STSong-Light

解读此行日志,先识别字体为STSong-Light,但系统中没有找到此字库,所以默认匹配到了MalgunGothic-Semilight。此字库为韩语字库,无法显示出中文,所以中文显示为□□□□□。

 上述类中的63行打了一个日志表示找不到字体。大概就是这样的:
在这里插入图片描述

if (!font.hasGlyph(code)){int cid = font.getParent().codeToCID(code);String cidHex = String.format("%04x", cid);LOG.warn("No glyph for " + code + " (CID " + cidHex + ") in font " + fontName);}

从 提出字体的地址 中看到,AdobeSongStd-Light.otf,这个字体可以解决这个问题。

解决方案1:

AdobeSongStd-Light.otf

电脑安装上面字体,C:\Windows\Fonts目录下,或者在项目中加载字体,但是当时openshift时有时加载失败,windows暂没问题。

解决方案2:(推荐)

进入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"));

重新执行就成功了。

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
PDFBox是一个用于处理PDF文件的Java库,它提供了一系列的API,可以用来读取、创建和修改PDF文件。虽然PDFBox本身并不直接支持将PDF换为Word文档,但可以通过其他方式实现这个功能。 一常见的方法是使用PDFBox读取PDF文件的内容,并将其换为纯文本格式。然后,可以使用Apache POI或其他类似的库来创建一个新的Word文档,并将纯文本内容写入其中。 以下是一个简单的示例代码,演示了如何使用PDFBox和Apache POI将PDF换为Word文档: ```java import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.text.PDFTextStripper; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class PDFToWordConverter { public static void main(String[] args) { try { // 加载PDF文件 PDDocument document = PDDocument.load(new FileInputStream("input.pdf")); // 创建Word文档 XWPFDocument wordDocument = new XWPFDocument(); // 提取PDF内容 PDFTextStripper stripper = new PDFTextStripper(); String text = stripper.getText(document); // 将内容写入Word文档 XWPFParagraph paragraph = wordDocument.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText(text); // 保存Word文档 FileOutputStream out = new FileOutputStream("output.docx"); wordDocument.write(out); out.close(); // 关闭PDF文档 document.close(); System.out.println("PDF换为Word成功!"); } catch (IOException e) { e.printStackTrace(); } } } ``` 请注意,这只是一个简单的示例,实际应用中可能需要更复杂的处理逻辑和错误处理。另外,换的结果可能会因PDF文件的结构和格式而有所差异。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值