您好,欢迎访问代理记账网站
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

java使用freemarker模版导出带格式和带附件的word的使用

1.建立一个word模版 如图:

2.另存为一个xml文件

3.打开xml文件

普通的插入对应的单个属性值操作如下:

把对应的值改成 ${xxxx}

修改前Aaa就是我们自己输入的值

修改后:

插入列表操作如下:

如需要传入表格数据找到对应的<w:tr>标签,在标签开始处添加<#list table1 as plan1>

<#list listasda as list>
    <w:tr>
        <w:tblPrEx>
               <w:tblBorders>
                       <w:top w:val="single" w:color="auto" w:sz="4" w:space="0"/>
                            ........................

总结表格中取集合值就可以点出集合对象

在<w:tr>标签结尾处添加</#list>

                .................................
                </w:r>
              </w:p>
           </w:tc>
       </w:tr>
</#list>

需要了解详可以看看freemarker标签的用法和当年写jsp感觉差不多

插入图片如下:

把原来占位的base64编码的图片删除换成${images}把填充的图换算成base64填充即可

4.然后重名名xml文件为ftl

5.pom包:

  <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.20</version>
        </dependency>

6.源码:

package com.zz.demo.word.flt2;


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.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URL;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.omg.PortableServer.SERVANT_RETENTION_POLICY_ID;

public class DocumentHandler {

    private Configuration configuration = null;

    public DocumentHandler() {
        configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
    }

    public void createDoc(Map<String, Object> dataMap, String fileName) throws IOException {
        //dataMap 要填入模本的数据文件
        //设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载,
        //这里我们的模板是放在ftl2包下面
//        其实这个方法是根据类加载路径来判断的,最终会执行以下代码://resources目录下的资源
//        URL resource = this.getClass().getClassLoader().getResource("aa1.doc");
//        this.getClass().getResource("/demo2.txt")
//        System.err.println(resource);
//        configuration.setClassForTemplateLoading(this.getClass(), "");

        //直接设置文件路径
        configuration.setDirectoryForTemplateLoading(new File("D:\\java_project\\springboot-spark-scala\\src\\main\\java\\com\\zz\\demo\\word\\flt2"));
//        第三种基于web project。 第二个参数是基于WebRoot下的。
//        setServletContextForTemplateLoading(context, "/ftl") 就是 /WebRoot/ftl目录

        Template t = null;
        try {
            //test.ftl为要装载的模板
            t = configuration.getTemplate("a2.ftl");
        } catch (IOException e) {
            e.printStackTrace();
        }
        //输出文档路径及名称
        File outFile = new File(fileName);
        Writer out = null;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(outFile);
            OutputStreamWriter oWriter = new OutputStreamWriter(fos, "UTF-8");
            //这个地方对流的编码不可或缺,使用main()单独调用时,应该可以,但是如果是web请求导出时导出后word文档就会打不开,并且包XML文件错误。主要是编码格式不正确,无法解析。
            //out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
            out = new BufferedWriter(oWriter);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }

        try {
            t.process(dataMap, out);
            out.close();
            fos.close();
        } catch (TemplateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //System.out.println("---------------------------");
    }
}

7.调用:


