[POI] ofdrw 2.1.0 转换pdf,部分ofd内部字体无法加载的问题

导致字体无法加载主要有两个因素: 1. 系统内没有安装对应的字体 2. 如果是ofd文件ofdrw首先去ofd解压文件抓取内部字体文件,如果这里出现异常会导致该部分字体无法正常显示。相关问题也可以看我这篇开发手账(一),下面是解决方案

一、对于没有安装字体的,需要安装字体,或者使用org.ofdrw.converter.FontLoader#scanFontDir(java.nio.file.Path)进行启动时扫描,可使用反射对以加载字体进行查看。

Field namePathMapping = ReflectUtil.getField(FontLoader.class, "fontNamePathMapping");

Map<String, String> fontNamePathMapping = (Map<String, String>) ReflectUtil.getFieldValue(preload,namePathMapping);

System.out.println("已加载字体:" + JSONUtil.toJsonStr(fontNamePathMapping.keySet()));

二、ofdrw会走下面的方法org.ofdrw.converter.FontLoader#loadFontSimilarStream进行字体加载,可用看到它在首次会判断从ResourceLocator 加载ctFont,并没有对字体文件有效性进行判断,如果外部异常,则无法加载默认字体从而导致部分文字直接显示不出来。

解决方法:可用直接注释掉内嵌字体绝对路径几行代码(我选用的),或者在异常报错处进行捕获并加载有效字体。需要这里都是需要对ofdrw源码进行修改

    public InputStream loadFontSimilarStream(ResourceLocator rl, CT_Font ctFont) {
   
        byte[] buf = null;
        try {
   
            if (ctFont != null) {
   
                // 内嵌字体绝对路径
                ST_Loc fontFileLoc = ctFont.getFontFile();
                if (fontFileLoc != null) {
   
                    String fontAbsPath = rl.getFile(ctFont.getFontFile()).toAbsolutePath().toString();
                    buf = Files.readAllBytes(Paths.get(fontAbsPath));
                } else {
   

                    // 无法从内部加载时,通过相似字体查找
                    String similarFontPath = getReplaceSimilarFontPath(ctFont.getFamilyName(), ctFont.getFontName());
                    if (similarFontPath != null) {
   
                        buf = Files.readAllBytes(Paths.get(similarFontPath));
                    }
                }
            }
        } catch (Exception e) {
   
            if (DEBUG) {
   
                log.warn("无法加载字体: " + ctFont.getFamilyName() + " " + ctFont.getFontName() + " " + ctFont.getFontFile(), e);
            }
        }

        if (buf == null || buf.length == 0) {
   
            try {
   
                buf = Files.readAllBytes(DefaultFontPath);
            } catch (IOException e) {
   
                throw new RuntimeException("默认字体文件读取异常", e);
            }
        }
        return new ByteArrayInputStream(buf);
    }

最近更新

  1. TCP协议是安全的吗?

    2023-12-05 19:52:06       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-05 19:52:06       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-05 19:52:06       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-05 19:52:06       20 阅读

热门阅读

  1. Visual Studio Code之自动补全的设置

    2023-12-05 19:52:06       34 阅读
  2. Kafka常见面试题

    2023-12-05 19:52:06       40 阅读
  3. 视图与模板

    2023-12-05 19:52:06       37 阅读
  4. Linux_Linux终端常用快捷键

    2023-12-05 19:52:06       33 阅读
  5. Git分支合并导致文件异常

    2023-12-05 19:52:06       31 阅读
  6. 生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)

    2023-12-05 19:52:06       38 阅读
  7. Easy Excel设置表格样式

    2023-12-05 19:52:06       35 阅读
  8. 【前端】html不渲染换行\n\t\r等的问题

    2023-12-05 19:52:06       37 阅读
  9. CCF-CSP 202303-2 垦田计划

    2023-12-05 19:52:06       35 阅读
  10. 山东济南原画培训机构如何选择?

    2023-12-05 19:52:06       39 阅读