java通过freemarker导出word循环合并表格单元格
本文主要讲解通过freemarker模板引擎来导出word,并且在word中包含表格的合并部分需要循环生成。
一、Java需要通过模板导出的word
如上图所示。物品的信息是循环部分。但是前面的表格是合并固定的。接下来我们将通过freemarker模板的方式来导出上述格式
二、创建freemarker模板
2.1首先将word的源文件另存为xml格式文件,如下
用文本工具打开xml文件。notepad++ 或者sublimetext都可以
打开后如上图,看起来很乱。这时候需要进行xml格式化。欢迎使用本站xml格式化工具
格式化以后如下:
格式化以后就好看多了。
首先我们需要去找到我们需要循环的表格
物品信息就是我们要循环的开始部分。
在这之前需要科普下word的xml是如何实现单元格合并的
主要就是
<w:vMerge w:val="restart"/>
<w:vMerge/>
两个标签的组合。
首先了解下word的表格标签
<w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge w:val="restart"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRPr="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:pPr>
<w:jc w:val="center"/>
<w:rPr>
<w:b/>
</w:rPr>
</w:pPr>
<w:r w:rsidRPr="00770B3E">
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:b/>
</w:rPr>
<w:t>物品信息</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>物品名称</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>刀</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>物品数量</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1660" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>2</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
上面是合并单元格的首行,所以你可以找到<w:vMerge w:val="restart"/>标签
标签说明:
<w:tr></w:tr> —行标签
<w:tc></w:tc> —单元格标签
我们继续看下面的一行xml
第二行表格xml:
<w:tr w:rsidR="00770B3E" w:rsidTr="00CC5D94">
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>物品说明</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="4978" w:type="dxa"/>
<w:gridSpan w:val="3"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:proofErr w:type="gramStart"/>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>刀非常</w:t>
</w:r>
<w:proofErr w:type="gramEnd"/>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>锋利</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
继续第三行:
<w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>上架时间</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>2</w:t>
</w:r>
<w:r>
<w:t>019</w:t>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>-</w:t>
</w:r>
<w:r>
<w:t>08</w:t>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>-</w:t>
</w:r>
<w:r>
<w:t>09</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>上架人</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1660" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>小左</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
从第二行,第三行可以找到<w:vMerge/>标签,标识这这列产生了合并
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>
</w:tc>
并且<w:vMerge/>就在第一个单元格内。
那么模板就好改了。思路:
首先循环判断是否第一条数据
第一条数据那么就使用行1的格式。后面的都使用合并后的格式
提取需要做模板的几行进行组建,通过上面我们可以知道,其实我们就是要循环以下三行表格:
<w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge w:val="restart"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRPr="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:pPr>
<w:jc w:val="center"/>
<w:rPr>
<w:b/>
</w:rPr>
</w:pPr>
<w:r w:rsidRPr="00770B3E">
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:b/>
</w:rPr>
<w:t>物品信息</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>物品名称</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>刀</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>物品数量</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1660" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>2</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
<w:tr w:rsidR="00770B3E" w:rsidTr="00CC5D94">
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>物品说明</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="4978" w:type="dxa"/>
<w:gridSpan w:val="3"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:proofErr w:type="gramStart"/>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>刀非常</w:t>
</w:r>
<w:proofErr w:type="gramEnd"/>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>锋利</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
<w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>上架时间</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>2</w:t>
</w:r>
<w:r>
<w:t>019</w:t>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>-</w:t>
</w:r>
<w:r>
<w:t>08</w:t>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>-</w:t>
</w:r>
<w:r>
<w:t>09</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>上架人</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1660" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>小左</w:t>
</w:r>
</w:p>
</w:tc>
接下来就针对这部分进行模板标签的编写
说明:Java代码后面给出,现在说明的是集合的key为 goodsList(物品集合)
循环片段代码格式缩进后如图
图6
上图其实就是判断了是否第一条记录,第一条记录和后面记录的区别就是第一行的第一个单元格,第一条记录的第一个单元格是写的”物品信息“后面的记录第一个单元格都是合并单元格的cell代码。
以下为循环片段代码:
<#list goodsList! as goods>
<#if goods_index == 0 >
<w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge w:val="restart"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRPr="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:pPr>
<w:jc w:val="center"/>
<w:rPr>
<w:b/>
</w:rPr>
</w:pPr>
<w:r w:rsidRPr="00770B3E">
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:b/>
</w:rPr>
<w:t>物品信息</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>物品名称</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>${goods.name}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>物品数量</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1660" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>${goods.number}</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
<w:tr w:rsidR="00770B3E" w:rsidTr="00CC5D94">
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>物品说明</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="4978" w:type="dxa"/>
<w:gridSpan w:val="3"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>${goods.description}</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
<w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>上架时间</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>${goods.time}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>上架人</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1660" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>${goods.user}</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
<#else>
<w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>物品名称</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>${goods.name}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>物品数量</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1660" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>${goods.number}</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
<w:tr w:rsidR="00770B3E" w:rsidTr="00644BE9">
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>物品说明</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="4978" w:type="dxa"/>
<w:gridSpan w:val="3"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>${goods.description}</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
<w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
<w:vMerge/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>上架时间</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>${goods.time}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1659" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>上架人</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1660" w:type="dxa"/>
</w:tcPr>
<w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
<w:t>${goods.user}</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
</#if>
</#list>
将上面代码放入demo.xml文件中替换掉原来的两个假数据行。替换后如下:(由于数据多,这里就截图展示)
将上诉的demo.xml保存并改为demo.ftl即完成freemarker的模板。
提示:这里说下为啥要if else ,因为第一次生成的行需要展示合并的单元格,后面的整个数据都是一个合并标签。当然简单化也可以在第一行的第一个单元格做if else不需要像我这样整个循环体做if else
三、编写freemarker模板导出复杂格式word代码
首先把上面制作的demo.ftl放入Java项目的classpath目录下
Java数据模型Goods
$title(Goods.java)
package demo;
public class Goods {
public Goods(String name, Integer number, String description, String time, String user) {
this.name = name;
this.number = number;
this.description = description;
this.time = time;
this.user = user;
}
String name;
Integer number;
String description;
String time;
String user;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
}
导出代码:
$title(ComplexWordExport.java)
package demo;
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
public class ComplexWordExport {
public static void main(String[] args) {
try {
// 创建模拟数据
List<Goods> goodsList = new ArrayList<>();
for (int i = 0; i < 4; i++) {
goodsList.add(new Goods("刀" + i, i + 2, "到很好不错,数量多+" + i,
new SimpleDateFormat("HH:mm:ss:SSS").format(new Date()), "用户" + i));
}
Map<String ,Object> dataMap=new HashMap<>();
dataMap.put("goodsList",goodsList);//注意这里的key与目标中的数据对应
File wordFile = new File("d:/demo.doc");// 注意这里只能输出doc,不能直接输出docx
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
configuration.setClassForTemplateLoading(WordTest.class, "/");
// 模板来源
// 1.创建一个word文件可以是doc或者docx的
// 2.在需要使用变量的地方用占位符占位
// 3.将word文档另存为xml文件
// 4.打开xml文件将里面的占位符替换为freemarker的表达式
// 5.重命名xml为ftl
// 6.完成
Template template = configuration.getTemplate("demo/demo.ftl", "UTF-8");//路径相对于项目的classpath
try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(wordFile),"UTF-8"))) {
template.process(dataMap, out);
out.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
四、导出结果
注意:导出文件必须是.doc因为docx会验证xml里面的一些数据导致文件打不开。
提示:项目源码下载,访问密码9987
demo-word-export-template-freemarker.zip
原创文章,作者:kirin,如若转载,请注明出处:https://blog.ytso.com/243616.html