word模板动态填充并下载

需求:java生成word
通常首先会想到iText和POI,这是因为我们习惯了使用这两种方法操作Excel,自然而然的也想使用这种生成word文档。但是当我们需要动态生成word时,通常不仅要能够显示word中的内容,还要能够很好的保持word中的复杂样式。这时如果再使用IText和POI去操作,就好比程序员去搬砖一样痛苦。
实现思路_
  这时候,我们应该考虑使用FreeMarker的模板技术快速实现这个复杂的功能,让程序员在喝咖啡的过程中就把问题解决。实现思路是这样的:先创建一个word文档,按照需求在word中填好一个模板,然后把对应的数据换成变量${},然后将文档保存为xml文档格式,使用文档编辑器打开这个xml格式的文档,去掉多余的xml符号,使用Freemarker读取这个文档然后替换掉变量,输出word文档即可。
1.1 需要的jar包
在这里插入图片描述
1.2 xml模板转为doc文件的工具类

	备注:此工具类使用了单利模式
	这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
	意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

    主要解决:一个全局使用的类频繁地创建与销毁。
    
    何时使用:当您想控制实例数目,节省系统资源的时候。
    
    如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
        
    优点: 
    1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
    2、避免对资源的多重占用(比如写文件操作)。
    缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
  
         * 根据word模板打印文件工具类__
         * 双检锁/双重校验锁__这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
         */

  public class DocUtil {
    private volatile static DocUtil docUtil;
    private Configuration configure = null;
    
    private DocUtil() {
        configure = new Configuration();
        configure.setDefaultEncoding("utf-8");
    }
    
    public static DocUtil getSingleton() {
        if (docUtil == null) {
            synchronized (DocUtil.class) {
                if (docUtil == null) {
                    docUtil = new DocUtil();
                }
            }
        }
        return docUtil;
    }
    /**
     * 根据Doc模板生成word文件
     *
     * @param dataMap      需要替换的数据 key__value
     * @param downloadType 模板名称
     * @param savePath     保存路径
     */
    public void createDoc(Map<String, Object> dataMap, String downloadType, String savePath) {
        try {
            //加载需要装填的模板
            Template template = null;
            //加载模板文件
            configure.setClassForTemplateLoading(this.getClass(), "/com/sgcc/fsp/manage/web/templates");
            //设置对象包装器
            configure.setObjectWrapper(new DefaultObjectWrapper());
            //设置异常处理器
            configure.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
            //定义Template对象,注意模板类型名字与downloadType要一致
            template = configure.getTemplate(downloadType + ".xml");
            //输出文档
            File outFile = new File(savePath);
            Writer out = null;
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));
            template.process(dataMap, out);
            outFile.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 获取付款打印的doc文档__
     */
    public static void getPaymentDoc(Map<String, Object> dataMap, String savePath) {
        DocUtil docUtil = DocUtil.getSingleton();
        //找到对应模板、替换变量值__
        docUtil.createDoc(dataMap, "paymentApproval", savePath);
    }
    
    public static void main(String[] args) {
        DocUtil docUtil = DocUtil.getSingleton();
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("year", "2018");
        dataMap.put("month", "11");
        dataMap.put("day", "22");
        dataMap.put("businessName", "远东国际");
        dataMap.put("businessGroupLeader", "薛胜东");
        dataMap.put("applicant", "赵远东");
        docUtil.createDoc(dataMap, "paymentApproval", "H:/outFile.doc");
    }
    }

单例模式文档___
http://www.runoob.com/design-pattern/singleton-pattern.html

猜你喜欢

转载自blog.csdn.net/e_shi_yi_p/article/details/84400735