`
邱红旭
  • 浏览: 8821 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

POI内存溢出问题(导出)

    博客分类:
  • 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);
		}
 

  

 

 

 

分享到:
评论

相关推荐

    大数据Excel操作不会内存溢出POI

    绝对原创,这是我在项目中解决大数据Excel导入时内存溢出问题而编写的Excel行级解析器。同时支持Excel-2003和Excel-2007,excel-2003解析采用poi的eventusermodel模式实现,2007采用xmlreader实现,经项目验证,...

    poi大量数据读取gc内存溢出解决方案

    poi读取大量数据会造成gc内存溢出的报错,由于垃圾回收机制无法将大量的对象及时的回收,而这些对象又会保存在内存中,会导致内存不够用的情况,这时候我们就需要使用新的方法,读取为cvs即可.此解决方案可支持千万数据的...

    java解决大批量数据导出Excel产生内存溢出的方案

    在Java开发中,当面临大批量数据导出到Excel文件时,可能会遇到内存溢出的问题。这是因为Excel文件格式本身的设计,以及Java默认处理大数据的方式,可能导致内存占用过高,尤其是在一次性加载大量数据到内存中进行...

    POI导出Excel万级数据分页实现 解决内存溢出问题

    一个POI导出Excel万级数据分页实现 解决内存溢出问题 完整的 project demo 有数据库dmp文件

    poi多线程大数据导出excel文件.zip

    由于Excel文件可能非常大,直接在内存中加载所有数据可能导致内存溢出。因此,项目可能采用了流式处理或者分批读取数据的方式,减少内存占用。此外,还可以利用SXSSFWorkbook(POI的一个子类)进行低内存使用,因为...

    利用poi导出excel100万行数据不会内存溢出

    &lt;groupId&gt;org.apache.poi &lt;artifactId&gt;poi-ooxml &lt;version&gt;3.10-FINAL 利用3.10-FINAL版本的poi,导出逻辑主要在FileDownloadUtils的createExcelFile方法

    poi导出根据模板导出excel和简单列表导出excel源码

    大量数据导出时,一次性加载到内存可能导致内存溢出。为解决这个问题,可以采用流式处理(Streaming User Model)或分批处理。例如,使用SXSSF(Streaming Usermodel API)可以避免一次性加载所有数据,它会在磁盘...

    使用poi从数据库导出excel表的示例

    在实际应用中,我们还需要考虑性能优化,比如使用PreparedStatement防止SQL注入,批量插入数据以减少数据库交互次数,以及合理设置内存缓冲大小以避免内存溢出。此外,为了提供良好的用户体验,我们还可以添加错误...

    poi 基于excel模板导出功能

    1. 使用SXSSFWorkbook:对于大数据量的导出,可以使用SXSSFWorkbook,它支持内存溢出优化,只在内存中存储有限行数的数据。 2. 分批次写入:如果数据量过大,可分批次读取和写入,减少一次性内存占用。 六、异常...

    poi大数据导出20万没内存溢出过.docx

    总结来说,这个文档示例了如何使用Apache POI的SXSSF API高效地处理大量数据的Excel导出,避免内存溢出问题,同时提供了自定义样式以增强导出文件的视觉效果。在处理大数据时,这样的方法是必要的,因为它允许程序在...

    POI处理大数据量的Excel文件, 不内存溢出

    从http://download.csdn.net/detail/whatismvc/3696185 和http://download.csdn.net/detail/whatismvc/3694229 下载的, 处理大数据量的Excel 2007文件不内存溢出,我试过的最大数据是 26000行,222列的xlsx。

    Java poi 实现excel导入导出

    此外,注意处理异常情况,如文件不存在、权限问题、内存溢出等。在导入时,还要考虑数据验证,如类型检查、格式验证等。在导出时,考虑到性能问题,如果数据量大,可以考虑分批写入或异步处理。 在提供的“java-...

    poi大数据导出20万没内存溢出过.pdf

    "poi大数据导出20万没内存溢出过.pdf"的标题表明了这个示例是关于如何使用SXSSF来避免内存溢出问题并处理大数据量导出的。 1. **SXSSFWorkbook**:这是SXSSF的工作簿实现,它只保留最近使用的100行数据在内存中,...

    poi多sheet页导出工具类和实例 包含多个excel导出

    本资源提供的 poi 多 sheet 导出工具类和实例,旨在解决这个问题,特别是当数据量超过 20 万行时的高效导出策略。 1. **多 Sheet 导出**: 在 Apache POI 中,我们可以使用 `XSSFWorkbook` 类来创建一个新的 Excel...

    POI千万级导入导出EXCEL工具.zip

    这通常涉及到优化内存使用、分批处理和多线程技术,以避免因数据量过大导致的性能问题或内存溢出。 标签中的“poi”代表Apache POI项目,“excel”表示与Microsoft Excel文件格式相关的操作,“大数据”意味着此...

    poi2007导出excel大数据

    java操作poi2007导出excel数据,解决内存溢出问题

    poi_模板导出excel,支持百万级数据模板导出

    poi导入、导出,支持百万级数据模板导出、合并excel。项目为spring-boot-2上开发。resource里面有模板,在junit...注意此版本不支持分页导出,一次性导出大批量数据也会出现内存溢出问题,最新上传的版本支持分页导出,

    java poi导出excel

    当数据量大时,可以使用`SXSSFWorkbook`,它提供了内存优化功能,防止内存溢出。 ```java SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(100); // 保留100行内存,其余写入磁盘 // ... 创建工作表、行、...

    java-poi-excel-导出20万条记录【源代码】

    然而,对于大数据量导出,这两种方式都可能导致内存问题。相反,SXSSFWorkbook(Streaming Usermodel API)是为处理大文件而设计的,它会将部分数据存储在磁盘上,而不是全部保留在内存中。 3. **使用SXSSF的工作...

Global site tag (gtag.js) - Google Analytics