前几天项目中遇到word 文档不标准问题,我详细查找原因,总结 了几种方案,现在和大家分享一下。

一、想生成word文档,首先要有生产word的模板,这里给大家介绍三种方式,每种方式有相应的生产word文档的代码:

1、html 模板 生成方式,打开word文档样例,如下图所示!

java在线生成word文档 java 生成word文件_Word

 然后单击F12 ,后显示如下

java在线生成word文档 java 生成word文件_xml_02

选择网页文件,保存后生成html格式的 文档 ,打开后如下图

java在线生成word文档 java 生成word文件_xml_03

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模板的生产方式,如图:

java在线生成word文档 java 生成word文件_Word_04

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模板和生成的文档示例如下:

java在线生成word文档 java 生成word文件_java_05

 

java在线生成word文档 java 生成word文件_java在线生成word文档_06

 

java在线生成word文档 java 生成word文件_java_07

到这里大家应该一目了然了吧!

4、这里稍微补充几点

A:希望大家尽量用xml模板,因为xml模板生产的word文档符合标准的office格式,通用;而html生成的word文档属于网页版,不标准。

B:这里xml生的word文档打开后点击F12发现是xml格式的,如下图

java在线生成word文档 java 生成word文件_java在线生成word文档_08

 即他是非加密的word 文档,但是不影响使用。这里有个加密的方法大家可以用一下

java在线生成word文档 java 生成word文件_Word_09

filePath就是生成的word文档路径。但是此方法只能在window环境使用,配置也比较麻烦,大家可以试试。标准的加密方法下一篇文章给大家详细分享,谢谢!有问题及时留言!!