POI之SXSSFWorkbook大量数据导出至excel

一:简介

          SXSSFWorkbook是用来生成海量excel数据文件,主要原理是借助临时存储空间生成excel,
          SXSSFWorkbook专门处理大数据,对于大型excel的创建且不会内存溢出的,就只有SXSSFWorkbook了。
          它的原理很简单,用硬盘空间换内存(就像hashmap用空间换时间一样)。 SXSSFWorkbook是streaming
          版本的XSSFWorkbook,它只会保存最新的excel rows在内存里供查看,在此之前的excel rows都会被写入到
          硬盘里(Windows电脑的话,是写入到C盘根目录下的temp文件夹)。被写入到硬盘里的rows是不可见的/不
          可访问的。只有还保存在内存里的才可以被访问到。 
          注:HSSFWorkbook和XSSFWorkbook的Excel Sheet导出条数上限(<=2003版)是65535行、256列,(>=2007版)
               是1048576行,16384列,如果数据量超过了此上限,那么可以使用SXSSFWorkbook来导出。实际上上万条数据,
               甚至上千条数据就可以考虑使用SXSSFWorkbook了。
        注意:首先需要引入依赖:注意:4.0.0版本的JDK需要1.8以上,如果JDK是1.7的,那么就使用3.9版本的依赖


   
   
   
   
  1. org.apache.poi
  2. poi-ooxml-schemas
  3. 4.0.0
  4. org.apache.poi
  5. poi-ooxml
  6. 4.0.0
  7. org.apache.poi
  8. poi
  9. 4.0.0

