使用freemarker导出复杂的excel表格、word文档

        最近因为项目需要,需要导出复杂的excel表格。由于需要合并单元格以及样式处理,用poi导出显得比较困难。因为之前用freemarker导出过pdf/word文件,就想着能不能用其导出excel。经过一番实验,大功告成,真是比poi好用N多倍呀!废话少说,直接进入正题。

        excel表格用编辑器打开后,可以发现它也是一个可编辑的标记性的格式,如同html页面里面的标签首尾相连。那就好办了。以下是具体步骤,部分逻辑不赘述直接上代码了。有逻辑或代码简陋望大神不要嘲笑并不吝指教。

        一、首先根据我们最终需要导出的excel表格的格式,用假数据填充后生成一个excel模板。如下图(假数据填充,作为模板):

       使用freemarker导出复杂的excel表格、word文档_第1张图片模板生成后,将当前模板另存,选择另存为XML格式 ,如下图:


另存后的文件打开后如下图:

使用freemarker导出复杂的excel表格、word文档_第2张图片


分析该文件,我们会发现如同poi导出一样,该文件已经自动包含了需要的样式Styles、Worksheet、Table、以及一行行的数据Row。我们只需要关注Table里面的东西就好,分析数据后根据自己的具体业务逻辑,将之前渲染的假数据通过freemarker的标签替换成动态的生成形式。至此,前期准备完毕。如图:

使用freemarker导出复杂的excel表格、word文档_第3张图片

二、前后台的最终实现(其实整个过程中最复杂部分就在将转成xml的文件中的数据替换成动态的)

前台部分:

页面点击导出按钮后触发事件,fileFrame是页面iframe隐藏域的id:


后台部分:直接上代码,很少几行而已。

使用freemarker导出复杂的excel表格、word文档_第4张图片

至此,通过freemarker导出复杂excel表格完成。相较于poi,本人更喜欢这种方式。由于担心一上来整的数据样子看起来太复杂大家看不明白,因此在末尾又码了一个简单模型,希望对大家有帮助。哈哈!

使用freemarker导出复杂的excel表格、word文档_第5张图片



补充:有朋友问我freemarker导出word,在这里也简单说一下,跟excel导出基本流程是一样的。

首先就是模板制作:将下图word模板另存为xml格式

使用freemarker导出复杂的excel表格、word文档_第6张图片

将转成的xml的w:tr (其实就是行)全部用freemarker动态标签渲染上

使用freemarker导出复杂的excel表格、word文档_第7张图片

动态渲染后的xml代码(比较长):



xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core"
xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"
xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no"
xml:space="preserve">出国、赴港澳任务批件飞总保卫室文书Administrator62016-10-11T07:11:00Z2018-07-03T07:56:02Z432044082327center1952730 dt:dt="string">2052-10.1.0.7400 w:ascii="Times New Roman" w:fareast="宋体" w:h-ansi="Times New Roman"
w:cs="Times New Roman" /> w:val="02020603050405020304" /> w:val="Auto" /> w:usb-1="C0007843" w:usb-2="00000009" w:usb-3="00000000" w:csb-0="400001FF"
w:csb-1="FFFF0000" />
w:val="02010600030101010101" /> w:val="Auto" /> w:usb-1="288F0000" w:usb-2="00000006" w:usb-3="00000000" w:csb-0="00040001"
w:csb-1="00000000" />
w:val="05000000000000000000" /> w:val="Auto" /> w:usb-1="00000000" w:usb-2="00000000" w:usb-3="00000000" w:csb-0="80000000"
w:csb-1="00000000" />
w:val="020B0604020202020204" /> w:val="SWiss" /> w:usb-0="E0002AFF" w:usb-1="C0007843" w:usb-2="00000009" w:usb-3="00000000"
w:csb-0="400001FF" w:csb-1="FFFF0000" />
w:val="02010609060101010101" /> w:val="Auto" /> w:usb-1="38CF7CFA" w:usb-2="00000016" w:usb-3="00000000" w:csb-0="00040001"
w:csb-1="00000000" />
w:val="02070309020205020404" /> w:val="Modern" /> w:usb-0="E0002AFF" w:usb-1="C0007843" w:usb-2="00000009" w:usb-3="00000000"
w:csb-0="400001FF" w:csb-1="FFFF0000" />
w:val="05050102010706020507" /> w:val="Roman" /> w:usb-0="00000000" w:usb-1="00000000" w:usb-2="00000000" w:usb-3="00000000"
w:csb-0="80000000" w:csb-1="00000000" />
w:val="020F0502020204030204" /> w:val="SWiss" /> w:usb-0="E00002FF" w:usb-1="4000ACFF" w:usb-2="00000001" w:usb-3="00000000"
w:csb-0="2000019F" w:csb-1="00000000" />
w:defLockedState="off" w:latentStyleCount="260"> w:name="Normal" /> w:name="heading 2" /> w:name="heading 4" /> w:name="heading 6" /> w:name="heading 8" /> w:name="index 1" /> w:name="index 3" /> w:name="index 5" /> w:name="index 7" /> w:name="index 9" /> w:name="toc 2" /> w:name="toc 4" /> w:name="toc 6" /> w:name="toc 8" /> w:name="Normal Indent" /> w:name="annotation text" /> w:name="footer" /> w:name="caption" /> w:name="envelope address" /> w:name="footnote reference" /> w:name="line number" /> w:name="endnote reference" /> w:name="table of authorities" /> w:name="toa heading" /> w:name="List Bullet" /> w:name="List 2" /> w:name="List 4" /> w:name="List Bullet 2" /> w:name="List Bullet 4" /> w:name="List Number 2" /> w:name="List Number 4" /> w:name="Title" /> w:name="Signature" /> w:name="Body Text" /> w:name="List Continue" /> w:name="List Continue 3" /> w:name="List Continue 5" /> w:name="Subtitle" /> w:name="Date" /> w:name="Body Text First Indent 2" /> w:name="Note Heading" /> w:name="Body Text 3" /> w:name="Body Text Indent 3" /> w:name="Hyperlink" /> w:name="Strong" /> w:name="Document Map" /> w:name="E-mail Signature" /> w:name="HTML Acronym" /> w:name="HTML Cite" /> w:name="HTML Definition" /> w:name="HTML Preformatted" /> w:name="HTML Typewriter" /> w:name="Normal Table" /> w:name="Table Simple 1" /> w:name="Table Simple 3" /> w:name="Table Classic 2" /> w:name="Table Classic 4" /> w:name="Table Colorful 2" /> w:name="Table Columns 1" /> w:name="Table Columns 3" /> w:name="Table Columns 5" /> w:name="Table Grid 2" /> w:name="Table Grid 4" /> w:name="Table Grid 6" /> w:name="Table Grid 8" /> w:name="Table List 2" /> w:name="Table List 4" /> w:name="Table List 6" /> w:name="Table List 8" /> w:name="Table 3D effects 2" /> w:name="Table Contemporary" /> w:name="Table Professional" /> w:name="Table Subtle 2" /> w:name="Table Web 2" /> w:name="Balloon Text" /> w:name="Table Theme" /> w:name="Light List" /> w:name="Medium Shading 1" /> w:name="Medium List 1" /> w:name="Medium Grid 1" /> w:name="Medium Grid 3" /> w:name="Colorful Shading" /> w:name="Colorful Grid" /> w:name="Light List Accent 1" /> w:name="Medium Shading 1 Accent 1" /> w:name="Medium Shading 2 Accent 1" /> w:name="Medium List 1 Accent 1" /> w:name="Medium List 2 Accent 1" /> w:name="Medium Grid 1 Accent 1" /> w:name="Medium Grid 2 Accent 1" /> w:name="Medium Grid 3 Accent 1" /> w:name="Dark List Accent 1" /> w:name="Colorful Shading Accent 1" /> w:name="Colorful List Accent 1" /> w:name="Colorful Grid Accent 1" /> w:name="Light Shading Accent 2" /> w:name="Light List Accent 2" /> w:name="Medium Shading 1 Accent 2" /> w:name="Medium Shading 2 Accent 2" /> w:name="Medium List 1 Accent 2" /> w:name="Medium List 2 Accent 2" /> w:name="Medium Grid 1 Accent 2" /> w:name="Medium Grid 2 Accent 2" /> w:name="Medium Grid 3 Accent 2" /> w:name="Dark List Accent 2" /> w:name="Colorful Shading Accent 2" /> w:name="Colorful List Accent 2" /> w:name="Colorful Grid Accent 2" /> w:name="Light Shading Accent 3" /> w:name="Light List Accent 3" /> w:name="Medium Shading 1 Accent 3" /> w:name="Medium Shading 2 Accent 3" /> w:name="Medium List 1 Accent 3" /> w:name="Medium List 2 Accent 3" /> w:name="Medium Grid 1 Accent 3" /> w:name="Medium Grid 2 Accent 3" /> w:name="Medium Grid 3 Accent 3" /> w:name="Dark List Accent 3" /> w:name="Colorful Shading Accent 3" /> w:name="Colorful List Accent 3" /> w:name="Colorful Grid Accent 3" /> w:name="Light Shading Accent 4" /> w:name="Light List Accent 4" /> w:name="Medium Shading 1 Accent 4" /> w:name="Medium Shading 2 Accent 4" /> w:name="Medium List 1 Accent 4" /> w:name="Medium List 2 Accent 4" /> w:name="Medium Grid 1 Accent 4" /> w:name="Medium Grid 2 Accent 4" /> w:name="Medium Grid 3 Accent 4" /> w:name="Dark List Accent 4" /> w:name="Colorful Shading Accent 4" /> w:name="Colorful List Accent 4" /> w:name="Colorful Grid Accent 4" /> w:name="Light Shading Accent 5" /> w:name="Light List Accent 5" /> w:name="Medium Shading 1 Accent 5" /> w:name="Medium Shading 2 Accent 5" /> w:name="Medium List 1 Accent 5" /> w:name="Medium List 2 Accent 5" /> w:name="Medium Grid 1 Accent 5" /> w:name="Medium Grid 2 Accent 5" /> w:name="Medium Grid 3 Accent 5" /> w:name="Dark List Accent 5" /> w:name="Colorful Shading Accent 5" /> w:name="Colorful List Accent 5" /> w:name="Colorful Grid Accent 5" /> w:name="Light Shading Accent 6" /> w:name="Light List Accent 6" /> w:name="Medium Shading 1 Accent 6" /> w:name="Medium Shading 2 Accent 6" /> w:name="Medium List 1 Accent 6" /> w:name="Medium List 2 Accent 6" /> w:name="Medium Grid 1 Accent 6" /> w:name="Medium Grid 2 Accent 6" /> w:name="Medium Grid 3 Accent 6" /> w:name="Dark List Accent 6" /> w:name="Colorful Shading Accent 6" /> w:name="Colorful List Accent 6" /> w:name="Colorful Grid Accent 6" /> w:type="paragraph" w:styleId="a1" w:default="on"> w:val="off" /> w:val="2" /> w:fareast="ZH-CN" /> w:styleId="a6" w:default="on"> w:type="table" w:styleId="a8" w:default="on"> w:w="0" w:type="dxa" /> w:w="0" w:type="dxa" /> w:type="paragraph" w:styleId="a2"> w:val="a3" /> w:val="a3" /> w:type="paragraph" w:styleId="a3"> w:val="a1" /> w:type="paragraph" w:styleId="a4"> w:val="a1" /> w:val="center" w:pos="4153" /> w:val="off" /> w:val="18" /> w:type="paragraph" w:styleId="a5"> w:val="a1" /> w:val="single" w:sz="6" wx:bdrwidth="15" w:space="1" w:color="auto" /> w:val="center" w:pos="4153" /> w:val="off" /> w:val="18" /> w:type="character" w:styleId="a7"> w:val="a6" /> w:type="character" w:styleId="a9"> w:val="a6" /> w:val="18" /> w:type="character" w:styleId="a10"> w:val="a6" /> w:val="18" /> id="_x0000_s1025"> w:val="print" /> w:val="CompressPunctuation" /> w:enforcement="off" /> w:val="425" /> w:val="105" /> w:val="156" /> w:val="0" /> w:val="2" /> w:val="center" /> w:val="32" /> w:val="32" />出 国 人 员 名 单 w:ascii="宋体" w:hint="default" /> w:ascii="宋体" w:hint="fareast" />                                                                          w:ascii="宋体" w:hint="fareast" />本单位人数:${total!''} w:w="12915" w:type="dxa" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:type="Fixed" /> w:w="108" w:type="dxa" /> w:w="108" w:type="dxa" /> w:w="1155" /> w:w="840" /> w:w="2625" /> w:w="2835" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:w="0" w:type="dxa" /> w:w="0" w:type="dxa" /> w:val="on" /> w:w="1155" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" /> w:val="24" />序号 w:w="1155" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" /> w:val="24" />姓   名 w:w="840" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" /> w:val="24" />性别 w:w="1365" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" /> w:val="24" />出生日期 w:w="1365" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" /> w:val="24" />出生地 w:w="2625" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" /> w:val="24" />身份证号码 w:w="1575" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:hint="fareast" />工作单位 w:w="2835" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" /> w:val="24" />职务


