POI 海量数据/大数据文件生成SXSSFWorkbook使用简介

  在之前我们知道处理xls的excel用的workbook是HSSFWorkbook,处理xlsx的excel用的是XSSFWorkbook。

  上面两个类导出excel的时候数据会驻留在内存中,所以当数据量大的时候容易造成内存溢出。SXSSFWorkbook是用来生成海量excel数据文件,主要原理是借助临时存储空间生成excel。POI要求3.8以上,生成的文件格式要求是07及以上版本,因为excel07级以上版本的行数1048576,量很大,而03版本的只有6万多。

  读取07及以上版本的excel仍然是“XSSFWorkbook”,写入则为“SXSSFWorkbook ”。

导出的代码:(一个简单的测试,如果想封装工具类,参考:https://www.cnblogs.com/qlqwjy/p/9974212.html)

复制代码
package cn.xm.exam.utils;

import java.io.File;
import java.io.FileOutputStream;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

public class SXSSFExcelUtil {
    public static void main(String[] args) {
        String[] title = { "id", "name", "sex" };
        // 创建一个工作簿
        Workbook workbook = new SXSSFWorkbook();
        // 创建一个工作表sheet
        Sheet sheet = workbook.createSheet();
        // 创建第一行
        Row row = sheet.createRow(0);
        // 创建一个单元格
        Cell cell = null;
        // 创建表头
        for (int i = 0; i < title.length; i++) {
            cell = row.createCell(i);
            cell.setCellValue(title[i]);
        }
        // 从第二行开始追加数据
        for (int i = 1; i <= 10000; i++) {
            // 创建第i行
            Row nextRow = sheet.createRow(i);
            // 参数代表第几列
            Cell cell2 = nextRow.createCell(0);
            cell2.setCellValue("a" + i);
            cell2 = nextRow.createCell(1);
            cell2.setCellValue("user" + i);
            cell2 = nextRow.createCell(2);
            cell2.setCellValue("男");
        }
        // 创建一个文件
        File file = new File("G:/tt1.xls");
        try {
            file.createNewFile();
            // 打开文件流
            FileOutputStream outputStream = new FileOutputStream(file);
            workbook.write(outputStream);
            outputStream.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}
复制代码

 

 

 补充:SXFFSWoorkbook导出的excel相比于XSSFWoorkbook导出的更节省空间:

 下面分别是SXXFS\XFFS\HFFS导出上面1万条数据的excel的文件大小:

 

 补充:测试HSSF\XSSF导出的数据占用内存,而SXFFS导出的数据不容易造成内存溢出

数据改为5万条并且写入之后查看内存信息:

 (1)查看XSSF导出的时候占用JVM内存

复制代码
package cn.xm.exam.utils;

import java.io.File;
import java.io.FileOutputStream;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class SXSSFExcelUtil {
    public static void main(String[] args) {
        String[] title = { "id", "name", "sex" };
        // 创建一个工作簿
        Workbook workbook = new XSSFWorkbook();
        // 创建一个工作表sheet
        Sheet sheet = workbook.createSheet();
        // 创建第一行
        Row row = sheet.createRow(0);
        // 创建一个单元格
        Cell cell = null;
        // 创建表头
        for (int i = 0; i < title.length; i++) {
            cell = row.createCell(i);
            cell.setCellValue(title[i]);
        }
        // 从第二行开始追加数据
        for (int i = 1; i <= 50000; i++) {
            // 创建第i行
            Row nextRow = sheet.createRow(i);
            // 参数代表第几列
            Cell cell2 = nextRow.createCell(0);
            cell2.setCellValue("a" + i);
            cell2 = nextRow.createCell(1);
            cell2.setCellValue("user" + i);
            cell2 = nextRow.createCell(2);
            cell2.setCellValue("男");
        }
        // 创建一个文件
        File file = new File("G:/tt1.xls");
        try {
            file.createNewFile();
            // 打开文件流
            FileOutputStream outputStream = new FileOutputStream(file);
            workbook.write(outputStream);
            outputStream.close();
            // dispose of temporary files backing this workbook on disk
//            ((SXSSFWorkbook) workbook).dispose();
            System.out.println("创建完成");
            System.out.println("总的内存->" + Runtime.getRuntime().totalMemory() / 1024 / 1024 + "MB");
            System.out.println("剩余的内存->" + Runtime.getRuntime().freeMemory() / 1024 / 1024 + "MB");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}
复制代码

结果:

创建完成
总的内存->883MB
剩余的内存->550MB

 

 (2)查看SXSSF导出的时候占用JVM内存

将上面XSSF改为SXFFS查看结果:

创建完成
总的内存->182MB
剩余的内存->175MB

 

posted @   QiaoZhi  阅读(10954)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示