专业的编程技术博客社区

网站首页 > 博客文章 正文

java导出复杂word报表的模板配置、以及java的实现

baijin 2024-08-31 16:09:37 博客文章 3 ℃ 0 评论

最近在实际生产项目中,遇到了需要导出复杂列表的需求,具体需求如下图:

实际需求

简单的分析一下:

其中包括的情况有:

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即可!

最终效果如下:

最终效果

最后,我们就完成了整个打印以及在线预览的工作!

整个过程比较繁琐,大家还是在做的时候多多小心吧!!!

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表