<#if pageList?exists && (pageList?size>0)>
<#list pageList as person>
w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /> w:w="0" w:type="dxa" /> w:w="0" w:type="dxa" /> w:val="on" /> w:w="1155" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" />${person_index + 1} w:w="1155" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" /> w:val="24" />${person.userName!''} w:w="840" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" /> w:val="24" />${person.sex!''} w:w="1365" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" />${person.birthDate!''} w:w="1365" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" /> w:val="24" />${person.bornIn!''} w:w="2625" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" />${person.idNo!''} w:w="1575" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" /> w:val="24" />${person.depDes!''} w:w="2835" w:type="dxa" /> w:fill="auto" /> w:val="center" /> w:val="24" /> w:val="24" />${person.postDuty!''}





w:left="8820" w:left-chars="4200" /> w:left="8820" w:left-chars="4200" /> w:left="8820" w:left-chars="4200" /> w:hint="fareast" />公章: w:left="8820" w:left-chars="4200" /> w:left="9240" w:left-chars="4400" /> w:hint="fareast" />${year!''}年${month!''}月${day!''}日 w:w="16838" w:h="11906" w:orient="landscape" /> w:right="1440" w:bottom="1701" w:left="1440" w:header="851" w:footer="992"
w:gutter="0" /> w:type="lines-and-chars" w:line-pitch="312" />

