本人菜鸟一个,最近做一个数据分析的项目,要导出大量的数据到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导入时内存溢出问题而编写的Excel行级解析器。同时支持Excel-2003和Excel-2007,excel-2003解析采用poi的eventusermodel模式实现,2007采用xmlreader实现,经项目验证,...
poi读取大量数据会造成gc内存溢出的报错,由于垃圾回收机制无法将大量的对象及时的回收,而这些对象又会保存在内存中,会导致内存不够用的情况,这时候我们就需要使用新的方法,读取为cvs即可.此解决方案可支持千万数据的...
在Java开发中,当面临大批量数据导出到Excel文件时,可能会遇到内存溢出的问题。这是因为Excel文件格式本身的设计,以及Java默认处理大数据的方式,可能导致内存占用过高,尤其是在一次性加载大量数据到内存中进行...
一个POI导出Excel万级数据分页实现 解决内存溢出问题 完整的 project demo 有数据库dmp文件
由于Excel文件可能非常大,直接在内存中加载所有数据可能导致内存溢出。因此,项目可能采用了流式处理或者分批读取数据的方式,减少内存占用。此外,还可以利用SXSSFWorkbook(POI的一个子类)进行低内存使用,因为...
<groupId>org.apache.poi <artifactId>poi-ooxml <version>3.10-FINAL 利用3.10-FINAL版本的poi,导出逻辑主要在FileDownloadUtils的createExcelFile方法
大量数据导出时,一次性加载到内存可能导致内存溢出。为解决这个问题,可以采用流式处理(Streaming User Model)或分批处理。例如,使用SXSSF(Streaming Usermodel API)可以避免一次性加载所有数据,它会在磁盘...
在实际应用中,我们还需要考虑性能优化,比如使用PreparedStatement防止SQL注入,批量插入数据以减少数据库交互次数,以及合理设置内存缓冲大小以避免内存溢出。此外,为了提供良好的用户体验,我们还可以添加错误...
1. 使用SXSSFWorkbook:对于大数据量的导出,可以使用SXSSFWorkbook,它支持内存溢出优化,只在内存中存储有限行数的数据。 2. 分批次写入:如果数据量过大,可分批次读取和写入,减少一次性内存占用。 六、异常...
总结来说,这个文档示例了如何使用Apache POI的SXSSF API高效地处理大量数据的Excel导出,避免内存溢出问题,同时提供了自定义样式以增强导出文件的视觉效果。在处理大数据时,这样的方法是必要的,因为它允许程序在...
从http://download.csdn.net/detail/whatismvc/3696185 和http://download.csdn.net/detail/whatismvc/3694229 下载的, 处理大数据量的Excel 2007文件不内存溢出,我试过的最大数据是 26000行,222列的xlsx。
此外,注意处理异常情况,如文件不存在、权限问题、内存溢出等。在导入时,还要考虑数据验证,如类型检查、格式验证等。在导出时,考虑到性能问题,如果数据量大,可以考虑分批写入或异步处理。 在提供的“java-...
"poi大数据导出20万没内存溢出过.pdf"的标题表明了这个示例是关于如何使用SXSSF来避免内存溢出问题并处理大数据量导出的。 1. **SXSSFWorkbook**:这是SXSSF的工作簿实现,它只保留最近使用的100行数据在内存中,...
本资源提供的 poi 多 sheet 导出工具类和实例,旨在解决这个问题,特别是当数据量超过 20 万行时的高效导出策略。 1. **多 Sheet 导出**: 在 Apache POI 中,我们可以使用 `XSSFWorkbook` 类来创建一个新的 Excel...
这通常涉及到优化内存使用、分批处理和多线程技术,以避免因数据量过大导致的性能问题或内存溢出。 标签中的“poi”代表Apache POI项目,“excel”表示与Microsoft Excel文件格式相关的操作,“大数据”意味着此...
java操作poi2007导出excel数据,解决内存溢出问题
poi导入、导出,支持百万级数据模板导出、合并excel。项目为spring-boot-2上开发。resource里面有模板,在junit...注意此版本不支持分页导出,一次性导出大批量数据也会出现内存溢出问题,最新上传的版本支持分页导出,
当数据量大时,可以使用`SXSSFWorkbook`,它提供了内存优化功能,防止内存溢出。 ```java SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(100); // 保留100行内存,其余写入磁盘 // ... 创建工作表、行、...
然而,对于大数据量导出,这两种方式都可能导致内存问题。相反,SXSSFWorkbook(Streaming Usermodel API)是为处理大文件而设计的,它会将部分数据存储在磁盘上,而不是全部保留在内存中。 3. **使用SXSSF的工作...