当我们使用Java生成word文档时,通常首先会想到iText和POI,这是因为我们习惯了使用这两种方法操作Excel,自然而然的也想使用这种生成word文档。但是当我们需要动态生成word时,通常不仅要能够显示word中的内容,还要能够很好的保持word中的复杂样式。这时如果再使用IText和POI去操作,就好比程序员去搬砖一样痛苦。

  这时候,我们应该考虑使用FreeMarker的模板技术快速实现这个复杂的功能,让程序员在喝咖啡的过程中就把问题解决。实现思路是这样的:先创建一个word文档,按照需求在word中填好一个模板,然后把对应的数据换成变量${},然后将文档保存为xml文档格式,使用文档编辑器打开这个xml格式的文档,去掉多余的xml符号,使用Freemarker读取这个文档然后替换掉变量,输出word文档即可。

  具体过程如下:

  1.创建带有格式的word文档,将该需要动态展示的数据使用变量符替换。

2. 将刚刚创建的word文档另存为xml格式。

3.编辑这个XMl文档去掉多余的xml标记,如图中蓝色部分

  4.从Freemarker官网【下载】最新的开发包,将freemarker.jar拷贝到自己的开发项目中。

  5.新建DocUtil类,实现根据Doc模板生成word文件的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.favccxx.secret.util;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
public class DocUtil {
       privateConfiguration configure = null;
       publicDocUtil(){
              configure= new Configuration();
              configure.setDefaultEncoding("utf-8");
       }
       /**
        * 根据Doc模板生成word文件
        * @param dataMap Map 需要填入模板的数据
        * @param fileName 文件名称
        * @param savePath 保存路径
        */
       publicvoid createDoc(Map<String, Object> dataMap, String downloadType, StringsavePath){
              try{
                     //加载需要装填的模板
                     Templatetemplate  = null;
                     //加载模板文件
                     configure.setClassForTemplateLoading(this.getClass(),"/com/favccxx/secret/templates");
                     //设置对象包装器
                     configure.setObjectWrapper(newDefaultObjectWrapper());
                     //设置异常处理器
                     configure.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
                     //定义Template对象,注意模板类型名字与downloadType要一致
                     template= configure.getTemplate(downloadType + ".xml");
                     //输出文档
                     FileoutFile = new File(savePath);
                     Writerout = null;
                     out= new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"utf-8"));                                   
                     template.process(dataMap,out);
                     outFile.delete();
              }catch (Exception e) {
                     e.printStackTrace();
              }
       }
}

  6.用户根据自己的需要,调用使用getDataMap获取需要传递的变量,然后调用createDoc方法生成所需要的文档。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
 * 根据下载类型获取需要传递的Map参数
 * @param oid 对象Id
 * @param downloadType 下载类型
 */
