本人菜鸟一个,最近做一个数据分析的项目,要导出大量的数据到EXCEL表格中,一开始数据导入的时间就报了内存错误,跟客户沟通改为CSV格式才解决。后来又要导出数据,这内存占用更不得了,才20000行就不行了,于是网上找各种解决方法,但都没合适的。
后看到SXSSFWorkbook可以进行批量导出,但不能读取,国为内存中这些数据已经不存在了,但国为表格结构比较复杂,数据也比较杂乱,有时需要用到刚生成的数据,于是想方法建了几个类mysheet,myrow,mycell,参照POI这几个类自定义几个属性方法,将所有数据都封装到自己的mysheet中,最后统一导出,结果感觉还是很满意的,速度很快,内存的问题也没了。
第一次写点东西,语无伦次了,哈哈,记录点是一点。
package com.yt.xcdata.pojo; import java.util.ArrayList; import java.util.List; public class MySheet { /** * 表格名 */ private String sheetName; /** * 表格顺序索引 */ private int sheetIndex; /** * 最后一行 */ private int lastRowNum; /** * 第一行 */ private int firstRowNum = 0; /** * 所有行 */ private List<MyRow> rowList = new ArrayList<MyRow>(); public String getSheetName() { return sheetName; } public void setSheetName(String sheetName) { this.sheetName = sheetName; } public int getSheetIndex() { return sheetIndex; } public void setSheetIndex(int sheetIndex) { this.sheetIndex = sheetIndex; } public int getLastRowNum() { return lastRowNum; } public void setLastRowNum(int lastRowNum) { this.lastRowNum = lastRowNum; } public int getFirstRowNum() { return firstRowNum; } public void setFirstRowNum(int firstRowNum) { this.firstRowNum = firstRowNum; } public MyRow getRow(int rowIndex) { return this.rowList.get(rowIndex); } public MyRow createRow(int rowIndex) { MyRow r = new MyRow(rowIndex,this); this.rowList.add(r); this.lastRowNum = rowList.size(); return r; } }
package com.yt.xcdata.pojo; import java.util.ArrayList; import java.util.List; public class MyRow { /** * 行索引 */ private int rowIndex; /** * 行高 */ private short height; /** * 第一列 */ private int firstCellNum = 0; /** * 最后一列 */ private int lastCellNum; /** * 所属表格 */ private MySheet sheet; /** * 所有单元格 */ private List<MyCell> cellList = new ArrayList<MyCell>(); public MyRow(int rowIndex, MySheet sheet) { this.rowIndex = rowIndex; this.sheet = sheet; } public short getHeight() { return height; } public void setHeight(short height) { this.height = height; } public int getFirstCellNum() { return firstCellNum; } public void setFirstCellNum(int firstCellNum) { this.firstCellNum = firstCellNum; } public int getLastCellNum() { return lastCellNum; } public void setLastCellNum(int lastCellNum) { this.lastCellNum = lastCellNum; } public int getRowNum() { return rowIndex; } public void setRowIndex(int rowIndex) { this.rowIndex = rowIndex; } public MyCell getCell(int cellIndex) { return this.cellList.get(cellIndex); } public MyCell createCell(int cellIndex) { MyCell c = new MyCell(cellIndex,this); this.cellList.add(c); this.lastCellNum = cellList.size(); return c; } public MySheet getSheet() { return sheet; } }
package com.yt.xcdata.pojo; import org.apache.poi.ss.usermodel.CellStyle; public class MyCell { /** * 除运算时,分母为0 */ public static final int INFINITY = 1; /** * 除运算时,分子大于分母(异常) */ public static final int UNUSUAL = 2; /** * 列索引 */ private int columnIndex; /** * 单元格字符串 */ private String stringCellValue; /** * 单元格数据 */ private double doubleCellValue; /** * 单元格样式 */ private CellStyle cellStyle = null; /** * 所属行 */ private MyRow row; /** * 所属表格 */ private MySheet sheet; /** * 错误类型 */ private int errorType = 0; public MyCell(int columnIndex, MyRow row){ this.columnIndex = columnIndex; this.row = row; } public CellStyle getCellStyle() { return cellStyle; } public void setCellStyle(CellStyle cellStyle) { this.cellStyle = cellStyle; } public int getColumnIndex() { return columnIndex; } public String getStringCellValue() { return stringCellValue; } public double getNumbericCellValue() { return doubleCellValue; } public void setCellValue(String cellValue){ this.stringCellValue = cellValue; } public void setCellValue(double cellValue){ this.doubleCellValue = cellValue; } public MyRow getRow() { return row; } public MySheet getSheet() { return sheet; } public int getErrorType() { return errorType; } public void setErrorType(int errorType) { this.errorType = errorType; } }
可以自己定制需要的属性 ,目前项目足够用了
用SXSSFWorkbook(3.8版才有)导出数据时,如果要用定义好的模板可以用
public SXSSFWorkbook(XSSFWorkbook workbook, int rowAccessWindowSize)
先将模板处理好,再调用该方法
.
.
.
.
.
.
sheet = book.getSheet(SheetNames.SALE_SHEET_CYCLETYPE_DEALER); Map<String,CellStyle> listStyle = CellStyleHelper.getCellStyles(book); for(int i = copyMyRow.getRowNum(); i < mysheet.getLastRowNum();i++){ MyRow tempR = mysheet.getRow(i); Row newRow = sheet.createRow(i); newRow.setHeight((short)350); for(int j = 0;j < copyMyRow.getLastCellNum();j++){ MyCell tempC = tempR.getCell(j); Cell newCell = newRow.createCell(j); if(i == mysheet.getLastRowNum() - 1){ if(j>=0 && j < 4){ newCell.setCellStyle(listStyle.get("bold_background")); }else{ newCell.setCellStyle(listStyle.get("background")); } }else{ if(j>=0 && j < 4){ newCell.setCellStyle(listStyle.get("bold")); }else{ newCell.setCellStyle(listStyle.get("border")); } } if(tempC.getStringCellValue() == null){ newCell.setCellValue(tempC.getNumbericCellValue()); }else{ if(tempC.getErrorType() == MyCell.INFINITY){ newCell.setCellStyle(listStyle.get("INFINITY")); }else if(tempC.getErrorType() == MyCell.UNUSUAL){ newCell.setCellStyle(listStyle.get("UNUSUAL")); } newCell.setCellValue(tempC.getStringCellValue()); } } } for(CellRangeAddress c : listCra){ sheet.addMergedRegion(c); }