java如何将大批量数据导成excel 工程需要导出百万条数据到excel,但是大概在6W条数据的时候就崩掉了,请各位大神帮忙下,提个可行性方法,最好能有代码例子。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 xls吧用的什么操作excel?POI?试试分sheet来导 我们以前导出大批量数据到excel中的时候,分页查询用流输出,循环导入到excel中,知道没有数据。不过导入到excel要注意一个问题,excel的一个sheet最多能放65536行数据,在导出的时候要注意分sheet 1.xls 一个sheet有行数限制 最多是 65536, 所以如果你一定要用xls的话 那当行数超过这个限制的时候你需要分sheet2.xlsx 也是有限制的 好像是150万左右3.如果你的数据不会超150万建议导出到csv 然后用可以用excel 2007+打开 更正:xlsx的行数上限是 1048576 内存溢出怎么解决,虽然有sheet,但是jxl的write只能执行一次,也就是说,只能在最后才可以write.但是内存没办法存放那么多数据。 先查询出满足条件的总数据条数在每次查询出6w分别写入sheet 这么大的数据 如果没有其他的业务转化(java介入),就直接使用数据库能提供的方式来解决 如果需要用java来介入的,可以使用JDBC批量处理 怎么分别写入,write只能执行一次,执行之后就失去效果了,所以虽然每查询6W写入sheet,但是数据还是放在缓存里面啊, 我写个8-9W分页什么的,轻轻松松的,但是40-50W就connect time out 了 跟什么连接超时了? 你实再要导成XLS格式的,只能分批执行。 数据太大内在溢出的话,可以导成多个文件。就不存在write完不好操作的问题。要是实再要导成一个文件多个sheet中的话。那每6w数据写一次。完了。再打开它,操作它的下一个sheet。 在6w的時候,什麽崩潰了?outofmemory? public class AssociatorExcelOrWordAction extends QueryRestrictedAction<UserInfo> { private List<UserInfo> associatorLi = new ArrayList<UserInfo>(); public String execute() throws Exception { HttpServletResponse response = ServletActionContext.getResponse(); OutputStream os = new FileOutputStream("F:\\ceshi.xls" ); String un = getParam("un"); String ph = getParam("ph"); String downtype = getParam("downtype"); String email = getParam("email"); String minDate = getParam("minDate"); String maxDate = getParam("maxDate"); List<String[]> data = null; // 导出数据 List<String> title = new ArrayList<String>(); // 导出EXCEL 标题 QueryUserEvt queryEvt = new QueryUserEvt(); if (null != un && !"".equals(un)) { queryEvt.setNickname(un); } if (null != ph && !"".equals(ph)) { queryEvt.setPhoneNumber(ph); } if(null != email && !"".equals(email)){ queryEvt.setEmail(email); } if (null != minDate && !"".equals(minDate)) { queryEvt.setMinCreateDate(DateUtil.getZoneHour(DateUtil.stringConvertDate(DateUtil.SHORT_FORMAT_PATTERN, minDate))); } if (null != maxDate && !"".equals(maxDate)) { queryEvt.setMaxCreateDate(DateUtil.getZoneHour(DateUtil.stringConvertDate(DateUtil.SHORT_FORMAT_PATTERN, maxDate))); } queryEvt.setQueryType(QueryType.QUERY_NUM.getValue()); int count = ServiceFactory.getUserService().queryUser(queryEvt).getRecordSum(); title.add("用户ID"); title.add("昵称"); title.add("手机号码"); title.add("邮箱"); title.add("注册时间"); int length = count/30000; if(count%30000>0){ length++; } int num = 0; WritableWorkbook book = Workbook.createWorkbook(os);// 生成Excel文件 Label label = null; for (int i = 0; i <length; i++) { data = ServiceFactory.getUserService().queryExportUser(queryEvt,i*30000+1,(i+1)*30000); if (data == null || data.size() == 0) { return "download"; }else{ if (os != null) { WritableSheet ws = null; try { if (title == null || title.size() == 0) { return "download"; } ws = book.createSheet("会员记录"+num, num); num++; // 添加标题 for (int j = 0; j < title.size(); j++) { label = new Label(j, 0, title.get(j), getHeaderCellStyle()); ws.addCell(label); if (j == 5) { ws.setColumnView(j, 70); } else { ws.setColumnView(j, 20); } } // 添加excel数值 int flag = 1; for (String[] temp : data) { for (int j = 0; j < temp.length; j++) { label = new Label(j, flag, temp[j]); ws.addCell(label); } flag++; } os.flush(); } catch (IOException e) { e.printStackTrace(); } catch (RowsExceededException e) { e.printStackTrace(); } catch (WriteException e) { e.printStackTrace(); } }else{ return "download"; } } //exportExcel(os, data, title,num); } book.write(); book.close(); os.close(); return "download"; } private WritableCellFormat getHeaderCellStyle() { /* * WritableFont.createFont("宋体"):设置字体为宋体 10:设置字体大小 * WritableFont.BOLD:设置字体加粗(BOLD:加粗 NO_BOLD:不加粗) false:设置非斜体 * UnderlineStyle.NO_UNDERLINE:没有下划线 */ WritableFont font = new WritableFont(WritableFont.createFont("宋体"), 11, WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE); WritableCellFormat headerFormat = new WritableCellFormat( NumberFormats.TEXT); try { // 添加字体设置 headerFormat.setFont(font); // 设置单元格背景色:表头为黑色 headerFormat.setBackground(Colour.YELLOW); // 设置表头表格边框样式 // 整个表格线为粗线、黑色 headerFormat.setBorder(Border.ALL, BorderLineStyle.THICK, Colour.BLACK); // 表头内容水平居中显示 headerFormat.setAlignment(Alignment.CENTRE); } catch (WriteException e) { e.printStackTrace(); } return headerFormat; } public InputStream getInputStream() throws Exception{ return new FileInputStream(new File("F:\\ceshi.xls")); } public List<UserInfo> getAssociatorLi() { return associatorLi; } public void setAssociatorLi(List<UserInfo> associatorLi) { this.associatorLi = associatorLi; }}求解 操作excel能否定位到具体的某一行?是否可以定位第1到第10w然后定位第10w零1到20w行以此类推分成多段 分批导入 例如 第一个方法(){ 读1到10w 然后插入数据库} 第二个方法()(){ 读10w零1到20w 然后插入数据库} 03版的也就是以xls结尾的最多是65536行数据,07版xlsx是1048576。这也就是为什么你导出到6w多的时候会报错了。所以你需要分开导出。怎么分开,有两类方法。1.按照类别来,比如月份、日期、部门等分类,但是也会出现一个月份超出65536的情况。2.就按照行数来,超出65536的就用下一个sheet来导出。这个在函数中很好实现的,一个for搞定。所以,楼主,就不需要纠结了。 03版的excle确实是有数量限制的,要是放到多个文件中能行不 请看代码,我已经分开多个sheet导了,但是数据量超过20W的时候还是会出错 ajax向servlet传递参数问题 请问extjs的textarea为什么会布局错乱 Java内存分配问题 webservice 问题 关于keel Framework三种核心模式的问题 配置连接池问题 请各位给些思路(对局域网内即时聊天工具监测) 急急求助! 急急急!!! multipartfile 强转 file 使用<generator class="native"></generator>native居然无法创建表格 什么原因非常奇怪?? 怎样用JAVA代码实现将远程服务器的文件拷到本地文件
用的什么操作excel?POI?
试试分sheet来导
不过导入到excel要注意一个问题,excel的一个sheet最多能放65536行数据,在导出的时候要注意分sheet
2.xlsx 也是有限制的 好像是150万左右
3.如果你的数据不会超150万建议导出到csv 然后用可以用excel 2007+打开
更正:xlsx的行数上限是 1048576
但是内存没办法存放那么多数据。
在每次查询出6w分别写入sheet
如果需要用java来介入的,可以使用JDBC批量处理
public class AssociatorExcelOrWordAction extends QueryRestrictedAction<UserInfo> { private List<UserInfo> associatorLi = new ArrayList<UserInfo>();
public String execute() throws Exception { HttpServletResponse response = ServletActionContext.getResponse();
OutputStream os = new FileOutputStream("F:\\ceshi.xls" );
String un = getParam("un");
String ph = getParam("ph");
String downtype = getParam("downtype");
String email = getParam("email");
String minDate = getParam("minDate");
String maxDate = getParam("maxDate");
List<String[]> data = null; // 导出数据 List<String> title = new ArrayList<String>(); // 导出EXCEL 标题 QueryUserEvt queryEvt = new QueryUserEvt(); if (null != un && !"".equals(un)) {
queryEvt.setNickname(un);
}
if (null != ph && !"".equals(ph)) {
queryEvt.setPhoneNumber(ph);
}
if(null != email && !"".equals(email)){
queryEvt.setEmail(email);
}
if (null != minDate && !"".equals(minDate)) {
queryEvt.setMinCreateDate(DateUtil.getZoneHour(DateUtil.stringConvertDate(DateUtil.SHORT_FORMAT_PATTERN, minDate)));
}
if (null != maxDate && !"".equals(maxDate)) {
queryEvt.setMaxCreateDate(DateUtil.getZoneHour(DateUtil.stringConvertDate(DateUtil.SHORT_FORMAT_PATTERN, maxDate)));
}
queryEvt.setQueryType(QueryType.QUERY_NUM.getValue());
int count = ServiceFactory.getUserService().queryUser(queryEvt).getRecordSum();
title.add("用户ID");
title.add("昵称");
title.add("手机号码");
title.add("邮箱");
title.add("注册时间");
int length = count/30000;
if(count%30000>0){
length++;
}
int num = 0;
WritableWorkbook book = Workbook.createWorkbook(os);// 生成Excel文件
Label label = null;
for (int i = 0; i <length; i++) {
data = ServiceFactory.getUserService().queryExportUser(queryEvt,i*30000+1,(i+1)*30000);
if (data == null || data.size() == 0) {
return "download";
}else{
if (os != null) {
WritableSheet ws = null;
try {
if (title == null || title.size() == 0) {
return "download";
}
ws = book.createSheet("会员记录"+num, num);
num++;
// 添加标题
for (int j = 0; j < title.size(); j++) {
label = new Label(j, 0, title.get(j),
getHeaderCellStyle());
ws.addCell(label);
if (j == 5) {
ws.setColumnView(j, 70);
} else {
ws.setColumnView(j, 20);
} } // 添加excel数值
int flag = 1;
for (String[] temp : data) {
for (int j = 0; j < temp.length; j++) {
label = new Label(j, flag, temp[j]);
ws.addCell(label);
}
flag++;
}
os.flush();
} catch (IOException e) {
e.printStackTrace();
} catch (RowsExceededException e) {
e.printStackTrace();
} catch (WriteException e) {
e.printStackTrace();
}
}else{
return "download";
}
}
//exportExcel(os, data, title,num);
}
book.write();
book.close();
os.close();
return "download";
}
private WritableCellFormat getHeaderCellStyle() { /*
* WritableFont.createFont("宋体"):设置字体为宋体 10:设置字体大小
* WritableFont.BOLD:设置字体加粗(BOLD:加粗 NO_BOLD:不加粗) false:设置非斜体
* UnderlineStyle.NO_UNDERLINE:没有下划线
*/
WritableFont font = new WritableFont(WritableFont.createFont("宋体"), 11,
WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE); WritableCellFormat headerFormat = new WritableCellFormat(
NumberFormats.TEXT);
try {
// 添加字体设置
headerFormat.setFont(font);
// 设置单元格背景色:表头为黑色
headerFormat.setBackground(Colour.YELLOW);
// 设置表头表格边框样式
// 整个表格线为粗线、黑色
headerFormat.setBorder(Border.ALL, BorderLineStyle.THICK,
Colour.BLACK);
// 表头内容水平居中显示
headerFormat.setAlignment(Alignment.CENTRE);
} catch (WriteException e) {
e.printStackTrace();
}
return headerFormat;
}
public InputStream getInputStream() throws Exception{
return new FileInputStream(new File("F:\\ceshi.xls"));
}
public List<UserInfo> getAssociatorLi() {
return associatorLi;
}
public void setAssociatorLi(List<UserInfo> associatorLi) {
this.associatorLi = associatorLi;
}
}
求解
读1到10w
然后插入数据库
}
第二个方法()(){
读10w零1到20w
然后插入数据库
}
这也就是为什么你导出到6w多的时候会报错了。
所以你需要分开导出。
怎么分开,有两类方法。
1.按照类别来,比如月份、日期、部门等分类,但是也会出现一个月份超出65536的情况。
2.就按照行数来,超出65536的就用下一个sheet来导出。这个在函数中很好实现的,一个for搞定。
所以,楼主,就不需要纠结了。
请看代码,我已经分开多个sheet导了,但是数据量超过20W的时候还是会出错