前几天项目中遇到word 文档不标准问题,我详细查找原因,总结 了几种方案,现在和大家分享一下。
一、想生成word文档,首先要有生产word的模板,这里给大家介绍三种方式,每种方式有相应的生产word文档的代码:
1、html 模板 生成方式,打开word文档样例,如下图所示!
然后单击F12 ,后显示如下
选择网页文件,保存后生成html格式的 文档 ,打开后如下图
word模板就再此基础上修改,标签:${ } 例如:${name},如果有多个对象可以用 list标签 如:<#list applicants as applyer>,更多的标签大家可以网上查询一下这里就不多写了。
A:这种html模板生成word文档,一般我们用freemarker 技术处理。再介绍一种模板后我们就上代码(因为有几张模板的代码实现基本是一样的),所需jar包:freemarker-2.3.16.jar
2、xml模板生产方式,首先给大家明确一下,原则上有两种xml模板,非原生的xml模板和原生的xml模版,这两张模板生成word文档的原理不一样,后面我会详细介绍。因为非原生的xml模板和html生成word文档的原理一样,这里就先介绍非原生xml模板的生产方式,如图:
A:如图选择xml格式,生成xml模板。注意:这里有一个必须要留意的地方,你打开文档所用的office 版本,希望大家进来用office2003版本(低版本),这里有一个向下兼容问题,程序员应该都理解这个道理。切记不要用wps打开word文档去另存为xml,因为wps兼容性太好,后期生成的word文档,会存在很多问题,主要是客户打不开(因为客户本地电脑的打开word文档的工具不确定)。xml模板里面的参数修改和html类似,改好后把文件尾由 .xml 改成 .ftl 另外文件名尽量用英文 不要用汉字。
3、通过java代码把以上两种模板生成word文档;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;/**
* @author: wanghuainan
* @version:
* @Date: Created in 2018年11月30日
*
*/
public class BoKeWordTest1 {
public static void main(String[] args) throws Exception {
Map<String,Object> dataMap=new HashMap<String,Object>();
getData(dataMap);
freemarkerHtmlTest(dataMap,null,null);
}
//封装模板参数
private static void getData(Map<String, Object> dataMap) {
dataMap.put("nian", "2016");
dataMap.put("yue", "3");
dataMap.put("address", "深圳市");
dataMap.put("name", "南道1");
dataMap.put("sex", "6");
dataMap.put("nling", "lc");
dataMap.put("xuehao", "111");
dataMap.put("neirong", "hhh好好");
List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
for (int i = 0; i < 3; i++) {
Map<String,Object> map = new HashMap<String,Object>();
map.put("xuehao", i);
map.put("neirong", "内容"+i);
list.add(map);
}
dataMap.put("list", list);
}
//正式生产word文档
public static String freemarkerHtmlTest(Map<String, Object> paramMap,String filePath,String fileName) throws Exception{
//创建一个合适的Configration对象
fileName = "bokeceshi.ftl";
filePath ="E://template/judicial/";
String sourcePath ="E://template/judicial/outFileBoKe"+".doc";
Configuration configuration = new Configuration();
configuration.setDirectoryForTemplateLoading(new File(filePath));
configuration.setObjectWrapper(new DefaultObjectWrapper());
configuration.setDefaultEncoding("UTF-8"); //这个一定要设置,不然在生成的页面中 会乱码
//获取或创建一个模版。
Template template = configuration.getTemplate(fileName);
Writer out = null;
File outFile = new File(sourcePath); //导出文件
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
//Template template = configuration.getTemplate(fileName,"utf-8");
template.process(paramMap, out); //将填充数据填入模板文件并输出到目标文件
out.close();
return null;
}
@SuppressWarnings("unused")
private void wordToDoc(String filePath){
//Word.Application代表COM OLE编程标识,可查询MSDN得到
ActiveXComponent app = new ActiveXComponent("Word.Application");
//设置Word不可见
app.setProperty("Visible",false);
//调用Application对象的Documents属性,获得Documents对象
Dispatch docs = app.getProperty("Documents").toDispatch();
//Dispatch doc = Dispatch.call(docs,"Open",sourcePath,new Variant(false),new Variant(true)).getDispatch();
Dispatch doc = Dispatch.call(docs,"Open",filePath).getDispatch();
Dispatch.call(doc,"SaveAS",filePath,12);
//关闭打开的Word文件
Dispatch.call(doc,"Close",false);
//关闭Word应用程序
app.invoke("Quit",0);
}
}
A:测试方法如上,完全成功:xml模板和生成的文档示例如下:
到这里大家应该一目了然了吧!
4、这里稍微补充几点
A:希望大家尽量用xml模板,因为xml模板生产的word文档符合标准的office格式,通用;而html生成的word文档属于网页版,不标准。
B:这里xml生的word文档打开后点击F12发现是xml格式的,如下图
即他是非加密的word 文档,但是不影响使用。这里有个加密的方法大家可以用一下
filePath就是生成的word文档路径。但是此方法只能在window环境使用,配置也比较麻烦,大家可以试试。标准的加密方法下一篇文章给大家详细分享,谢谢!有问题及时留言!!