zoukankan      html  css  js  c++  java
  • HSSF与XSSF导出excel文档

    Apache POI

    Apache POI 是用Java编写的免费开源的跨平台的 Java API,它可以创建和维护操作各种符合Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API。

    用它可以使用Java读取和创建,修改MS Excel文件.而且,还可以使用Java读取和创建MS Word和MSPowerPoint文件。Apache POI 提供Java操作Excel解决方案(适用于Excel97-2008)。

    HSSF and XSSF for Excel Documents

    需要以下jar

    <!-- office文档组件 -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>3.9</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>3.9</version>
            </dependency>
            <dependency>
                <groupId>org.apache.xmlbeans</groupId>
                <artifactId>xmlbeans</artifactId>
                <version>2.4.0</version>
            </dependency>

    一、HSSF:支持 excel97—2003之间的,(.xls)

    注意:97—2003excel一个sheet最多65536行。

    创建步骤:

    1、New Workbook//创建一个工作簿

    2、New Sheet//创建一个工作表

    3、createRow//创建一个行

    4、row.createCell(index)//index是指定哪一列

    5、cell.setCellValue(1);//向单元格设置内容

    分析:WriteExcelHSSF 的代码

    是按照上边步骤执行,最后进行写操作。

    测试代码:

     1 package yycg.poi;
     2 
     3 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
     4 import org.apache.poi.ss.usermodel.Cell;
     5 import org.apache.poi.ss.usermodel.Row;
     6 import org.apache.poi.ss.usermodel.Sheet;
     7 import org.apache.poi.ss.usermodel.Workbook;
     8 
     9 import java.io.FileOutputStream;
    10 
    11 /**
    12  * poi测试导出excel文件,数据量大出现内存溢出
    13  */
    14 public class WriteExcelHSSF {
    15     public static void main(String[] args) throws Exception {
    16         //创建一个文件输出 流
    17         FileOutputStream out = new FileOutputStream("d:/workbook.xls");
    18         //创建一个工作薄
    19         Workbook wb = new HSSFWorkbook();
    20         for (int j = 0; j < 11; j++) {
    21             Sheet s = wb.createSheet();//创建一个sheet
    22             wb.setSheetName(j, "sheet"+j);//指定sheet的名称
    23             //xls文件最大支持65536行
    24             for (int rownum = 0; rownum < 65536; rownum++) {//创建行,.xls一个sheet中的行数最大65535
    25                 //创建一行
    26                 Row row = s.createRow(rownum);
    27                 for (int cellnum = 0; cellnum < 10; cellnum++) {//一行创建10个单元格
    28                     // 在行里边创建单元格
    29                     Cell cell = row.createCell(cellnum);
    30                     //向单元格写入数据
    31                     cell.setCellValue(cellnum);
    32                 }
    33             }
    34         }
    35         System.out.println("int .......");
    36         wb.write(out);//输出 文件内容
    37 
    38         try {
    39             Thread.sleep(2000);
    40         }catch (InterruptedException e){
    41             e.printStackTrace();
    42         }
    43         out.close();
    44         System.out.println("创建excel文件成功!。。。。。。。。。。。。");
    45     }
    46 }

    通过执行大数据抛出异常:

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

    内存溢出

    总结:HSSF 在使用将excel数据加载到内容再写磁盘,如果是大数据量操作,会导致内存溢出。

     

    二、XSSF:支持2007以上版本,Excel 2007 OOXML (.xlsx)

    excel文件格式是基于是xml存储,这是与03版本最大的区别。

    XSSF对HSSF性能更好,对内存消耗不高。

     

    可以解决HSSF操作大数据内存溢出问题。

     

    原理:

    在创建XSSFworkbook时需要设置构造函数的参数:

    SXSSFWorkbook wb = new SXSSFWorkbook(-1); //设置为-1,关闭自动写入磁盘时机,由手动进行控制

    SXSSFWorkbook wb = new SXSSFWorkbook(100); //SXSSF设置100表示,只保持100个记录在内存,超过记录则写入磁盘。

    创建workbook的过程和HSSF一样,先后创建workbook、sheet、row、cell

    测试代码如下:

    package yycg.poi;
    
    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.util.CellReference;
    import org.apache.poi.xssf.streaming.SXSSFSheet;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    
    import java.io.FileOutputStream;
    
    public class WriterExcelXSSF1 {
        public static void main(String[] args) throws  Exception{
            //创建一个SXSSFWorkbook
            //关闭自动刷新
            SXSSFWorkbook wb = new SXSSFWorkbook(-1);
            //创建一sheet
            Sheet sheet = wb.createSheet();
            for(int rownum=0;rownum<100000;rownum++){
                //创建一个行
                Row row = sheet.createRow(rownum);
                for (int cellnum=0;cellnum<10;cellnum++){
                    //创建单元格
                    Cell cell = row.createCell(cellnum);
                    //单元格地址
                    String adress = new CellReference(cell).formatAsString();
                    cell.setCellValue(adress);//向单元格中写入数据
                }
                //手动控制行刷新到磁盘的方式
                if (rownum%10000==0){//一万行向磁盘写一次
                    ((SXSSFSheet)sheet).flushRows(100);//保留最后100行并刷新所有其他行
                    //Thread.sleep(1000);
                    System.out.println("写入....");
                    // ((SXSSFSheet)sh).flushRows() is a shortcut for ((SXSSFSheet)sh).flushRows(0),
                    // this method flushes all rows
                }
            }
    
            FileOutputStream out=new FileOutputStream("d:/testxssf.xlsx");
            wb.write(out);//将临时文件合并,写入最终文件
            out.close();
            wb.dispose();
        }
    }
    package yycg.poi;
    
    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.util.CellReference;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    
    public class WriteExcelSXSSF2 {
    
        public static void main(String[] args) throws Throwable {
            SXSSFWorkbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory,
            // exceeding rows will be
            // flushed to disk
            Sheet sh = wb.createSheet();
            for (int rownum = 0; rownum < 1000; 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:/test2222.xlsx");
            wb.write(out);
            out.close();
    
            // dispose of temporary files backing this workbook on disk
            wb.dispose();
        }
    
    }

    通过跟踪发现,使用XSSF在导出大数据时,手动控制进行写磁盘,写在了临时文件中,我的电脑是:

    (C:UsersThinkpadAppDataLocalTemppoi-sxssf-sheet1910970138657434208.xml 该目录有很多临时文件)

    最终待导出完成将临时合并成最终文件写入磁盘。

     

    总结:使用XSSF导出数据,将数据写入内存一部分,超过的则立即写磁盘,所以内存占有量有限不会导致内存溢出。

  • 相关阅读:
    sql面试题
    C#基础(1)
    Java中的冒泡排序(减少比较次数)
    Java中面向对象的分拣存储
    Java中分拣存储的demo
    XML序列化
    C#读取csv文件使用字符串拼接成XML
    Java中HashMap(泛型嵌套)的遍历
    Java 中List 集合索引遍历与迭代器遍历
    java 中的try catch在文件相关操作的使用
  • 原文地址:https://www.cnblogs.com/limn/p/9490653.html
Copyright © 2011-2022 走看看