最近在实际生产项目中,遇到了需要导出复杂列表的需求,具体需求如下图:
实际需求
简单的分析一下:
其中包括的情况有:
1:表格列表
2:列表的纵向、横向合并
3:列表中数据的主从关系的横向、纵向的排序
4:排序后横向数据的合并
因为开发过程中,每一个列表中的数据都来源于一张物理表,那么我们首先对其字段数据的模板化处理就比较单一了,但是如此一来第2张表格的排序以及合并上就要费点劲了!
第一步:word的标签化处理。
第一步,模板化处理
注意:${********},在一个模板中不能重复出现。
比如上图中的:两个项目名称、两个备注。
第二步:word的标签与数据库字段的对应处理
JAVA代码中可以使用POI的HSSFWorkbook (2003 .doc)或者 XSSFWorkbook(2007+ .docx)进行文档中的标签解析。
XSSFWorkbook需要额外导入poi-ooxml-3.9-sources.jar和poi-ooxml-schemas-3.9.jar。
一般严谨的后端程序会通过文件后缀名 、文件流的头文件去严谨的区分当前输入的文件;但是这样在导出什么的时候也会出现一些问题,好,我们本着向最低版本兼容的原则,选用了HSSFWorkbook !
所以,首先要将做好的模板保存为2003 doc的格式!
模板保存为这个格式
开发了一个接口解析出模板中的标签
解析结果如这个!
其实要想实现这个解析也没有什么的
解析过程
A:读取文件流内容
B:通过正则匹配${**********},并读取出其中的******。
解析后进行数据库配对
这个。。各自根据自己的业务需要去实现吧,其实就是对标签和数据库的表名字段名的一个关系的绑定!
各自操作,各自实现,当然还包括如何拼接SQL,从数据表中取出相对应的值,并且把最终结果 AS 标签名!
发现hibernate中同一个字段查询在sql中重复出现时,会出现查询异常,这时可以根据框架对sql进行处理,或者对模板标签进行同名化处理!
第三步:模板列表的xml脚本的编辑处理(模板中无列表、图片时,这一步可以省略!!!!!!)
模板中无列表、图片时,这一步可以省略!!!!!!
模板中无列表、图片时,这一步可以省略!但最好转换成XML格式,重点看一下下面的第1步就好了!
因为该模板中涉及到列表以及列表相关的操作处理
首先,我们把刚才的doc模板另存为xml格式。
doc另存为XML格式
然后使用NotePad++打开这个模板,并且对模板进行格式化
xml格式化
1:
首先重点看一下xml中非表格标签
<w:t>${项目名称}</w:t>中的{****}之间除了设定的“项目名称”有没有其他的字符。如果有,将其删掉,仅仅留下“项目名称”就够了!其他非列表情况一样处理!
非列表的标签
xml中出现这种情况的
错误情况
需要删掉多余的字符,处理成这种
正确情况
最后,最好全文搜索一下$,确保所有的标签在XML中都处理的正确无误!
这一步很重要!
所有的标签都是正确的!!
2:
至此,我们的xml就已经处理检查完毕了,下面我们就来讲讲列表的信息化处理!
下面的MAP的key值以及列表的列值,因为本系统底层自动化设计原理,就以数据库的表名,以及字段名来处理表示。
1》:列表的数据加载
在XML的列表标签的<w:tr........的上方加一个list标签
<#list AAAAA as listOne> 其中AAAAA 为列表物理表表名! listOne为其别名,随便起,自己能看懂,XML中不重复即可!
然后再在,标签的${********}的地方,把 ******** 改成 别名.具体字段名 !!
比如:${拟建项目} ---》》改成了----》》${listOne.APPCONCONTENT}
此处的APPCONCONTENT为 拟建项目 这个列在数据库中所对应的字段名!
TR上方
TR下方补齐标签对称
两个列表改完后是这样子的
注意:!!!!!!---在做列表的时候,“!”这个一定要在列表中加上!
列表中数据在查询时,有时为空值,所以我们要进一步处理模板中空值的情况;
${listTwo.REMARK!} -----数据库没有值的时候显示 空白
${listTwo.REMARK!!'默认值'},-----数据库没有值的时候显示 默认值
2:》数据列表的字段排序与合并
举例:在我们模板的第2个列表中,我们需要对“规划用地编号”相同的进行纵向的合并操作,并且其中地块的主信息与其附属信息存在主从关系!
为了达到HTML的grid表格中的效果,我们首先要对查询的数据进行排序:
html中的效果
分析一下,此图中主要涵盖了三个功能点:
1:根据用地编号进行行合并;
2:用地编号的主信息处于该地块的最后一行;
3:最后一行存在根据列的占用情况,进行列的合并;
A:排序:仔细分析一下此表格,此表格只需要根据“规划用地编号”、“界内用地性质”两个字段进行排序即可;实现方法还是需要在<list 标签中进行排序处理~~~~
list的排序
?sort_by("INSLANDTYPE")?sort_by("PLANLANDNO") INSLANDTYPE、PLANLANDNO为字段名!
注意:最主要的排序写在最后一个sort_by
排序后的效果:
信息排序后
B:合并
排序处理完后后,我们需要进行合并操作,在此表格中,需要根据用地编号进行行合并,并且需要对地块主信息中某些信息进行列合并。
1:跨行合并处理
1): 找出需要处理跨行的列!
2):在<w:tcW 标签内进行if判断,含义就是值一样的进行跨行标签<w:vMerge 的添加!
3):在显示具体信息值的地方加if判断,含义就是对于跨行的信息仅显示第一条!
跨行合并处理
经过此步骤的最终效果是这样的:
排序了,合并了!
此时此刻,我们距离成功还差最后一步!地块主信息的横向合并!
这一步就简单多了,因为我们“地下空间使用性质”、“地下垂直空间范围”、”地下水平投影最大范围”这几个值都是在数据库固定字段里面写死的,所以我们只需要找到这个字段,加一个if判断就能搞定了!
主要分为两步:
1):在<w:tcW 标签内加if判断指定跨列数目 <w:gridSpan w:val="3"/>
2):在列上加一个判断,当该列被前面的列跨了时,该列不在加载显示!
if判断列合并
这样整个XML文件就完成了制作,
最后一步!!!----------我们将这个XML文件的后缀名.xml,改成.ftl即可!
最终效果如下:
最终效果
最后,我们就完成了整个打印以及在线预览的工作!
整个过程比较繁琐,大家还是在做的时候多多小心吧!!!
本文暂时没有评论,来添加一个吧(●'◡'●)