java 导出Excel 大数据量,自己经验总结!(二)
在上一次的基础上加上了样式,以及中文列名
package com.tommy.fundation.util; import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set; import javax.servlet.http.HttpServletResponse; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors; public class ExportExcel<T> {
public void doExcel(HttpServletResponse response, List<T> list, String fileName) throws Exception {
String[] columnNames = new String[0];
doExcel(response, list , columnNames, fileName);
}
/**
* 导出多张excel表,解决xls格式行数65535的限制
* @author OnlyOne
* @param response
* @param list 需要处理的list数据集合
* @param columnNames 与实体属性一一对应的列名
* @param fileName 文件名
* @throws Exception
*/
public void doExcel(HttpServletResponse response, List<T> list, String[] columnNames, String fileName) throws Exception {
OutputStream os = response.getOutputStream();//获取输出流
response.reset();
// 设置下载头部信息。Content-disposition为属性名。attachment表示以附件方式下载,如果要在页面中打开,则改为inline。filename为文件名
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-disposition", "attachment;filename="+ new String((fileName + ".xls").getBytes(), "iso-8859-1")); //将数据集合按65000个进行分割成多个子集合
Map<Integer, List<T>> sheetMap = doSheets(list);
// 创建excel工作簿
HSSFWorkbook wb = new HSSFWorkbook();
//将map集合转换成set集合
Set<Integer> keys = sheetMap.keySet(); // 创建两种单元格格式
HSSFCellStyle cs = wb.createCellStyle();
HSSFCellStyle cs2 = wb.createCellStyle(); // 创建两种字体
HSSFFont f = wb.createFont();
HSSFFont f2 = wb.createFont(); // 创建第一种字体样式(用于列名)
f.setFontHeightInPoints((short) 10);
f.setColor(IndexedColors.BLACK.getIndex());
f.setBoldweight(Font.BOLDWEIGHT_BOLD); // 创建第二种字体样式(用于值)
f2.setFontHeightInPoints((short) 10);
f2.setColor(IndexedColors.BLACK.getIndex()); // 设置第一种单元格的样式(用于列名)
cs.setFont(f);
cs.setBorderLeft(CellStyle.BORDER_THIN);
cs.setBorderRight(CellStyle.BORDER_THIN);
cs.setBorderTop(CellStyle.BORDER_THIN);
cs.setBorderBottom(CellStyle.BORDER_THIN);
cs.setAlignment(CellStyle.ALIGN_CENTER); // 设置第二种单元格的样式(用于值)
cs2.setFont(f2);
cs2.setBorderLeft(CellStyle.BORDER_THIN);
cs2.setBorderRight(CellStyle.BORDER_THIN);
cs2.setBorderTop(CellStyle.BORDER_THIN);
cs2.setBorderBottom(CellStyle.BORDER_THIN);
cs2.setAlignment(CellStyle.ALIGN_CENTER); //对set集合进行遍历
for (Iterator<Integer> iterator = keys.iterator(); iterator.hasNext();) {
//获取遍历的下标
Integer sheetKey = iterator.next();
// 创建一个sheet(页),并命名
HSSFSheet sheet = wb.createSheet("sheet"+sheetKey);
//获取一页的数据
List<T> sheetData = sheetMap.get(sheetKey);
//创建列名的行
HSSFRow firstRow = sheet.createRow(0);
//如果columnNames有值,则作为列名;如果没有,则实体的属性名作为列名
if(columnNames.length == 0){
T en = (T) sheetData.get(0);
List<Object> titleList = RelectUtil.<T>reflectEntityAttribute(en);
for(int m=0; m<titleList.size(); m++){
HSSFCell cell = firstRow.createCell(m);
cell.setCellValue(titleList.get(m+1).toString());
cell.setCellStyle(cs);
}
}else{
for(int m=0; m<columnNames.length; m++){
HSSFCell cell = firstRow.createCell(m);
cell.setCellValue(columnNames[m]);
cell.setCellStyle(cs);
}
} // 手动设置列宽。第一个参数表示要为第几列设;,第二个参数表示列的宽度,n为列高的像素数。
for(int i=0;i<columnNames.length;i++){
sheet.setColumnWidth((short) i, (short) (35.7 * 100));
} //遍历一页的数据集合
for (int i = 0, len = sheetData.size(); i < len; i++) {
//获取数据实体
T en = (T) sheetData.get(i);
//反射获取行数据
List<Object> dataList = RelectUtil.<T>reflectEntity(en, en.getClass());
//创建数据行,以第二行开始,第一行作为列名使用
HSSFRow row = sheet.createRow(i+1);
for(int m=0; m<dataList.size(); m++){
HSSFCell cell = row.createCell(m);
cell.setCellValue(dataList.get(m).toString());
cell.setCellStyle(cs2);
} }
}
wb.write(os);
os.flush();
os.close();
}
/**
* 此方法将数据集合按65000个进行分割成多个子集合
* @author OnlyOne
* @param list 需要处理的list数据集合
* @return
*/
public Map<Integer, List<T>> doSheets(List<T> list){
int count = list.size()/65000;
int yu = list.size() % 65000;
Map<Integer, List<T>> map = new HashMap<Integer, List<T>>();
for (int i = 0; i <= count; i++) {
List<T> subList = new ArrayList<T>();
if (i == count) {
subList = list.subList(i * 65000, 65000 * i + yu);
} else {
subList = list.subList(i * 65000, 65000 * (i + 1));
}
map.put(i, subList);
}
return map;
}
}
辅助工具类
package com.tommy.fundation.util; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List; public class RelectUtil {
public static <T> List<Object> reflectEntity(T model,Class<?> cals) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchFieldException{
List<Object> list = new ArrayList<Object>();
Field[] field = model.getClass().getDeclaredFields(); //获取实体类的所有属性,返回Field数组
for(int j=0 ; j<field.length ; j++){ //遍历所有属性
String nam = field[j].getName(); //获取属性的名字
String name = nam;
name = name.substring(0,1).toUpperCase()+name.substring(1);
String type = field[j].getGenericType().toString(); //获取属性的类型 if(type.equals("class java.lang.String")){ //如果type是类类型,则前面包含"class ",后面跟类名
Method m = model.getClass().getMethod("get"+name);
String value = (String) m.invoke(model); //调用getter方法获取属性值
if(value != null){
list.add(value);
}else{
list.add("");
}
} if(type.equals("class java.lang.Integer") || type.equals("int")){
Method m = model.getClass().getMethod("get"+name);
Integer value = (Integer) m.invoke(model);
if(value != null){
list.add(value);
}else{
list.add("");
}
} if(type.equals("class java.lang.Short") || type.equals("short")){
Method m = model.getClass().getMethod("get"+name);
Short value = (Short) m.invoke(model);
if(value != null){
list.add(value);
}else{
list.add("");
}
} if(type.equals("class java.lang.Double") || type.equals("double")){
Method m = model.getClass().getMethod("get"+name);
Double value = (Double) m.invoke(model);
if(value != null){
list.add(value);
}else{
list.add("");
}
} if(type.equals("class java.lang.Boolean") || type.equals("boolean")){
Method m = model.getClass().getMethod("get"+name);
Boolean value = (Boolean) m.invoke(model);
if(value != null){
list.add(value);
}else{
list.add("");
}
} if(type.equals("class java.util.Date")){
Method m = model.getClass().getMethod("get"+name);
Date value = (Date) m.invoke(model);
if(value != null){
list.add(value);
}else{
list.add("");
}
}
}
return list;
}
public static <T> List<Object> reflectEntityAttribute(T model) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchFieldException {
List<Object> list = new ArrayList<Object>();
Field[] field = model.getClass().getDeclaredFields(); //获取实体类的所有属性,返回Field数组
for (int j = 0; j < field.length; j++) { //遍历所有属性
String nam = field[j].getName(); //获取属性的名字
list.add(nam);
}
return list;
}
}
java 导出Excel 大数据量,自己经验总结!(二)的更多相关文章
- java 导出Excel 大数据量,自己经验总结!
出处: http://lyjilu.iteye.com/ 分析导出实现代码,XLSX支持: /** * 生成<span style="white-space: normal; back ...
- java excel大数据量导入导出与优化
package com.hundsun.ta.utils; import java.io.File; import java.io.FileOutputStream; import java.io.I ...
- java导出excel模板数据
Java导出excel数据模板,这里直接贴代码开发,流程性的走下去就是步骤: String[] colName=new String[]{"期间","科目代码" ...
- ASP.NET MVC导出excel(数据量大,非常耗时的,异步导出)
要在ASP.NET MVC站点上做excel导出功能,但是要导出的excel文件比较大,有几十M,所以导出比较费时,为了不影响对界面的其它操作,我就采用异步的方式,后台开辟一个线程将excel导出到指 ...
- MVC学习笔记---MVC导出excel(数据量大,非常耗时的,异步导出)
要在ASP.NET MVC站点上做excel导出功能,但是要导出的excel文件比较大,有几十M,所以导出比较费时,为了不影响对界面的其它操作,我就采用异步的方式,后台开辟一个线程将excel导出到指 ...
- 使用NPOI或POI 导出Excel大数据(百万级以上),导致内存溢出的解决方案(NPOI,POI)
使用工具:POI(JAVA),NPOI(.Net) 致谢博主 Crazy_Jeff 提供的思路 一.问题描述: 导出任务数据量近100W甚至更多,导出的项目就会内存溢出,挂掉. 二.原因分析: 1.每 ...
- Excel大数据量分段导入到Oracle
客户需要将一个具有2W多条数据的Excel表格中的数据导入到Oracle数据库的A表中,开始采用的是利用Oledb直接将数据读入到DataTable中,然后通过拼接InserInto语句来插入到数据库 ...
- Salesforce 大数据量处理篇(二)Index
本篇参考: https://developer.salesforce.com/docs/atlas.en-us.202.0.salesforce_large_data_volumes_bp.meta/ ...
- POI 生成excel(大数据量) SXSSF
使用POI 的SXSSF (Streaming Usermodel API)生成较大的excel,同时开启压缩 import junit.framework.Assert; import org.ap ...
随机推荐
- DS实验题 PlayGame Kruskal(UnionFindSet)
题目: 思路: 有两种做法,一种是Prim算法,另外一种则是我所使用的Kruskal算法,Kruskal的算法实现可以参考:最小生成树-Prim算法和Kruskal算法,讲的已经是十分清楚了. 具体算 ...
- Given a compiled machine-language program, which statements in the source language cause the execution of the most machine-language instructions and what is the execution time of these instr
COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION A variety of studi ...
- MongoShell中的一些命令总结
mongo 127.0.0.1 可以连接到本地的mongo数据库并进入shell exit可以退出shell show dbs 可以查看当前数据库中所有的数据库名称 use [数据库名称] 可以进入指 ...
- C语言 ---- 函数 结构体 iOS学习-----细碎知识点总结
函数的定义 返回值类型 函数名(形式参数列表) { 函数的实现 } 函数不允许嵌套定义 如果函数的定义在主调函数之后,那么要进行提前声明才能使用. // 匿名结构体,结构 ...
- Long型转化成BigDecimal
Long转成带小数的,最好使用BigDecimal,而不是double. 以下例子,是将long型转化成BigDecimal,这样容易保持精度. public class Test { public ...
- SDK开发断点失效
做SDK开发,一般会创建一个静态库工程,然后添加一个app的Target 可是,Xcode7创建的工程,app的Target中断点有效,能断住,为什么静态库的Target中的断点断不住呀. 断点断住发 ...
- easyui datagrid标题列宽度自适应
最近项目中使用easyui做前端界面,相信大部分使用过easyui datagrid的朋友有这么一个疑问:如果在columns中不设置width属性能不能写个方法让datagrid的头部标题和数据主体 ...
- Lua JSONRPC学习笔记
JSON RPC JSON RPC 为利用json数据格式来执行远程调用方式, 作用同xmlrpc,不过与xmlrpc相比, jsonrpc更加轻量,json更加节省数据量,更加可读性高. 官网网站: ...
- HTTPS与强制门户
强制门户 http://www.whatis.com.cn/word_5182.htm 强制网络门户(captive portal)是一个Web页面,它是使用公共访问网络的用户在被授予访问权限前必须访 ...
- 浏览器网页判断手机是否安装IOS/Android客户端程序
IOS 原理如下: 为HTML页面中的超链接点击事件增加一个setTimeout方法. 如果在iPhone上面500ms内,本机有应用程序能解析这个协议并打开程序,则这个回调方法失效: 如果本机没有应 ...