使用Java生成word文档(附源码)

简介:

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


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

  具体过程如下:

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

140726908.png

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

140752129.png


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

140826202.png



  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.赶紧把这个方法,应用到自己的项目中吧。





本文转自 genuinecx 51CTO博客,原文链接:http://blog.51cto.com/favccxx/1331115,如需转载请自行联系原作者

目录
相关文章
|
17天前
|
存储 小程序 Java
热门小程序源码合集:微信抖音小程序源码支持PHP/Java/uni-app完整项目实践指南
小程序已成为企业获客与开发者创业的重要载体。本文详解PHP、Java、uni-app三大技术栈在电商、工具、服务类小程序中的源码应用,提供从开发到部署的全流程指南,并分享选型避坑与商业化落地策略,助力开发者高效构建稳定可扩展项目。
|
4月前
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
198 3
|
5月前
|
JavaScript Java 关系型数据库
家政系统源码,java版本
这是一款基于SpringBoot后端框架、MySQL数据库及Uniapp移动端开发的家政预约上门服务系统。
160 6
家政系统源码,java版本
|
5月前
|
供应链 JavaScript 前端开发
Java基于SaaS模式多租户ERP系统源码
ERP,全称 Enterprise Resource Planning 即企业资源计划。是一种集成化的管理软件系统,它通过信息技术手段,将企业的各个业务流程和资源管理进行整合,以提高企业的运营效率和管理水平,它是一种先进的企业管理理念和信息化管理系统。 适用于小微企业的 SaaS模式多租户ERP管理系统, 采用最新的技术栈开发, 让企业简单上云。专注于小微企业的应用需求,如企业基本的进销存、询价,报价, 采购、销售、MRP生产制造、品质管理、仓库库存管理、财务应收付款, OA办公单据、CRM等。
287 23
|
6月前
|
前端开发 Java 关系型数据库
基于Java+Springboot+Vue开发的鲜花商城管理系统源码+运行
基于Java+Springboot+Vue开发的鲜花商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的鲜花商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。技术学习共同进步
426 7
|
6月前
|
Java 关系型数据库 MySQL
Java汽车租赁系统源码(含数据库脚本)
Java汽车租赁系统源码(含数据库脚本)
105 4
|
6月前
|
消息中间件 算法 安全
JUC并发—1.Java集合包底层源码剖析
本文主要对JDK中的集合包源码进行了剖析。
|
6月前
|
Java
【源码】【Java并发】【ConcurrentHashMap】适合中学体质的ConcurrentHashMap
本文深入解析了ConcurrentHashMap的实现原理,涵盖JDK 7与JDK 8的区别、静态代码块、构造方法、put/get/remove核心方法等。JDK 8通过Node数组+链表/红黑树结构优化并发性能,采用CAS和synchronized实现高效锁机制。文章还详细讲解了hash计算、表初始化、扩容协助及计数更新等关键环节,帮助读者全面掌握ConcurrentHashMap的工作机制。
135 6
【源码】【Java并发】【ConcurrentHashMap】适合中学体质的ConcurrentHashMap
|
6月前
|
人工智能 安全 Java
智慧工地源码,Java语言开发,微服务架构,支持分布式和集群部署,多端覆盖
智慧工地是“互联网+建筑工地”的创新模式,基于物联网、移动互联网、BIM、大数据、人工智能等技术,实现对施工现场人员、设备、材料、安全等环节的智能化管理。其解决方案涵盖数据大屏、移动APP和PC管理端,采用高性能Java微服务架构,支持分布式与集群部署,结合Redis、消息队列等技术确保系统稳定高效。通过大数据驱动决策、物联网实时监测预警及AI智能视频监控,消除数据孤岛,提升项目可控性与安全性。智慧工地提供专家级远程管理服务,助力施工质量和安全管理升级,同时依托可扩展平台、多端应用和丰富设备接口,满足多样化需求,推动建筑行业数字化转型。
208 5
|
6月前
|
Java
【源码】【Java并发】【LinkedBlockingQueue】适合中学体质的LinkedBlockingQueue入门
前言 有了前文对简单实用的学习 【Java并发】【LinkedBlockingQueue】适合初学体质的LinkedBlockingQueue入门 聪明的你,一定会想知道更多。哈哈哈哈哈,下面主播就...
107 6
【源码】【Java并发】【LinkedBlockingQueue】适合中学体质的LinkedBlockingQueue入门