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

  • 相关阅读:
    oracle 导入数据时提示只有 DBA 才能导入由其他 DBA 导出的文件
    oracle 常用语句
    android udp 无法收到数据 (模拟器中)
    android DatagramSocket send 发送数据出错
    AtCoder ABC 128E Roadwork
    AtCoder ABC 128D equeue
    AtCoder ABC 127F Absolute Minima
    AtCoder ABC 127E Cell Distance
    CodeForces 1166E The LCMs Must be Large
    CodeForces 1166D Cute Sequences
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/10188076.html
Copyright © 2011-2022 走看看