POI内存溢出问题(导出)

本人菜鸟一个,最近做一个数据分析的项目,要导出大量的数据到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);
		}
 

  

 

 

 

你可能感兴趣的:(java,poi)