freemarker导出word文档(循环+合并单元格)

Step1. 制作模板

首先准备一份要导出的word.doc文档;
例如,这就是你要生成的效果:
在这里插入图片描述
如上图,行不确定,列是确定的,先不考虑合并单元格的问题,假设每个部分都只是一列的时候,制作相应模板,把需要导出的数据相应的插入 ${}到里面, ${}就是个占位符,来放数据的,如下:
在这里插入图片描述
接下来使用wps将文档另存为xml格式,然后将xml文件的后缀名改成ftl
这样一来模板就制作完成了

Step2. 修改ftl文档

使用ue或者其他格式化工具打开ftl文档,这样方便查看,不然一大堆代码看起来很费劲,代表行,查找它找到${a1}的那一行,在前面添加<#list list1 as item>这一句代码,然而还必须在对应的后面添加,就如HTML代码那样需要对应上。list1是需要循环的数据,item是自定义的别名,当然它可以定义成任意的名字,只要内容对应上即可。对应将 ${a1}改成 ${item.a1}为了对应上list当中的数据,以此类推对应修改。合并单元格只需要在循环第一次的时候在需要合并的那一列加上这句话,所以加上<#if item_index==0>这句话判断是否为第一次循环,并且在标签后面添加合并单元格,当其他循环时<#elseif item_index!=0 >,在标签后面加上,就完成了aa行的操作,模板上后面那两行也是这么修改,以此类推就可以了,ftl参考如下:


<#list list1 as item><#if item_index==0>${item.a1}${item.aa}${item.ab}${item.ac}<#elseif item_index!=0 >${item.a1}${item.aa}${item.ab}${item.ac}

Step3. 生成word文档代码

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;public class Word08 {private Configuration configuration = null;   public Word08(){   configuration = new Configuration();   configuration.setDefaultEncoding("UTF-8");   }   public static void main(String[] args) {  Word08 test = new Word08();  test.createWord();    }   public void createWord(){   Map dataMap=new HashMap();   getData(dataMap);configuration.setClassForTemplateLoading(this.getClass(), "");Template t=null;   try {   t = configuration.getTemplate("080.ftl","UTF-8");File outFile = new File("D:/outFile"+new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(new Date())+".doc"); //?????????? Writer out = null;   out = new BufferedWriter(new OutputStreamWriter((new FileOutputStream(outFile)), "UTF-8"));  t.process(dataMap, out);System.out.println("生成成功");} catch (Exception e) {  e.printStackTrace();  }  }   private void getData(Map dataMap) {List> list1 = new ArrayList>();List> list2 = new ArrayList>();List> list3 = new ArrayList>();List dtos = new ArrayList() ;TestDto08 dto1 = new TestDto08();dto1.setA1("钣金");dto1.setAa("aa");dto1.setAb("aa");dto1.setAc("aa");dtos.add(dto1);TestDto08 dto3 = new TestDto08();dto3.setA1("钣金");dto3.setAa("bb");dto3.setAb("bb");dto3.setAc("bb");dtos.add(dto3);List dtos1 = new ArrayList() ;TestDto08 dto2 = new TestDto08();dto2.setB1("喷漆");dto2.setAa("cc");dto2.setAb("cc");dto2.setAc("cc");dtos1.add(dto2);TestDto08 dto4 = new TestDto08();dto4.setB1("喷漆");dto4.setAa("dd");dto4.setAb("dd");dto4.setAc("dd");dtos1.add(dto4);List dtos2 = new ArrayList() ;TestDto08 dto5 = new TestDto08();dto5.setC1("机修");dto5.setAa("ee");dto5.setAb("ee");dto5.setAc("ee");dtos2.add(dto5);TestDto08 dto6 = new TestDto08();dto6.setC1("机修");dto6.setAa("ff");dto6.setAb("ff");dto6.setAc("ff");dtos2.add(dto6);for (int i = 0; i < dtos.size(); i++) { Map map = new HashMap();map.put("a1", dtos.get(i).getA1());map.put("aa", dtos.get(i).getAa());map.put("ab", dtos.get(i).getAb());map.put("ac", dtos.get(i).getAc());list1.add(map);}for (int i = 0; i < dtos1.size(); i++) {Map map = new HashMap();map.put("b1", dtos1.get(i).getB1());map.put("aa", dtos1.get(i).getAa());map.put("ab", dtos1.get(i).getAb());map.put("ac", dtos1.get(i).getAc());list2.add(map);}for (int i = 0; i < dtos2.size(); i++) {Map map = new HashMap();map.put("c1", dtos2.get(i).getC1());map.put("aa", dtos2.get(i).getAa());map.put("ab", dtos2.get(i).getAb());map.put("ac", dtos2.get(i).getAc());list3.add(map);}dataMap.put("list1", list1);dataMap.put("list2", list2);dataMap.put("list3", list3);}}

TestDto08是一个实体类为了获取数据临时加上的

public class TestDto08 {private String state;private String a;private String aa;private String ab;private String ac;private String bb;private String bc;private String bd;private String a1;private String b1;private String c1;public String getB1() {return b1;}public void setB1(String b1) {this.b1 = b1;}public String getA1() {return a1;}public void setA1(String a1) {this.a1 = a1;}public String getC1() {return c1;}public void setC1(String c1) {this.c1 = c1;}public String getA() {return a;}public void setA(String a) {this.a = a;}public String getAa() {return aa;}public void setAa(String aa) {this.aa = aa;}public String getAb() {return ab;}public void setAb(String ab) {this.ab = ab;}public String getAc() {return ac;}public void setAc(String ac) {this.ac = ac;}public String getState() {return state;}public void setState(String state) {this.state = state;}public String getBb() {return bb;}public void setBb(String bb) {this.bb = bb;}public String getBc() {return bc;}public void setBc(String bc) {this.bc = bc;}public String getBd() {return bd;}public void setBd(String bd) {this.bd = bd;}}

代码比较简单可以自己理解一下。

如果你不想使用那么多的list,这些也可以在一个list中完成,使用<#list map?keys as key>遍历list中的map,这时list中就会有三个map,这样做模板就不需要三行,只需要做一行。ftl代码如下:

<#list map?keys as key> 
<#list map[key] as item>
<#if item_index==0>


${item.a} 
${item.aa}${item.ab}${item.ac}<#elseif item_index!=0 > 


${item.a} 
${item.aa}${item.ab}${item.ac}    


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部