合理使用导出csv、excel方式
- 结果集不大,并且格式固定,可用poi、jxl等方式
- 结果集无法估算大小,甚至有可能导致程序内存溢出,建议就直接用流的方式。将数据分页查询,再一页一页的写进流里,例子如下:
使用的jar包:
<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.3</version>
</dependency>
通用cvs导出方法
相关代码段:
/**
* 输出CSV
* @param response
* @param pageInfo 分页参数
* @param manager manager实例
* @param methodName manager对应方法
* @param cols 列名
* @throws IOException
*/
protected void writeCSV(HttpServletResponse response, PageInfo pageInfo, Object manager, String methodName, List<String[]> cols) throws IOException {
try {
response.setContentType("application/octet-stream");
response.setCharacterEncoding("GBK");
CSVWriter csvWriter = new CSVWriter(response.getWriter(), ',');
Class cla = manager.getClass();
Method m = cla.getDeclaredMethod(methodName, PageInfo.class);
// 查出总记录数、列名
int pageSize = pageInfo.getPageSize(); // 分页大小
pageInfo.setPageNumber(1);
pageInfo.setPageSize(1);
Page page = (Page) m.invoke(manager, pageInfo);
int totalNum = page.getTotalNumberOfElements(); // 总记录
int lastPageNum = totalNum / pageSize +1; // 页数
// 写列名到输出流
List<Object> objects = (List<Object>) page.getThisPageElements();
if(null == objects || objects.size() < 1){
return;
}
// 如果没有传入列名 默认用字段名
if (cols == null) {
cols = new ArrayList<String[]>();
String[] strs = ObjectUtils.getFiledName(objects.get(0));
cols.add(strs);
}
csvWriter.writeAll(cols);
// 将i页的记录写到输出流
pageInfo.setPageSize(pageSize);
List<String[]> strs = new ArrayList<String[]>();
for (int i = 1; i <= lastPageNum; i++) {
pageInfo.setPageNumber(i);
page = (Page) m.invoke(manager, pageInfo);
List<Object> objs = (List<Object>) page.getThisPageElements();
strs = ObjectUtils.listObj2Strs(objs);
csvWriter.writeAll(strs);
}
// 关闭输出流
csvWriter.flush();
csvWriter.close();
} catch (Exception e) {
log.error(e);
}
}
输出的csv:
id | pkey | pvalue | description |
---|---|---|---|
402828c44105be98014105c2f8ab0002 | test1 | test2 | 测试 |
ff8080814830f0af0148340d662c4fd2 | test1 | test2 | 测试 |
ff80808147812b9c014781a6af952557 | test1 | test2 | 测试 |
ff8080814834bd24014837070fdd32cf | test1 | test2 | 测试 |