(ssh整合web导出excel)在ssh框架中使用poi正确导出具有比较高级固定格式的excel 整体过程,查询导出前后台下载

(一) 接需求  :   需求相关   (贴图 )

生成三核对文件

1、新增三核对菜单页面中,增加生成三核对文件功能按钮,弹窗可根据变电站、电压等级查询定值单。

2、定值单信息以表格形式展示,根据选择情况,生成三核对文件。

整体就是这样的一个需求,分sheet,合并单元格,设置各种单元格格式,要有序号。

(二)吐槽

新手,什么都不会,哈哈我当时整个人都是懵逼的。一会总结说。

(三)具体流程

全部代码,控制层,service,前台,全都贴在最下面。

1 数据库查询

2将信息导出为datatable格式(公司框架)

3将datatable格式转化为workbook(循环遍历)  使用poi 导出excel

4workbook生成多SHEET以及合并单元格,单元格赋值,转换style

5生成workbook后  弹出下载页面  能够传到浏览器界面提供下载   (有关springweb框架前后台传参数取值问题 )

6中间出现的一些小问题  (全局变量设置  )

(四)代码实现与实现过程问题与解决

1 数据库查询

要生成一个这样一个excel表格,而我们的信息还没有获取到,这时应该考虑如何根据通过前台传过来的参数进行一次查询。(参数为一个,就是能够获得一个能关联到三个表的guid(有一个是无主键视图))

而在查询过程中也遇到了一些问题。
1. 游标的使用

把查询想的太过简单,关联三个表的问题研究一会就解决了,但是又出现新的问题,首先数据库查询出的信息并不满足我想要的信息,因为在需求中,那个执行日期执行人和核对日期核对人在我的数据库查询语句中是无法实现的,因为他们两个是一个并行的行,只有一个guid的话,在我的查询语句中注定只能查出不是执行日期就是核对日期的列。也就是说执行日期核对日期都只是一列中的值,不能并存,只能查出一条。

解决:  网上查了下,使用了一个比较坏的方法:  建立一个游标临时表,先通过一部分限制条件单独将执行日期执行人核对日期核对人查出如下

这个就是游标的一种用法,查出这样的数据后,建立游标,使用forward-only进行顺序读取, 也就是将这两行两列的数据从左至右读取并依次存入name2356中,这样我们就可以为所欲为了,因为这样我们可以安排name2356到任何地方,他们中一直都存着我之前给他们赋予的值,因为它们在一个临时表中,这样在下面放入数据库信息时,我再给它们用as重新命名并且进行拼接,可以直接安放到另一个查询语句中。  这样就解决了将不同行的某些信息放入同一行中的问题。

2.字符串的拼接。

表格中的信息部分我只能查到单独的信息,比如执行人和执行日期,这两个是两列,如何拼起来让他们变成一列。

查了一下,这个还是很好解决,使用+和as就可以解决。之前还以为多难。。。。

3.一个guid   与   变电站转化。

仔细看之前的表格需求,是分sheet的,是以变电站为一个sheet的形式,那么,我们应当如何做呢。就是分数据源来进行查询。

传过来的参数只有guid一个字符串,但是我可以通过guid来查出这些guid中的信息都是哪几个变电站的。

在这样的数据库查询语句中,使用in是如何使用的呢,毕竟in'1,2,3'这样的格式,和字符串格式还是有点差距。

那么就是用  String guiddd = "'"+guid.replaceAll(",", "','")+"'";//转换为能够被数据查询语句查询的字符串 这样,guiddd就能够使用啦。

我这个逻辑比较乱,如下图,这样就完成了分数据源查询,也就可以分sheet了。

具体数据库查询如下。

2将信息导出为datatable格式(公司框架)

这样查出了信息之后其实也顺便将信息放入一个datatable中了,这个datatable好像是c#中的一种封装好的, 公司平台也给它用java封装了一个类。

这样每个datatable中其实包含了一个sheet的信息,一会对这个对象进行上下的循环遍历就能够存入信息主体啦。

说的很轻松他妈的看这个datatable的源码看了我好久,太菜了。

3将datatable格式转化为workbook(循环遍历)

这样是一个sheet,使用poi 包可以通过建立一个workbook(一个完整的excel表格)

我是这样做的,就是先在循环外围建立一个workbook,然后在sub循环中建立sheet,guid循环,也就建立了sub.length个sheet,一个sheet中也包含了一个sub中的所有信息,这个work中包含了所有全部sheet。  (sheet的name就是查询出的subname)

W

我是不是搞复杂了。。。

4workbook生成多SHEET以及合并单元格,单元格赋值,转换style

到这里就是一个比较繁琐的事情了,因为在需求中有五种格式一上,还有单元格的样式问题。

先说sheet导入时单个sheet其实是这个样子(下面是样式),有特别多不符合要求的地方,这里还没有分sheet,此刻就先让整个数据信息向下平移两个单元格留出标题以及序号的位置,然后向右平移留出一个序号位置。

具体工具类的设定就不说了,比较简单。

重点说一下合并单元格以及合并单元格的赋值与设定cellstyle是如何操作的。

