java poi excel 大文件名_POI-处理大Excel文件(xlsx写)

之前介绍了如何读取较大文件的excel文件,但是都无法进行文件的写入操作,在写大文件的情况下就会出现oom

错误模拟

同之前一样,设置heap大小为100m用于模拟,之后创建简单的方法来创建一个大的xlsx

public static void main(String[] args) throws Exception {

// 创建Excel的工作书册 Workbook,对应到一个excel文档

XSSFWorkbook wb = new XSSFWorkbook();

// 创建Excel的工作sheet,对应到一个excel文档的tab

XSSFSheet sheet = wb.createSheet("sheet1");

for (int i = 0; i < 100000; i++) {

// 创建Excel的sheet的一行

XSSFRow row = sheet.createRow(i);

// 创建一个Excel的单元格

XSSFCell cell = row.createCell(0);

// 给Excel的单元格设置样式和赋值

cell.setCellValue("hello world");

}

FileOutputStream os = new FileOutputStream("d:\\workbook.xlsx");

wb.write(os);

os.close();

}

运行之后就将报出oom

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded

at org.apache.xmlbeans.impl.store.Cur$Locations.(Cur.java:493)

at org.apache.xmlbeans.impl.store.Locale.(Locale.java:168)

at org.apache.xmlbeans.impl.store.Locale.getLocale(Locale.java:242)

at org.apache.xmlbeans.impl.store.Locale.newInstance(Locale.java:593)

at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.newInstance(SchemaTypeLoaderBase.java:198)

at org.apache.poi.POIXMLTypeLoader.newInstance(POIXMLTypeLoader.java:84)

at org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst$Factory.newInstance(Unknown Source)

at org.apache.poi.xssf.usermodel.XSSFRichTextString.(XSSFRichTextString.java:87)

at org.apache.poi.xssf.usermodel.XSSFCell.setCellValue(XSSFCell.java:426)

at blog.excel.WriteXls.main(WriteXls.java:28)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:483)

at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

SXSSF

POI提供了SXSSF的方式可以流式的创建十分大的xlsx文件,SXSSF使用了window的概念,如果数据行已经超出window的范围,那么就无法修改其内容。

这个窗口的大小可以在构造函数中设定new SXSSFWorkbook(int windowSize) 也可以在sheet中设定SXSSFSheet#setRandomAccessWindowSize(int windowSize),其默认值为SXSSFWorkbook.DEFAULT_WINDOW_SIZE(100)。

还要注意SXSSF会创建一些临时文件这个需要在finally中显示地通过调用dispose方法清除,而且临时文件也占用一定硬盘,可以通过wb.setCompressTempFiles(true)设置workbook的临时文件使用压缩来减少硬盘占用。下面是的一个例子:

public static void main(String[] args) {

SXSSFWorkbook wb = null;

try {

wb=new SXSSFWorkbook();

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);

}

}

FileOutputStream out = new FileOutputStream("d://xsxxf.xlsx");

wb.write(out);

out.close();

}catch (Exception ex){

ex.printStackTrace();

} finally {

// 删除临时文件

if(wb!=null){

wb.dispose();

}

}

}

通过上面的操作可以产生大型的xlsx文件。SXXSF可以使用原有的xssf,这里创建一个template.xlsx第一个单元格输入内容

public static void main(String[] args) {

SXSSFWorkbook wb = null;

try {

InputStream is = new FileInputStream("d://template.xlsx");

XSSFWorkbook xwb = new XSSFWorkbook(is);

wb=new SXSSFWorkbook(xwb);

Sheet sh = wb.getSheet("Sheet1");

System.out.println(sh.getRow(0));

}catch (Exception ex){

ex.printStackTrace();

} finally {

// 删除临时文件

if(wb!=null){

wb.dispose();

}

}

}

--------------输出---------------

null

这里取出的第一行是null,无法读取原文件,但是可以追加文件

public static void main(String[] args) {

SXSSFWorkbook wb = null;

try {

InputStream is = new FileInputStream("d://template.xlsx");

XSSFWorkbook xwb = new XSSFWorkbook(is);

wb=new SXSSFWorkbook(xwb);

Sheet sh = wb.getSheet("Sheet1");

for (int rownum =1; rownum < 1000000; rownum++) {//这里必须从template之后的行开始写,不然会报出“Attempting to write a row[X] in the range [X,X] that is already written to disk.”

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);

}

}

FileOutputStream out = new FileOutputStream("d://xsxxf.xlsx");

wb.write(out);

out.close();

}catch (Exception ex){

ex.printStackTrace();

} finally {

// 删除临时文件

if(wb!=null){

wb.dispose();

}

}

}

总结

SXSSF可以解决写大文件的问题,但是无法进行修改文件原有的内容,也不支持读源文件。如果需要,可以结合之前的读大文件,然后将读到的内容通过SXSSF写入新的文件,来达到类似修改的操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用以下代码来设置导出的 Excel 文件名: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class ExcelExportUtil { public static void exportToExcel(HttpServletResponse response) throws IOException { // 创建工作簿 Workbook workbook = new XSSFWorkbook(); // 创建工作表 Sheet sheet = workbook.createSheet("Sheet1"); // 创建单元格样式 CellStyle style = workbook.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); // 创建第一行并设置列名 Row headerRow = sheet.createRow(0); Cell cell = headerRow.createCell(0); cell.setCellValue("Column1"); cell.setCellStyle(style); // ... 添加更多的列 // 设置响应头信息 response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setHeader("Content-Disposition", "attachment; filename=\"filename.xlsx\""); // 将工作簿入响应流中 workbook.write(response.getOutputStream()); // 关闭工作簿 workbook.close(); } } ``` 在上述代码中,首先创建了一个 XSSFWorkbook 对象作为工作簿,然后创建一个工作表,并设置单元格样式和列名。接下来,设置响应头信息,包括响应类型和文件名。最后,将工作簿入 HttpServletResponse 的输出流中,并关闭工作簿。 请注意,上述代码中的文件名为 "filename.xlsx",您可以根据实际需求修改为您想要的文件名

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值