zoukankan      html  css  js  c++  java
  • java生成复杂word文档

    在Web应用中,有时需要按照固定的模板将数据导出到Word,如流程审批单,在流程处理完成后将处理过程按照流程单的要求导出,有时程序中需要实现生成 标准Word文档,要求能够打印,并且保持页面样式不变,常见的方案有POI、iText、JACOB、JSP几种方式,POI读取Word文档比较适 合、对于生成文档样式比较难控制,iText操作Excel还可以,对Word的操作功能有限,JACOB操作Word实现复杂,并且无法将服务部署到 Linux平台,要求安装office,对于实现固定格式的报表实现困难,对于JSP直接输出方式样式控制难。

    Word从2003开始支持XML格式,用XML+Freemarder还做就很简单了,大致的思路是先用office2003或者2007编辑好 word的样式,然后另存为xml,将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板并输出Doc。经测试这样方 式生成的word文档完全符合office标准,样式、内容控制非常便利,打印也不会变形,生成的文档和office中编辑文档完全一样。具体实现过程如 下:

    1、  首先用office【版本要2003以上,以下的不支持xml格式】编辑文档的样式,将需要动态填充的内容使用Freemarker标签替换:Word文档样式如下:

     

    2、  将Word文档另存为XML格式,将后缀名“xml”修改为“ftl”

    3、  使用Freemarker填充内容,代码如下:

     
    1. package com.test.freemarker.report;  
    2.   
    3.    
    4.   
    5. import java.io.BufferedWriter;  
    6.   
    7. import java.io.File;  
    8.   
    9. import java.io.FileOutputStream;  
    10.   
    11. import java.io.IOException;  
    12.   
    13. import java.io.OutputStreamWriter;  
    14.   
    15. import java.io.Writer;  
    16.   
    17. import java.util.HashMap;  
    18.   
    19. import java.util.Map;  
    20.   
    21.    
    22.   
    23. import freemarker.template.Configuration;  
    24.   
    25. import freemarker.template.Template;  
    26.   
    27. import freemarker.template.TemplateException;  
    28.   
    29.    
    30.   
    31. public class DocumentHandler {  
    32.   
    33.    private Configuration configuration = null;  
    34.   
    35.    
    36.   
    37.    public DocumentHandler() {  
    38.   
    39.       configuration = new Configuration();  
    40.   
    41.       configuration.setDefaultEncoding("utf-8");  
    42.   
    43.    }  
    44.   
    45.    
    46.   
    47.    public void createDoc() {  
    48.   
    49.       // 要填入模本的数据文件   
    50.   
    51.       Map dataMap = new HashMap();  
    52.   
    53.       getData(dataMap);  
    54.   
    55.       // 设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载,   
    56.   
    57.       // 这里我们的模板是放在com.havenliu.document.template包下面   
    58.   
    59.       configuration.setClassForTemplateLoading(this.getClass(),  
    60.   
    61.             "/com/test/freemarker/report");  
    62.   
    63.       Template t = null;  
    64.   
    65.       try {  
    66.   
    67.          // test.ftl为要装载的模板   
    68.   
    69.          t = configuration.getTemplate("test.ftl");  
    70.   
    71.          t.setEncoding("utf-8");  
    72.   
    73.       } catch (IOException e) {  
    74.   
    75.          e.printStackTrace();  
    76.   
    77.       }  
    78.   
    79.       // 输出文档路径及名称   
    80.   
    81.       File outFile = new File("D:/test.doc");  
    82.   
    83.       Writer out = null;  
    84.   
    85.       try {  
    86.   
    87.          out = new BufferedWriter(new OutputStreamWriter(  
    88.   
    89.                 new FileOutputStream(outFile), "utf-8"));  
    90.   
    91.    
    92.   
    93.       } catch (Exception e1) {  
    94.   
    95.          e1.printStackTrace();  
    96.   
    97.       }  
    98.   
    99.       try {  
    100.   
    101.          t.process(dataMap, out);  
    102.   
    103.          out.close();  
    104.   
    105.       } catch (TemplateException e) {  
    106.   
    107.          e.printStackTrace();  
    108.   
    109.       } catch (IOException e) {  
    110.   
    111.          e.printStackTrace();  
    112.   
    113.       }  
    114.   
    115.    }  
    116.   
    117.    
    118.   
    119.    /** 
    120.  
    121.     * 注意dataMap里存放的数据Key值要与模板中的参数相对应 
    122.  
    123.     *  
    124.  
    125.     * @param dataMap 
    126.  
    127.     */  
    128.   
    129.    private void getData(Map dataMap) {  
    130.   
    131.       dataMap.put("title_name""用户信息");  
    132.   
    133.       dataMap.put("user_name""张三");  
    134.   
    135.       dataMap.put("org_name""微软公司");  
    136.   
    137.       dataMap.put("dept_name""事业部");  
    138.   
    139.    }  
    140.   
    141. }  


    4、  生成的Word结果如下:

    对于复杂的报表样式可以在Word中编辑后保存,如果需要输出列表类型数据可以参考Freemarker的循环或逻辑控制。

     

    引用自:http://blog.csdn.net/java7star/article/details/9668883

  • 相关阅读:
    第04组 Beta冲刺(2/4)
    第04组 Beta冲刺(1/4)
    2019 SDN上机第6次作业
    SDN课程阅读作业(2)
    2019 SDN上机第5次作业
    第04组 Alpha事后诸葛亮
    第04组 Alpha冲刺(4/4)
    2019 SDN上机第4次作业
    第04组 Alpha冲刺(3/4)
    第07组 Alpha冲刺(4/6)
  • 原文地址:https://www.cnblogs.com/shisw/p/3513258.html
Copyright © 2011-2022 走看看