下面的代码就是先使用这个合并单元格,

 CellRangeAddress(起始行,结束行,起始列,结束列);
CellRangeAddress craa = new CellRangeAddress(rownumber,rownumber,0,5);
像我这样创建的话,这个单元格就是rownumber的第一个单元格了,因为起始列是0.
但是现在其实sheet中并没有改变这个单元格。
必须要用
 sheet.addMergedRegion(craa); 
这个语句来进行sheet单元格的添加。
添加后,需要
    HSSFRow roww = sheet.createRow(rownumber);
  HSSFCell cellw = roww.createCell((short)0);
在sheet中找到对应行以及对应单元格位置。以上。  这样,单元格与合并单元格就对应啦。
就可以和正常单元格一样给它赋值设定style或是干什么了~~~。
下面代码,没有格式,我在下面会加上所有代码。

然后序号问题我就做的比较蠢了,向下平移两格后第二行我直接设置column.size()的个数递增设置列序号。。。。。。。

竖向序号的话就直接在数据库中加了点东西,因为用的是sql server,所以有现成的东西。

ROW_NUMBER() OVER (ORDER BY GUID) AS 'RowNumber'
这个可以增加行序号~

5生成workbook后  弹出下载页面  能够传到浏览器界面提供下载   (有关springweb框架前后台传参数取值问题 )

有关这个前后台传递参数的问题我搞了三天吧,从最开始傻了吧唧直接指定固定位置后台直接保存,到前台传递参数后台接受并操作,操作后response回前台弹出窗口并进行下载。问别人问到他烦哈哈哈哈哈妈的真是没爱。

首先,所用框架决定,我要是想弹出下载的话,应该有固定的参数格式。我的参数格式是参照springweb传递参数的格式设定的。这里就不是java的问题了,是js jq的问题,他们应当能够给我后台传回我所需要我能操作的参数。

这里贴一段js代码。前台单击按钮,首先将要获取的东西一一获取,然后设定url,然后设定参数,然后提交到openpostwindow中,在这个方法里面,新建一个form表单,传过来几个参数,我就新建几个inputfield ,不过这些都是隐藏着进行的,用户看不到,然后使用for in  依次给inputfield赋值,name和value,皆对应相应的参数值,

比如我的,就是name就是我自己传过来设定的那个名字,substationa

value则是我subtation实际传过来的值,即"白云变"

这样 ,form中包含着三个inputfield,而这三个控件则拥有其自己的名字和值,  然后进行提交表单,就可以进入后台,后台中是这样的定义的。

这样,就ok啦,前台获取的参数,通过提交表单,传入后台参数,后台可以对这个进行操作了。required = false 是传入的参数可以为空的意思~~~

这个应该算是注解模式吧,使用的时候必须debug慢慢看,前后台都要debug,不然不行。

调试这个时候总是要出现  error400的   ,不是你的url有问题,就是你的传参有问题,一般我都是传参有问题。

前后台传参结束了,后台操作也结束了,现在生成的这个workbook放到哪里呢。~~~

这么放,重点看几行,

  OutputStream out = response.getOutputStream();
20 response.setCharacterEncoding("UTF-8");
21 response.setContentType("application/x-msdownload");//设置向浏览器端传送的文件格式
22 response.setHeader("Content-disposition", "attachment; filename="
23 + URLEncoder.encode(fileName, "utf-8"));

22+23行代码就是关键,以这个格式设置的话,便会弹出下载。  写完记得关文件流。

这个代码还存到了c盘,如果没有c盘还会报错。

不想存的话可以直接删了。

(五)总结

这个是我自己做出来的效果。代码会在下面。

总结

现在是总结和吐槽时间。

这个功能其实想想不难,难住我的是刚接触java直接用框架再加上公司平台,我直接懵逼,期间自我否定,有点怨天尤人,让我耽误了很多时间。

刚开始我是真的觉得自己做不出来,几乎什么都不懂,然后这个功能身边一个组的同事也都不太懂。。。我问人都没地方问。。。真的太折磨了。。。

数据库由于应用不熟练不懂游标 ,一路查一路搞过来,数据库应该注意的是在java语句中一定要注意空格,注意一些字符的长度,我被guid坑了好久,因为默认字符长度太短我的guid总是少了两个字符,找了好久查询不出来的问题。游标懂了一些,拼接懂了一点,表的联合懂了一点。

前后台那里问人加研究,debug太重要了,一步一步,de的我头发哗哗掉。

poi操作excel ,我从听都没听过到做出这么一个比较规整美观的表格我还是很有成就感的,多亏了博客园的诸多博客以及百度啦,需要改进的地方就是自己不太想去深入的理解,总是去试,因为这样不用思考,这样太蠢了,,100多个尝试文档。。也是智障。。。。

最重要的是,做事绝不可以敷衍了事了,工作不满足用户需求,就是你自己的锅,活在手里,决不能逃避,逃也是你的,不会做还是你的,没有人会管你。

凡事先debug再问人,先把手里信息弄懂,这样问人,别人说的话你才懂,你问别人的问题,才有分量。

时间不等人,努力。。。。

以下为各层代码

view层在前面拉,我就不重复了~~

希望有人给我留言指点一下~~谢谢谢~