docx4j word转pdf
WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(is);
这行代码 首次加载很慢 需要8s左右。第二次请求就正常,有什么办法能优化?
```java
public static void word2Pdf(InputStream is, String pdfPath) {
OutputStream os = null;
try {
WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(is);
Mapper fontMapper = new IdentityPlusMapper();
//加载字体文件(解决linux环境下无中文字体问题)
if (PhysicalFonts.get("SimSun") == null) {
PhysicalFonts.addPhysicalFonts("FangSong_GB2312", WordUtils.class.getResource("/font/GB2312.ttf"));
}
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"));
PhysicalFont simsunFont = PhysicalFonts.get("SimSun");
fontMapper.put("SimSun", simsunFont);
mlPackage.setFontMapper(fontMapper);
os = new java.io.FileOutputStream(pdfPath);
FOSettings foSettings = Docx4J.createFOSettings();
foSettings.setWmlPackage(mlPackage);
Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
is.close();//关闭输入流
os.close();//关闭输出流
} catch (Exception e) {
e.getMessage();
try {
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
} catch (Exception ex) {
ex.getMessage();
}
}
}
第一次加载耗时长是因为docx4j需要初始化一些内容。可以通过以下方式来优化:
1.第一次请求后预加载docx4j,使不必每次请求都重新初始化;
2.减少字体映射的数量,只加载实际使用的字体;
3.使用预先配置的docx4j的配置文件,而不是每次请求都重新配置;
4.关闭debug模式,减少打印信息的量。
首次调用load方法 耗时较长优化方向:
1、减小不必要的启动项
2、提前进行预启动
3、方法集成,直接引用
该回答引用ChatGPT
请参考下面的解决方案,如果有帮助,还请点击 “采纳” 感谢支持!
可以考虑使用一些优化方法来提高加载速度:
1、缓存:将加载好的文件进行缓存,下次请求时直接从缓存中读取,避免了重复加载的时间。
2、压缩文件:如果文件较大,可以考虑对文件进行压缩,加载时间缩短。
3、使用更快的加载方法:可以考虑使用更快的加载方法来加载文件,减少加载时间。
4、具体优化方法需要根据实际情况来确定,可以考虑需求以及代码的实现情况。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
代码优化:
1、将字体的配置移到独立的方法中,把配置单独处理,方便修改和维护。
2、将try-catch中的代码抽离出来,提高代码的可读性。
3、使用Java 7以上的自动关闭资源特性,简化代码,并且保证流的关闭。
public static void word2Pdf(InputStream is, String pdfPath) {
try (OutputStream os = new FileOutputStream(pdfPath)) {
WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(is);
Mapper fontMapper = createFontMapper();
mlPackage.setFontMapper(fontMapper);
FOSettings foSettings = Docx4J.createFOSettings();
foSettings.setWmlPackage(mlPackage);
Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
} catch (Exception e) {
e.printStackTrace();
}
}
private static Mapper createFontMapper() throws Exception {
Mapper fontMapper = new IdentityPlusMapper();
if (PhysicalFonts.get("SimSun") == null) {
PhysicalFonts.addPhysicalFonts("FangSong_GB2312", WordUtils.class.getResource("/font/GB2312.ttf"));
}
fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
...
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"));
PhysicalFont simsunFont = PhysicalFonts.get("SimSun");
fontMapper.put("SimSun", simsunFont);
return fontMapper;
}
根据您描述的问题,在使用docx4j的过程中,发现首次加载很慢的问题,这是由于首次加载需要初始化其中的JAXB content 。如果需要减少加载的时间,可以尝试如下方法:
1.加大jvm的内存大小,或者检查电脑cpu或内存是否过小。
2.如果可以,可以采用预加载的方式提前加载过来。
3.如果可以,把docx4j源码中,不需要的包删除。
要优化您提供的代码中 WordprocessingMLPackage 的加载时间,您可以考虑以下方法:
缓存对象:首次加载 WordprocessingMLPackage 后,您可以缓存对象以供后续使用。这样,您可以在将来的请求中重复使用同一对象,而不必每次都重新加载它。
增加内存分配:您可以增加 JVM 可用的内存量,因为这可能有助于加快初始加载时间。您可以通过在启动 JVM 时使用 -Xmx 选项来执行此操作,例如,通过运行以下命令:java -Xmx1024m -jar myapp.jar
优化文件格式:.docx格式的文字处理文件可能很大且复杂,这会减慢加载过程。您可以尝试将文件转换为更优化的格式,例如.pdf或.html,这可能会导致更快的加载时间。
并行处理:如果需要加载多个文字处理文件,可以考虑并行加载它们以减少整体加载时间。
升级到最新版本的 docx4j:较新版本的库可能包含性能优化、错误修复和其他有助于加快加载过程的改进。
请注意,最佳解决方案将取决于您的特定用例,您可能需要尝试不同的方法或方法组合来找到最适合您的方法。
如果耗时找不到有效的优化方案,建议就更换方法嘛,不就是将word转pdf,我给你推荐一篇,题主你参考一下,若有帮助,还望采纳,点击回答右侧采纳即可。
1、https://blog.csdn.net/weixin_43970743/article/details/125906262
2、https://blog.csdn.net/weixin_43970743/article/details/125907235