微信流量主挑战:用户数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帮工办

相关推荐
风安•辛幸2 天前
mac上微信最新v4以上版客户端多开教程,亲测可用
macos·微信
智购科技无人售货机厂家2 天前
2026自动售货机出货口防夹手设计:从红外检测到电机反转的工程实践~YH
大数据·linux·单片机·嵌入式硬件·微信
QH139292318802 天前
R&S FSPN50 FSPN26 FSWP26 相位噪声分析仪典型应用案例
人工智能·百度·微信·集成测试·音视频·facebook·oneapi
UWA3 天前
GPM 2.0 WebGL 监测能力扩容|覆盖 Unity/Cocos/LayaAir 多引擎微信 & 抖音小游戏
unity·微信·性能优化·小游戏·webgl
运营秋秋4 天前
微信定时群发:设置一次自动触达
微信
极客互动API8 天前
企业微信 iPad 协议服务搭建与 AI 回调实战
网络·汇编·人工智能·微信·企业微信·ipad
极客互动API8 天前
企业微信 iPad 协议消息接口开发:文本 / 图片 / 群发消息的统一封装
人工智能·ios·微信·机器人·企业微信·ipad
Chengbei119 天前
DSH渗透测试插件dsh-pentest全新升级!适配DeepSeek Harness,可视化探索链路,一键搭建轻量化AI渗透测试环境。
人工智能·web安全·网络安全·微信·小程序·系统安全·安全架构
2501_9419820510 天前
个人微信API二次开发:多开回调串appId
微信
wechatbot88813 天前
极客互动企业微信 SCRM 私域运营实战效果全景
大数据·汇编·微信·自动化·企业微信·rpa