import sun.misc.BASE64Encoder;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {
    //获得图片的base64码
//    @SuppressWarnings("deprecation")
    public static String getImageBase(String src) {
//        if(src==null||src==""){
//            return "";
//        }
//        File file = new File(getRequest().getRealPath("/")+src.replace(getRequest().getContextPath(), ""));
        File file = new File("E:\\aa\\ss.jpg");
        if(!file.exists()) {
            return "";
        }
        InputStream in = null;
        byte[] data = null;
        try {
            in = new FileInputStream(file);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
        try {
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }
    /**
     * @param args
     * @throws UnsupportedEncodingException
     */
    public static void main(String[] args) throws IOException {;

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("Aaa", "阿斯达大所多");
        map.put("bbbb", "111法师法师沙发");
        map.put("dddd", "222法师法师");
        map.put("打啊", "asdasdad");
        map.put("image", getImageBase("图片路径"));

        List<Map<String, Object>> list4 = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < 5; i++) {

            Map<String, Object> map2 = new HashMap<String, Object>();
            map2.put("qqq", i);
            map2.put("www", "说ss"+i);
            map2.put("eee", "说明作业调度,中级调度和进程调度的区别,并分析下述问题应由哪一级调度程序负责。"+i);
            list4.add(map2);
        }
        map.put("listasda", list4);

        DocumentHandler mdoc = new DocumentHandler();
        mdoc.createDoc(map, "E:/aa/dasd.doc");
    }

}

源码2:

package com.zz.demo.word.flt3;


import freemarker.template.Configuration;
import freemarker.template.Template;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;

/**
 * @author jagoLyu
 * @Description:
 * @data 2019/10/10 22:11
 */
public class ExportWortUtil {
    private static Template template=null;

    private static void addTemplate() throws IOException {
        //创建配置实例
        Configuration configuration = new Configuration();

        //设置编码
        configuration.setDefaultEncoding("UTF-8");

        //ftl模板文件统一放至 com.lun.template 包下面
        configuration.setClassForTemplateLoading(ExportWortUtil.class, "/temp");
        //获取模板
        template = configuration.getTemplate("inword.ftl","utf-8");
    }
    public static void createWord(Map dataMap, String tempPath, String fileName){
        try {
            if(template==null){
                addTemplate();
            }
            //输出文件
            File outFile = new File(tempPath+File.separator+fileName);

            //如果输出目标文件夹不存在,则创建
            if (!outFile.getParentFile().exists()){
                outFile.getParentFile().mkdirs();
            }

            //将模板和数据模型合并生成文件
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));


            //生成文件
            template.process(dataMap, out);

            //关闭流
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //预览
    public static void getHtmlWord(HttpServletResponse response,Map dataMap){
        try {
            if(template==null){
                addTemplate();
            }
            response.setContentType("text/html;charset=utf-8");
            template.process(dataMap,response.getWriter());
        }catch (Exception e){

        }
    }
    //下载
    public static void downloadWord(HttpServletResponse response,Map dataMap,String fileName){
        try {
            if(template==null){
                addTemplate();
            }
            response.setHeader("content-Type", "application/msword");
            // 下载文件的默认名称
            response.setHeader("Content-Disposition", "attachment;filename="+fileName);
            template.process(dataMap,new OutputStreamWriter(response.getOutputStream(),"UTF-8"));
        }catch (Exception e){

        }
    }
}

8.重新导出来的完整的word:

 

总结:

1.用Microsoft Office Word打开word原件(wps完美支持);

2.把需要动态修改的内容替换成***,如果有图片,尽量选择较小的图片几十K左右,并调整好位置;

3.另存为,选择保存类型Word 2003 XML 文档(*.xml)【这里说一下为什么用Microsoft Office Word打开且要保存为Word 2003XML,本人亲测,用WPS找不到Word 2003XML选项,如果保存为Word XML,会有兼容问题,避免出现导出的word文档不能用Word 2003打开的问题】;

4.用Firstobject free XML editor打开文件,选择Tools下的Indent【或者按快捷键F8】格式化文件内容。左边是文档结构,右边是文档内容;

5. 将文档内容中需要动态修改内容的地方,换成freemarker的标识。其实就是Map<String, Object>中key,如${landName};

6.在加入了图片占位的地方,会看到一片base64编码后的代码,把base64替换成${image},也就是Map<String, Object>中key,值必须要处理成base64;

  代码如:<w:binData w:name="wordml://自定义.png" xml:space="preserve">${image}</w:binData>

  注意:“>${image}<”这尖括号中间不能加任何其他的诸如空格,tab,换行等符号。

  如果需要循环,则使用:<#list maps as map></#list>  maps是Map<String, Object>中key,值为数组,map为自定义;

7. 标识替换完之后,模板就弄完了,另存为.ftl后缀文件即可。注意:一定不要用word打开ftl模板文件,否则xml内容会发生变化,导致前面的工作白做了。


分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进