接下来就是后台代码了,直接上图:

使用freemarker导出复杂的excel表格、word文档_第8张图片

后台代码:

@RequestMapping("/exportWord.do")
public void exportWord(HttpServletRequest request,HttpServletResponse response,String certGroupId,String orderType){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateString = sdf.format(new Date());//2018-07-03
String basePath =request.getSession().getServletContext().getRealPath("/");//绝对路径    
String basePath2=basePath.replaceAll("\\\\", "/");  
Configuration cfg = FreemarkerConfiguration.getConfiguation();
//封装返回数据
Map returnMap = new HashMap<>();
try {
cfg.setDirectoryForTemplateLoading(new File(basePath2 + "/WEB-INF/pages/icert/group"));
List pageList = hrCertGroupPersonService.selectPersonListByCertGroupId(certGroupId,orderType);
returnMap.put("pageList", pageList);
returnMap.put("total", pageList.size());
returnMap.put("year",dateString.substring(0, 4));
returnMap.put("month",dateString.substring(5, 7));
returnMap.put("day",dateString.substring(8, 10));
request.setCharacterEncoding("UTF-8"); 
    response.setContentType("application/x-download;");  
    response.setHeader("Content-disposition", "attachment; filename="  
                + new String("出国人员名单.doc".getBytes("gb2312"), "ISO8859-1"));
    response.setCharacterEncoding("UTF-8");
    cfg.getTemplate("/groupWord.xml").process(returnMap,response.getWriter());
} catch (Exception e) {
e.printStackTrace();
}
}

至此,用freemarker导出word完成,流程与导出excel一致。


码字不易,转载请注明出处!

你可能感兴趣的:(java上传,下载,导出,打印)