zoukankan      html  css  js  c++  java
  • 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导出的更节省空间:

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

     补充:测试HSSFXSSF导出的数据占用内存,而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

  • 相关阅读:
    这是一篇通过open live writer发布的博文
    网卡重启失败
    2020年1月目标
    二、安装docker
    JS中的数据类型,包含ES6,set和map等等
    关于prototype和__proto__,最好的一些解释
    JS中call,apply和bind方法的区别和使用场景
    ThinkPHP5生成word文档代码库
    js/jquery操作iframe
    PHP技术--思维导图
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/10188076.html
Copyright © 2011-2022 走看看