sqlrowset 转化为json_关于SpringMVC中如何把查询数据全转成String类型

之前,本想与客户商量做几张固定的报表予使用,结果发现客户每个月都需要各种各样的报表,所以我们做了个窗口用于直接执行SQL语句;数据量一开始并不是很大查询出来的数据较少(约1~6W左右),所以刚开始几个月很好用,查询出来的数据直接从页面复制下来贴到Excel做月报表,就这样一年过去了,最近做三期,发现运维人员月底几天特别的忙,数据逾百万(汗),SQL查询语句都要写n多分页。。。。

伙伴们如此幸苦,还是我来拯救他们吧~

我的解决思路大致如下:

A>界面增加查询倒出Excel表功能(SQL不需要分页,也不需要在页面显示)

B>在后端把查询结果字段全转换成String类型(主要解决BigDeceal还有long类型在JXL中数据类型转换问题)

C>把查询出来的数据按6W/每页 分页(主要由于JXL只能导出.XLS文件类型(2003型)的EXCEL文件,故每sheet最多只能容纳65536行数据)

D>查询出来的数据遍历分页(需要注意的是sheet名需要按当前数据量和位置命名,EXCEL样式为固定样式)

开始上代码啦~

A就直接略过...

SQL语句传入JdbcTemplate获取数据后会返回一个SqlRowSet对象,现在就开始把每一列的字段类型通过遍历获取字段的String数据,然之放入Map中,以此类推,把所有记录的各个字段全转换成String,其中需要主要的是,Map的Key需要通过getMetaData().getColumnNames()获取,这是个String数组,你需要遍历这个String数组(下标从0开始),对应的Value的下标是从1开始的,千万不要搞错啦~(附代码)

/**

* 查询数据

* @param sql

* @return

*/

public List> queryToFile(String sql){

SqlRowSet rs=jdbc.queryForRowSet(sql);//JdbcTemplate

List> mList=new ArrayList>();

while(rs.next()){

Map mp=new HashMap();

for(int i=0;i

mp.put(rs.getMetaData().getColumnNames()[i], rs.getString(i+1));//注意!

}

mList.add(mp);

}

return mList;

}

SqlRowSet提供的Api确实够用,如果是从存储过程取固定列长度类型的数据完全可以使用getBigDecimal(...)、getInt(...)等方法直接获取指定的列的数据 再行处理更为便捷

以上数据处理算是个难点,数据处理好了,接下来还有两个问题:如何分页,如何按数据的index给sheet命名?

下面我是按6W每份切割源数据,核心就是整除取余,记住整除的时候预计会是一个float或double的数,这不重要,重要的是你用int接收,double的小数部分会被无情地截掉,因此页数不会小于1的,(代码):

/**

* 将数据切割成6W每组的List

* @param data

* @return

* @throws ParseException

*/

public List>> splitDatas(List> data) throws ParseException{

List>> mList=new ArrayList>>();

int len=data.size()%60000==0?data.size()/60000:data.size()/60000+1;//关键点!!!

for(int i=0;i

if(i

List> l=new ArrayList>();

l.addAll(data.subList(i==0?0:i*60000, (i+1)*60000));

mList.add(l);

}else{//最后一组数据这样处理

List> l=new ArrayList>();

l.addAll(data.subList(i*60000, data.size()));

mList.add(l);

}

}

return mList;

}

做到这里,我们已经把数据按每6W/份 扔进List里面了,但是导出的数据量大的时候不可能不看sheet名吧,sheet是可以命名的干嘛要使用自动生成的sheet1、sheet2...?

说白了,为了更方便些,我们需要做成这样子:

定位准确清晰易懂岂不更好?

说的容易做的并不轻巧,这时你需要处理好当前组的index和size才行,要不然做出来的东西可能就存在断号或遗漏的问题...,以下是个人的处理逻辑,请小心查看book.createSheet(...)的命名方式(也就是sheet的命名方式):

/**

* 导出多Sheet Excel,按6W每份分sheet

* @param data 数据

* @param headerName 头名称

* @param cellName 数据名称

* @param formName 表格名称

* @param response 响应

* @throws ParseException 异常

*/

public void expSheetsExcel(List> data,List headerName,List cellName,String formName, HttpServletResponse response) throws ParseException{

try {

OutputStream os=response.getOutputStream();

response.reset();

WritableFont font1 = new WritableFont(WritableFont.TAHOMA, 11, WritableFont.BOLD, false);

WritableFont font2 = new WritableFont(WritableFont.TAHOMA, 10, WritableFont.NO_BOLD, false);

WritableCellFormat cellFormat1 = new WritableCellFormat(font1);

WritableCellFormat cellFormat2 = new WritableCellFormat(font2);

cellFormat1.setBackground(Colour.GRAY_25);

cellFormat1.setAlignment(jxl.format.Alignment.CENTRE);

cellFormat1.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);

cellFormat2.setAlignment(jxl.format.Alignment.CENTRE);

cellFormat2.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);