二:实例一,我们使用SXSSFWorkbook向Excel中写入50万条数据,只需要         34秒左右,内存占用率最多在700M左右,CPU使用率在25%左右           
        


           代码如下:


   
   
   
   
  1. package com.test.POI;
  2. import java.io.BufferedOutputStream;
  3. import java.io.File;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  8. import org.apache.poi.xssf.streaming.SXSSFRow;
  9. import org.apache.poi.xssf.streaming.SXSSFSheet;
  10. import org.apache.poi.xssf.streaming.SXSSFWorkbook;
  11. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  12. public class SXSSFWORKBookUtils {
  13. @SuppressWarnings( "resource")
  14. public static void main(String[] args) throws FileNotFoundException, InvalidFormatException {
  15. long startTime = System.currentTimeMillis();
  16. String filePath = "E:\\txt\\111.xlsx";
  17. SXSSFWorkbook sxssfWorkbook = null;
  18. BufferedOutputStream outputStream = null;
  19. try {
  20. //这样表示SXSSFWorkbook只会保留100条数据在内存中,其它的数据都会写到磁盘里,这样的话占用的内存就会很少
  21. sxssfWorkbook = new SXSSFWorkbook(getXSSFWorkbook(filePath), 100);
  22. //获取第一个Sheet页
  23. SXSSFSheet sheet = sxssfWorkbook.getSheetAt( 0);
  24. for ( int i = 0; i < 50; i++) {
  25. for ( int z = 0; z < 10000; z++) {
  26. SXSSFRow row = sheet.createRow(i* 10000+z);
  27. for ( int j = 0; j < 10; j++) {
  28. row.createCell(j).setCellValue( "你好:"+j);
  29. }
  30. }
  31. }
  32. outputStream = new BufferedOutputStream( new FileOutputStream(filePath));
  33. sxssfWorkbook.write(outputStream);
  34. outputStream.flush();
  35. sxssfWorkbook.dispose(); // 释放workbook所占用的所有windows资源
  36. } catch (IOException e) {
  37. e.printStackTrace();
  38. } finally {
  39. if(outputStream!= null) {
  40. try {
  41. outputStream.close();
  42. } catch (IOException e) {
  43. e.printStackTrace();
  44. }
  45. }
  46. }
  47. long endTime = System.currentTimeMillis();
  48. System.out.println(endTime-startTime);
  49. }
  50. /**
  51. * 先创建一个XSSFWorkbook对象
  52. * @param filePath
  53. * @return
  54. */
  55. public static XSSFWorkbook getXSSFWorkbook(String filePath) {
  56. XSSFWorkbook workbook = null;
  57. BufferedOutputStream outputStream = null;
  58. try {
  59. File fileXlsxPath = new File(filePath);
  60. outputStream = new BufferedOutputStream( new FileOutputStream(fileXlsxPath));
  61. workbook = new XSSFWorkbook();
  62. workbook.createSheet( "测试Sheet");
  63. workbook.write(outputStream);
  64. } catch (Exception e) {
  65. e.printStackTrace();
  66. } finally {
  67. if(outputStream!= null) {
  68. try {
  69. outputStream.close();
  70. } catch (IOException e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. }
  75. return workbook;
  76. }
  77. }

  效果:
      POI之SXSSFWorkbook大量数据导出至excel_第1张图片

三:我们使用XSSFWorkbook常规的方法分批向excel中写入50万条数据,内         存占用率最多在  2.1个G左右(占用了很大的内存),CPU使用率在90%           左右 ,最后内存 溢出了

          POI之SXSSFWorkbook大量数据导出至excel_第2张图片
          代码如下:
          


   
   
   
   
  1. package com.test;
  2. import java.io.BufferedOutputStream;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileNotFoundException;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  9. import org.apache.poi.xssf.usermodel.XSSFRow;
  10. import org.apache.poi.xssf.usermodel.XSSFSheet;
  11. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  12. public class POIController {
  13. /**
  14. * 这种方式效率比较低并且特别占用内存,数据量越大越明显
  15. * @param args
  16. * @throws FileNotFoundException
  17. * @throws InvalidFormatException
  18. */
  19. public static void main(String[] args) throws FileNotFoundException, InvalidFormatException {
  20. long startTime = System.currentTimeMillis();
  21. BufferedOutputStream outPutStream = null;
  22. XSSFWorkbook workbook = null;
  23. FileInputStream inputStream = null;
  24. String filePath = "E:\\txt\\666.xlsx";
  25. try {
  26. workbook = getWorkBook(filePath);
  27. XSSFSheet sheet = workbook.getSheetAt( 0);
  28. for ( int i = 0; i < 50; i++) {
  29. for ( int z = 0; z < 10000; z++) {
  30. XSSFRow row = sheet.createRow(i* 10000+z);
  31. for ( int j = 0; j < 10; j++) {
  32. row.createCell(j).setCellValue( "你好:"+j);
  33. }
  34. }
  35. //每次要获取新的文件流对象,避免将之前写入的数据覆盖掉
  36. outPutStream = new BufferedOutputStream( new FileOutputStream(filePath));
  37. workbook.write(outPutStream);
  38. }
  39. } catch (IOException e) {
  40. e.printStackTrace();
  41. } finally {
  42. if(outPutStream!= null) {
  43. try {
  44. outPutStream.close();
  45. } catch (IOException e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. if(inputStream!= null) {
  50. try {
  51. inputStream.close();
  52. } catch (IOException e) {
  53. e.printStackTrace();
  54. }
  55. }
  56. if(workbook!= null) {
  57. try {
  58. workbook.close();
  59. } catch (IOException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. }
  64. long endTime = System.currentTimeMillis();
  65. System.out.println(endTime-startTime);
  66. }
  67. /**
  68. * 先创建一个XSSFWorkbook对象
  69. * @param filePath
  70. * @return
  71. */
  72. public static XSSFWorkbook getWorkBook(String filePath) {
  73. XSSFWorkbook workbook = null;
  74. try {
  75. File fileXlsxPath = new File(filePath);
  76. BufferedOutputStream outPutStream = new BufferedOutputStream( new FileOutputStream(fileXlsxPath));
  77. workbook = new XSSFWorkbook();
  78. workbook.createSheet( "测试");
  79. workbook.write(outPutStream);
  80. } catch (Exception e) {
  81. e.printStackTrace();
  82. }
  83. return workbook;
  84. }
  85. }

效果:
   POI之SXSSFWorkbook大量数据导出至excel_第3张图片
        

你可能感兴趣的:(POI)