微信流量主挑战:用户数30!新增文档转化功能,解决docker运行jar包报错SimSun找不到的问题(新纪元5)

哎呀,今天忙到飞起,文章晚点更新啦!不过好消息是,我们的小程序用户终于突破30啦,感谢大家的支持!而且,大家期待已久的文档转化功能明天就要上线啦,目前支持word转pdf,pdf转图片,xlsx转pdf。

记录下难点,有个问题是在docker部署时候word转pdf没有中文乱码,控制台报错

024-12-27 23:59:11.769 WARN 1 --- [nio-8004-exec-3] org.docx4j.fonts.RunFontSelector : Font 'SimSun' is not mapped to a physical font. 2024-12-27 23:59:11.788 WARN 1 --- [nio-8004-exec-3] org.docx4j.fonts.RunFontSelector : Font 'Cambria' is not mapped to a physical font. 2024-12-27 23:59:11.807 WARN 1 --- [nio-8004-exec-3] org.docx4j.fonts.fop.util.FopConfigUtil : Document font Cambria is not mapped to a physical font!

大概意思是某个字体映射没有找到,网上说的大概流程是查看docker字体,没有就去下载之类的

但是我是通过window的c盘fonts转过去的,容器中也有字体了

通过window的c盘fonts转到容器

命令如下,docker容器外进行

docker cp /usr/share/fonts/truetype/dejavu/. eblog:/usr/share/fonts/truetype/chinese/

eblog为你的容器名称,/usr/share/fonts/truetype/dejavu/是以下部分

/usr/share/fonts/truetype/chinese/为容器内的文件夹

通过上述命令可以将字体库放入docker容器中了

但是后续打包好jar包后运行,还是会报SimSun找不到的错误,导致转pdf全是乱码

即使是直接将对应的字体文件引入都不行,这里我设置了字体映射注册也不行

        try {
            // 设置字体映射
            fontMapper.put("SimSun", PhysicalFonts.get("/usr/share/fonts/truetype/chinese/SIMSUN.TTC"));

            // 检查是否成功
            PhysicalFont font = PhysicalFonts.get("SimSun");
            if (font == null) {
                System.out.println("Failed to map SimSun to physical font.");
            } else {
                System.out.println("SimSun mapped to " + font.getName());
            }

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Failed to map fonts.");
        }

通过获取系统中所有已注册的字体并打印出来,发现并没有将SimSun注册

            PhysicalFonts.getPhysicalFonts().forEach((key, font) -> {
                System.out.println("Font: " + key);
            });

我的解决办法就是将sisum.ttc文件一起打包上去,将simsun.ttc放在resources下的fonts中

获取字体文件的 URL并且注册fontMapper.put("宋体", PhysicalFonts.get("SimSun"));

// 获取字体文件的 URL,路径相对于类路径(即 resources 目录)
        ClassLoader classLoader = FileServiceImpl.class.getClassLoader();
        URL fontUrl = classLoader.getResource("fonts/simsun.ttc");
        if (fontUrl == null) {
            throw new RuntimeException("Resource not found: " + fontUrl);
        }
        fontMapper.put("宋体", PhysicalFonts.get("SimSun"));

打包运行转换成功

完整代码如下

private String convertWordToPdf(String filePath) throws Exception {
        FileOutputStream fileOutputStream = null;
        try {
            // 获取当前时间戳
            String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());

            // 获取文件名(去掉路径和扩展名)
            File file = new File(filePath);
            String fileName = file.getName().replaceAll("\\.docx$", "");

            // 创建带时间戳的pdf路径,文件保存到fileDir目录下
            String pdfPath = fileDir + fileName + "_" + timestamp + ".pdf";

            // 进行文件转换
            fileOutputStream = new FileOutputStream(new File(pdfPath));
            WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(file);
            setFontMapper(mlPackage);
            Docx4J.toPDF(mlPackage, fileOutputStream);

            System.out.println("PDF转换成功,文件保存为:" + pdfPath);

            // 返回生成文件路径
            return fileName + "_" + timestamp + ".pdf";
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("转换失败");
            throw new UnsupportedOperationException("Word 转 PDF 的功能尚未实现: " + filePath);
        } finally {
            IOUtils.closeQuietly(fileOutputStream);
        }
    }

    private static void setFontMapper(WordprocessingMLPackage mlPackage) throws Exception {
        Mapper fontMapper = new IdentityPlusMapper();

        // 获取字体文件的 URL,路径相对于类路径(即 resources 目录)
        ClassLoader classLoader = FileServiceImpl.class.getClassLoader();
        URL fontUrl = classLoader.getResource("fonts/simsun.ttc");
        if (fontUrl == null) {
            throw new RuntimeException("Resource not found: " + fontUrl);
        }

        // 使用 PhysicalFonts 添加字体
        PhysicalFonts.addPhysicalFonts("SimSun", fontUrl);
        fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
        fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
        fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));
        fontMapper.put("黑体", PhysicalFonts.get("SimHei"));
        fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));
        fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));
        fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
        fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));
        fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));
        fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));
        fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));
        fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));
        fontMapper.put("等线", PhysicalFonts.get("SimSun"));
        fontMapper.put("等线 Light", PhysicalFonts.get("SimSun"));
        fontMapper.put("华文琥珀", PhysicalFonts.get("STHupo"));
        fontMapper.put("华文隶书", PhysicalFonts.get("STLiti"));
        fontMapper.put("华文新魏", PhysicalFonts.get("STXinwei"));
        fontMapper.put("华文彩云", PhysicalFonts.get("STCaiyun"));
        fontMapper.put("方正姚体", PhysicalFonts.get("FZYaoti"));
        fontMapper.put("方正舒体", PhysicalFonts.get("FZShuTi"));
        fontMapper.put("华文细黑", PhysicalFonts.get("STXihei"));
        fontMapper.put("宋体扩展",PhysicalFonts.get("simsun-extB"));
        fontMapper.put("仿宋_GB2312",PhysicalFonts.get("FangSong_GB2312"));
        fontMapper.put("新細明體",PhysicalFonts.get("SimSun"));
        //解决宋体(正文)和宋体(标题)的乱码问题
        PhysicalFonts.put("PMingLiU", PhysicalFonts.get("SimSun"));
        PhysicalFonts.put("新細明體", PhysicalFonts.get("SimSun"));
        // 设置字体映射
        mlPackage.setFontMapper(fontMapper);

    }

有兴趣体验小程序,搜索Listen Hui帮工办

相关推荐
kingbal2 天前
uniapp:编译微信、h5都正常的,编译钉钉小程序无法找到页面
微信·uni-app·钉钉
陶然同学2 天前
【畅购商城】微信支付之支付回调和支付状态
java·mysql·微信·springcloud
陶然同学2 天前
【畅购商城】微信支付之支付模块
java·spring boot·后端·mysql·微信
至尊鸡4 天前
微信流量主挑战:三天25用户!功能未完善?(新纪元4)
微信
至尊鸡4 天前
微信流量主挑战:用户破16!新增文档转换(新纪元3)
微信
大脸猫脸大5 天前
微信V3支付报错 平台证书及平台证书序列号
微信
wmd131643067128 天前
将微信配置信息存到数据库并进行调用
数据库·微信
陈思杰系统思考Jason8 天前
系统思考—全局思维
百度·微信·微信公众平台·新浪微博·微信开放平台