WritableWorkbook book=Workbook.createWorkbook(os);//创建一个Excel表

String fileName =formName+".xls";

response.setContentType("application/x-excel");

response.setHeader("Content-disposition","attachment;filename="+new String(fileName.getBytes("GBK"),"iso8859-1"));

/*切割数据为6W每份*/

List>>mData=splitDatas(data);

for (List> mList : mData) {

//第一个sheet 参数(sheet名称,sheet的序号)

WritableSheet sheet=book.createSheet(String.format("%s~%s",

(data.size()>60000?

mData.indexOf(mList)*6000+1//(mData.size()==(mData.indexOf(mList)+1)?mData.indexOf(mList)*6000:60000*(mData.indexOf(mList)))

:0)+"",

(data.size()>60000?

(mData.size()==(mData.indexOf(mList)+1)?data.size():60000*(mData.indexOf(mList)+1))

:data.size())+""),

mData.indexOf(mList)

);

for(int i=1;i

sheet.setRowView(i,350,false); //设置行高

}

for(int j=0;j

sheet.setColumnView(j,30);//设置宽度

}

/*设置表头数据*/

int colLength=0;//标记行数

for(int k=0;k

sheet.addCell(new Label(k,colLength,headerName.get(k),cellFormat1));//(?列,?行,单元格内容,样式)

}

colLength+=1;//添加一行

/*设置表体数据*/

for(Map d : mList) {

for(int m=0;m

sheet.addCell(new Label(m,colLength,d.get(cellName.get(m)),cellFormat2));//(?列,?行,单元格内容,样式)

}

colLength+=1;//添加一行

}

}

book.write();

book.close();

os.close();

os.flush();

response.flushBuffer();

} catch(Exception e){

e.printStackTrace();

}

}

关键的地方用了三目运算,新手同学需自行查找三目运算相关的资料,这里就不再缀诉啦~~~

SpringMVC中使用Json传数据

在web项目中使用Json进行数据的传输是非常常见且有用的,在这里介绍下在SpringMVC中使用Json传数据的一种方法,在我的使用中,主要包括下面四个部分(我个人喜好使用maven这类型工具进行项 ...

java中,字符串类型的时间数据怎样转换成date类型。

将字符串类型的时间转换成date类型可以使用SimpleDateFormat来转换,具体方法如下:1.定义一个字符串类型的时间:2.创建一个SimpleDateFormat对象并设置格式:3.最后使用 ...

SpringMVC中的 JSR 303 数据校验框架说明

JSR 303 是java为Bean数据合法性校验提供的标准框架,它已经包含在JavaEE 6.0中. JSR 303 通过在Bean属性上标注类似于@NotNull.@Max等标准的注解指定校验规则 ...

springMVC中接收请求参数&&数据转发

### 1. 接收请求参数 #### 1.1. [不推荐] 通过HttpServletRequest获取请求参数 假设存在:

关于异常的疑难解答:System.Runtime.InteropServices.COMException

COMException exception is thrown when an unrecognized HRESULT is returned from a COM method call.&qu ...

C#使用DirectoryEntry操作IIS创建网站和虚拟路径

原文:http://www.cnblogs.com/Aiooioo/archive/2011/05/30/cs-iis.html 在.Net中我们可以使用内置的类DirectoryEntry来承载II ...

BCM wifi驱动学习

BCMwifi驱动学习 一.wifi详解1 1.代码路径:Z:\home\stonechen\svn\TD550_X\TD550\3rdparty\wifi\BCM43362\special\bcmd ...

【数学基础篇】---详解极限与微分学与Jensen 不等式

一.前述 数学基础知识对机器学习还有深度学习的知识点理解尤为重要,本节主要讲解极限等相关知识. 二.极限 1.例子 当 x 趋于 0 的时候,sin(x) 与 tan(x) 都趋于 0. 但是哪一个趋 ...

vue加载流程

首先加载main.js,main.js中new一个vue实例,这个实例中会有一个id="app"映射到app.vue,启动时候首页映射到index.html,其中

lambda函数式编程

一.接口注解(@FunctionalInterface) @FunctionalInterface interface Interface1 { public void print(); } publ ...

kafka环境搭建测试

一.安装 1. 下载:去kafka官网下载:https://www.apache.org/dyn/closer.cgi?path=/kafka/0.9.0.1/kafka_2.11-0.9.0.1.t ...

SpringCloud初体验之Eureka

Eureka简介 SpringBoot简化了Spring工程的复杂度,之前复杂的Spring工程被拆分成了一个个小的SpringBoot工程.那么SpringBoot之间如何通讯,相互获取信息呢?这就 ...

In Compiler.php line 36: Please provide a valid cache path.

/********************************************************************************* * In Compiler.php ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值