private Map<String, Object> getDataMap(String oid,String downloadType){
    Map<String, Object> dataMap = new HashMap<String, Object>();
    if("Parameter1".equals(downloadType)){
        ...
        ...
        dataMap = DataMapUtil.setObjToMap(Object1);
    }else{
        ...
        ...
        dataMap = DataMapUtil.setObjToMap(Object2);
    }
    return dataMap;
}

  

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class DataMapUtil {
       
    private static Map<String, Object> dataMap = new HashMap<String, Object>();
       
    /**
     * 将对象转换成Map
     * @param obj 对象类
     * @return
     */
    public static Map<String,Object> setObjToMap(Object obj){
        Class c;
        try {
            c = Class.forName(obj.getClass().getName());
            Method[] methods = c.getMethods();
            for(int i=0,l=methods.length;i<l;i++){
                String method = methods[i].getName();
                System.out.println("The method is:" + method);
                if(method.startsWith("get")){
                    Object value = methods[i].invoke(obj);
                    if(value != null){
                        if(value.getClass().getClassLoader() != null){  //处理自定义的对象类型
                            setObjToMap(value);
                        }
                        String key = method.substring(3);
                        key = key.substring(0, 1).toLowerCase() + key.substring(1);
                        if("java.util.Date".equals(value.getClass().getName())){
                            value = DateUtil.dateToString((Date)value);
                        }
                        dataMap.put(key, value);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dataMap;
    }
}

  7.赶紧把这个方法,应用到自己的项目中吧。

本文出自 “这个人的IT世界” 博客,请务必保留此出处http://favccxx.blog.51cto.com/2890523/1331115

使用Java生成word文档(附源码)的更多相关文章

  1. [转载]Java生成Word文档

    在开发文档系统或办公系统的过程中,有时候我们需要导出word文档.在网上发现了一个用PageOffice生成word文件的功能,就将这块拿出来和大家分享. 生成word文件与我们编辑word文档本质上 ...

  2. [原创]Java生成Word文档

    在开发文档系统或办公系统的过程中,有时候我们需要导出word文档.在网上发现了一个用PageOffice生成word文件的功能,就将这块拿出来和大家分享. 生成word文件与我们编辑word文档本质上 ...

  3. Java生成 Word文档的并打印解决方案

    户要求用程序生成标准的word文档,要能打印,而且不能变形,以前用过很多解决方案,都在客户严格要求下牺牲的无比惨烈. POI读word文档还行,写文档实在不敢恭维,复杂的样式很难控制不提,想象一下一个 ...

  4. poi读写word模板 / java生成word文档

    有一word文档表格 形如: 姓名 ${name} 电话 ${tel} 从数据库读取记录替换上述变量 import java.io.FileOutputStream; import java.util ...

  5. Java生成word文档

    itext-rtf-2.1.7.jar,下载地址:http://download.csdn.net/detail/xuxu198899223/7717727 itext-2.1.7.jar 下载地址: ...

  6. JAVA生成Word文档(经过测试)

    首先告诉大家这篇文章的原始出处:http://www.havenliu.com/java/514.html/comment-page-1#comment-756 我也是根据他所描述完成的,但是有一些地 ...

  7. java使用freemarker 生成word文档

      java 生成word文档     最近需要做一个导出word的功能, 在网上搜了下, 有用POI,JXL,iText等jar生成一个word文件然后将数据写到该文件中,API非常繁琐而且拼出来的 ...

  8. Java 导出数据库表信息生成Word文档

    一.前言 最近看见朋友写了一个导出数据库生成word文档的业务,感觉很有意思,研究了一下,这里也拿出来与大家分享一波~ 先来看看生成的word文档效果吧 下面我们也来一起简单的实现吧 二.Java 导 ...

  9. PoiDocxDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0),目前只能java生成】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这个是<PoiDemo[Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)]>的扩展,上一篇是根 ...

随机推荐

  1. Datatable 导出到execl 官网demo

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content ...

  2. list tuple dict (列表,元祖,字典间的相互转换)

    #-*- coding:UTF-8 -*- #author:RXS002 #1.字典 dict = {'name':'Zara','age':7,'class':'First'} #字典转换为字符串, ...

  3. Fast Matrix Calculation 矩阵快速幂

    One day, Alice and Bob felt bored again, Bob knows Alice is a girl who loves math and is just learni ...

  4. Java Number类(数据类型的包装类)

    Java Number 一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte.int.long.double等. 例如: int i = 5000; float gpa = 13.65 ...

  5. 第3章 ES文档和故障处理

    第3章 ES文档和故障处理 一.ES网络配置表 ES网络配置表是ES的硬件和软件组成的列表.ES网络配置常包括以下项目: 分级 项目 杂项信息 系统名.系统厂商/型号.CPU速率.RAM.存储器.系统 ...

  6. Cocos2d-x教程(34)-三维物体OBB碰撞检測算法

    欢迎增加Cocos2d-x 交流群:193411763 个中心点.1个旋转矩阵和3个1/2边长(注:一个旋转矩阵包括了三个旋转轴,若是二维的OBB包围盒则是一个中心点,两个旋转轴,两个1/2边长). ...

  7. 阿牛的EOF牛肉串-记忆化搜索或动态规划

    C - 阿牛的EOF牛肉串 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submi ...

  8. 用Arduino对Apple手表进行远程红外控制

    描写叙述 用于控制随意红外设备的Apple手表及iPhone应用. IOS应用发送HTTP请求至一个或多个带有以太网插板的Arduino.Arduino正在解析http请求并发送红外信号.Arduin ...

  9. mysql中间件amoeba实现mysql读写分离

    Amoeba是一个以MySQL为底层数据存储,并相应用提供MySQL协议接口的proxy.它集中地响应应用的请求,根据用户事先设置的规则.将SQL请求发送到特定的数据库上运行.基于此能够实现负载均衡. ...

  10. 【Spring四】AOP之XML配置

    AOP:Aspect Oriented  Programming 面向切面编程 面向切面编程的核心是动态代理设计模式.请先參见动态代理设计模式笔记. 以Hibernate保存一个对象到数据库为例,因为 ...