Step1. 制作模板
首先准备一份要导出的word.doc文档;
例如,这就是你要生成的效果:
如上图,行不确定,列是确定的,先不考虑合并单元格的问题,假设每个部分都只是一列的时候,制作相应模板,把需要导出的数据相应的插入 ${}到里面, ${}就是个占位符,来放数据的,如下:
接下来使用wps将文档另存为xml格式,然后将xml文件的后缀名改成ftl
这样一来模板就制作完成了
Step2. 修改ftl文档
使用ue或者其他格式化工具打开ftl文档,这样方便查看,不然一大堆代码看起来很费劲,<w:tr>代表行,查找它找到${a1}的那一行,在<w:tr>前面添加<#list list1 as item>这一句代码,然而还必须在对应的</w:tr>后面添加</#list>,就如HTML代码那样需要对应上。list1是需要循环的数据,item是自定义的别名,当然它可以定义成任意的名字,只要内容对应上即可。对应将 ${a1}改成 ${item.a1}为了对应上list当中的数据,以此类推对应修改。合并单元格只需要在循环第一次的时候在需要合并的那一列加上<w:vmerge w:val=“restart”/>这句话,所以加上<#if item_index==0>这句话判断是否为第一次循环,并且在<w:tcW >标签后面添加<w:vmerge w:val=“restart”/>合并单元格,当其他循环时<#elseif item_index!=0 >,在<w:tcW >标签后面加上<w:vmerge w:val=“continue”/>,就完成了aa行的操作,模板上后面那两行也是这么修改,以此类推就可以了,ftl参考如下:
<#list list1 as item>
<#if item_index==0>
<w:tr><w:tblPrEx><w:tblBorders><w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:insideH w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:insideV w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/></w:tblBorders><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPrEx><w:trPr><w:trHeight w:val="367" w:h-rule="atLeast"/><w:jc w:val="center"/></w:trPr><w:tc><w:tcPr>
<w:tcW w:w="1487" w:type="dxa"/><w:vmerge w:val="restart"/>
<w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.a1}</w:t></w:r></w:p></w:tc>
<w:tc><w:tcPr><w:tcW w:w="1842" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="default"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.aa}</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="4132" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="default"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.ab}</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="1263" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="top"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="default"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.ac}</w:t></w:r></w:p></w:tc></w:tr>
<#elseif item_index!=0 >
<w:tr><w:tblPrEx><w:tblBorders><w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:insideH w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:insideV w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/></w:tblBorders><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPrEx><w:trPr><w:trHeight w:val="367" w:h-rule="atLeast"/><w:jc w:val="center"/></w:trPr><w:tc><w:tcPr>
<w:tcW w:w="1487" w:type="dxa"/><w:vmerge w:val="continue"/>
<w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.a1}</w:t></w:r></w:p></w:tc>
<w:tc><w:tcPr><w:tcW w:w="1842" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="default"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.aa}</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="4132" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="default"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.ab}</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="1263" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="top"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="default"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.ac}</w:t></w:r></w:p></w:tc></w:tr>
</#if>
</#list>
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<String,Object> dataMap=new HashMap<String,Object>();
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<String, Object> dataMap) {
List<Map<String,Object>> list1 = new ArrayList<Map<String,Object>>();
List<Map<String,Object>> list2 = new ArrayList<Map<String,Object>>();
List<Map<String,Object>> list3 = new ArrayList<Map<String,Object>>();
List<TestDto08> dtos = new ArrayList<TestDto08>() ;
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<TestDto08> dtos1 = new ArrayList<TestDto08>() ;
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<TestDto08> dtos2 = new ArrayList<TestDto08>() ;
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<String,Object> map = new HashMap<String,Object>();
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<String,Object> map = new HashMap<String,Object>();
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<String,Object> map = new HashMap<String,Object>();
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>
<w:tr><w:tblPrEx><w:tblBorders><w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:insideH w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:insideV w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/></w:tblBorders><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPrEx><w:trPr><w:trHeight w:val="367" w:h-rule="atLeast"/><w:jc w:val="center"/></w:trPr>
<w:tc><w:tcPr><w:tcW w:w="1487" w:type="dxa"/><w:vmerge w:val="restart"/>
<w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.a}</w:t></w:r></w:p></w:tc>
<w:tc><w:tcPr><w:tcW w:w="1842" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.aa}</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="4132" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.ab}</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="1263" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="top"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.ac}</w:t></w:r></w:p></w:tc></w:tr>
<#elseif item_index!=0 >
<w:tr><w:tblPrEx><w:tblBorders><w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:insideH w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/><w:insideV w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/></w:tblBorders><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPrEx><w:trPr><w:trHeight w:val="367" w:h-rule="atLeast"/><w:jc w:val="center"/></w:trPr>
<w:tc><w:tcPr><w:tcW w:w="1487" w:type="dxa"/><w:vmerge w:val="continue"/>
<w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.a}</w:t></w:r></w:p></w:tc>
<w:tc><w:tcPr><w:tcW w:w="1842" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.aa}</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="4132" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.ab}</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="1263" w:type="dxa"/><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="top"/></w:tcPr><w:p><w:pPr><w:jc w:val="center"/><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:fareast="黑体" w:hint="fareast"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr><w:t>${item.ac}</w:t></w:r></w:p></w:tc></w:tr>
</#if>
</#list>
</#list>