出处:
分析导出实现代码,XLSX⽀持:
/**
* ⽣成XLSX,2007版本的excel,每个sheet⽆6.5W的⾏数限制,但是到了⼀定数量,可能内存溢出, * 次⽅法适合在预计10W以下的数据导出时使⽤,本机测试,14W可以导出。列数量在8列左右 *
* @param fileOut * 输出流
* @param sheetMap
* 要设置的数据信息 * @throws SQLException */
public static void createXSLXByResultSet(OutputStream fileOut, WriteXLSBean... beans) throws SQLException { try {
//重点 Workbook
Workbook wb = new XSSFWorkbook();
for (int i = 0, len = beans.length; i < len; i++) { WriteXLSBean xlsBean = beans[i];
Sheet sheet = wb.createSheet(xlsBean.getSheetName()); ResultSet rs = xlsBean.getRs();
ResultSetMetaData rsmd = rs.getMetaData(); TypeHandlerRegistry tr = BeanContext.tr; Map long t1 = System.currentTimeMillis(); org.apache.poi.ss.usermodel.Row row = sheet .createRow(index); for (int j = 0, numberOfColumns = rsmd.getColumnCount(); j < numberOfColumns; j++) { String key = rsmd.getColumnLabel(j + 1).toLowerCase(); if (th.containsKey(key)) { TypeHandler> type = tr.getTypeHandler(JdbcType .forCode(rsmd.getColumnType(j + 1))); Object obj = type.getResult(rs, key); row.createCell(j).setCellValue(obj == null ? \"\" : obj.toString()); } } System.out.println(index + \" :\" + (System.currentTimeMillis() - t1)); index++; } } //重点 Workbook wb.write(fileOut); } catch (IOException e) { e.printStackTrace(); throw new ServiceRunTimeException(\"⽣产xls⽂档错误\ } finally { } } 在上⾯ 标注了重点的两处,分别是:1.构建⼀个Excel对象 2.将该对象写⼊⼀个OutPutStream ⽽在构建过程中,没有地⽅写⼊OutPutSteam ,也就是说必须在内存中构建整个 Excel,才能进⾏写出操作,在⼤数据量情况下,这样将导致所有数据加载到内存中,⽽不能输出,导致最后 内存溢出。根据运⾏环境不⽤,可能内存溢出的 情况不同根据情况,如果数据量达到10W以上,建议使⽤ 1、多个Excel,每个Excel⼀个Sheet,因为所有Sheet都是Workbook的组成部分。如果不分多个Excel,即使分Sheet也没⽤, 2、每个Excel中列数适中,⽐如: 5W⾏每个Excel档,实现分多次导出和分页查询原理⼀样 3、对多个Excel导出到⼀个临时⽬录,并通过程序压缩,然后提供给客户下载 2003版通过数据库结果存到List中,然后进⾏⽣产:Table 就是List Row 是Map /** * ⽣产xls,2003版本的excel,每个sheet有6.5W的⾏数限制 * * @param fileOut * 输出流,未关闭 * @param sheetMap * 要导出的数据信息 */ public static void createXSLByMap(OutputStream fileOut, Map HSSFWorkbook wb = new HSSFWorkbook(); Set for (Iterator String SheetKey = iterator.next(); Sheet sheet = wb.createSheet(SheetKey); List org.apache.poi.ss.usermodel.Row row = sheet.createRow(i); int j = 0; for (Iterator String cellKey = iterCell.next(); Object obj = cellMap.get(cellKey); row.createCell(j).setCellValue(obj == null ? \"\" : obj.toString()); } } } wb.write(fileOut); } catch (IOException e) { e.printStackTrace(); throw new ServiceRunTimeException(\"⽣产xls⽂档错误\ } finally { } } 新版本 POI+office 2007版本excel可以导出⼏⼗万条⽽不内存溢出,详细见: 导出⼤量数据到 excel 的 xlsx⽂件 static String src=\"abcdefafslfelgtryjukjhgfdadertjDSFGHJKJGHFERTUIOabcdefafslfelgtryjukjhgfdadertjDSFGHJKdertjDSFGHJKJGHFERTUIOabcdefafslfelgtryjukjhgfdadertjDSFGHJKJGHFERTUIO\"; public static void main(String[] args) throws Throwable { SXSSFWorkbook wb = new SXSSFWorkbook(100); // 这⾥100是在内存中的数量,如果⼤于此数量时,会写到硬盘,以避免在内存导致内存溢出 Sheet sh = wb.createSheet(); for (int rownum = 0; rownum < 1000000; rownum++) { Row row = sh.createRow(rownum); for (int cellnum = 0; cellnum < 10; cellnum++) { Cell cell = row.createCell(cellnum); String address = new CellReference(cell).formatAsString(); cell.setCellValue(address+src.substring(rownum%10*10+1, (rownum%10+1)*10)); } } File file = new File(\"F:/aa.xlsx\"); file.createNewFile(); FileOutputStream out = new FileOutputStream(file); wb.write(out); out.close(); } 内存使⽤情况: 根据以上前辈经验,⾃⼰在结果⾃⾝需求考虑,整合出⼀个⼯具。解决了excle表.xls格式⾏数65535⾏的限制。我实现的形式是导出⼀张表,⾥⾯有多页(我是已65000为⼀页) 这⾥是⽤反射来使⽤所有传⼊进⾏的实体的属性的值。这⾥只针对String和基本数据类型。如有⾃⼰定义的类型需要⾃⼰加上。 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