部分心得。不一定完全正确。
一、
项目要做生成docx报表。包括文字、表格、折线图、柱状图等。
主要参考了博客:
java使用poi在word中生成柱状图、折线图、饼图、柱状图+折线图组合图、动态表格、文本替换、图片替换、更新内置Excel数据、更新插入的文本框内容、合并表格单元格;
博客内容是,写好模板后,如何向内填写数据。博文最后有源码链接。该文档引用的poi是4.1.0。
注意:
1、对于模板文件,其中的 {{可替代文字}} ,需要从记事本中拷贝过去。
2、docx的折线图等,模板文件中插入图表的时候,需要使用默认的数据(不包括标题、折线颜色等),不可修改数据,不然使用poi替换数据的时候会报错。(当然也可能是因为我使用的是wps不是office的问题,这个没有验证)
二、poi版本
对于doc文件来说,无论是poi3还是poi4,都无法编辑其中的折线图等图表。
对于docx文件来说,只有poi4可以编辑折线图等图表。
三、另存为功能
参考博客
需要引入ooxml-schemas-版本号.jar,注意不是poi-ooxml-schemas-版本号.jar。当然后者也需要引入。
我这里需求是将docx文件另存为html文件或pdf文件。
对于poi3来说,docx转化为html或pdf,需要引入 org.apache.poi.xwpf.converter.core,org.apache.poi.xwpf.converter.xhtml (或pdf)。
对于poi4来说,docx转化为html或pdf,需要引入 fr.opensagres.poi.xwpf.converter.core-2.0.2.jar,fr.opensagres.poi.xwpf.converter.xhtml-2.0.2.jar(或pdf)。
但是现在来说,还是有点问题,这个poi4导出的html文件,不能显示图表。但是poi自带的导出excel文件是可以显示图表的。
为了实现另存为html文件,下载了jacob。相当于用java文件调用本机的office。这个必须在windows机器上安装了office后才可以使用。
下载链接:
https://sourceforge.net/projects/jacob-project/files/
源码链接
https://github.com/freemansoft/jacob-project
但是我没有找到怎么下载jar包,最终下载的1.7版本的:
https://dl.pconline.com.cn/download/1812052-1.html
根据博客:
https://blog.csdn.net/SHBWeiXiao/article/details/78392382
这样放进去。就可以使用了。
对于1.19版本的,还需在环境变量配置的java_home/bin,里面放进去dll文件。64系统放x64,32系统放x86。
public static void convertHtml(String filePath) {
File ff = new File(filePath.replace(".docx", ".html"));
if(ff.exists()){
ff.delete();
}
delFile(filePath.replace(".docx", ".files"));
ActiveXComponent app = null;
try {
app = new ActiveXComponent("Word.Application");
app.setProperty("Visible", new Variant(false));
// documents表示word程序的所有文档窗口,(word是多文档应用程序)
Dispatch docs = app.getProperty("Documents").toDispatch();
// 打开要转换的word文件
Dispatch doc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[] { filePath, new Variant(false), new Variant(true) }, new int[1])
.toDispatch();
// 作为html格式保存到临时文件
Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] { filePath.replace(".docx", ".html"), new Variant(WORD_HTML) }, new int[1]);
// 关闭word文件
Dispatch.call(doc, "Close", new Variant(false));
// 关闭word应用程序
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally{
if(app != null) {
app.invoke("Quit", 0);
}
}
}