POI 和 EasyExcel 操作 Excel

一、概述

        目前操作 Excel 比较流行的就是 Apache POI 和阿里巴巴的 easyExcel

1.1 POI 简介

        Apache POI 是用 Java 编写的免费开源的跨平台的 Java APIApache POI 提供 API Java 程序对 Microsoft Office 格式文档读和写的常用功能。POI “Poor Obfuscation Implementation” 的首字母缩写,意为“简洁版的模糊实现”。其常用的结构如下:

        HSSF -- 提供读写 03 版本的 Excel 常用功能。

        XSSF -- 提供读写 07 版本的 Excel 常用功能。

        HWPF -- 提供读写 Word 格式的常用功能

        HSLF -- 提供读写 ppt 格式的常用功能。

        HDGF -- 提供读写 visio 格式的常用功能

1.2 easyExcel 简介

        easyExcel 是阿里巴巴开源的一个 excel 处理框架,以使用简单、节省内存著称。easyExcel 能大大减少占用内存的主要原因是在解析 Excel 时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

        easyExcel 官网地址:https://github.com/alibaba/easyexcel

1.3 xls 和 xlsx 区别

        常用的 excel 文档有两种结尾形式,分别为 xlsxlsx,其中以 xls 结尾的文档属于 03 版本的,它里面最多可以存储 65536 行数据。而以 xlsx 结尾的文档属于 07 版本的,它理论上可以存储无限行数据,这就是两者之前的区别。

二、POI 常用操作

2.1 添加 maven 依赖

    
        
        
            org.apache.poi
            poi
            3.9
        
        
        
            org.apache.poi
            poi-ooxml
            3.9
        
        
        
            joda-time
            joda-time
            2.10.1
        
        
        
            junit
            junit
            4.12
        
    

2.2 写入 Excel 操作

2.2.1 一般文件写入

2.2.1.1 03 版本
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.joda.time.DateTime;
import org.junit.Test;

import java.io.FileOutputStream;

public class ExcelWriteTest {
    String PATH ="F:\\idea_home\\poi-excel\\";

    @Test
    public void testWrite03() throws Exception {
        // 1、创建一个工作簿
        Workbook workbook = new HSSFWorkbook();
        // 2、创建一个工作表
        Sheet sheet = workbook.createSheet("我是 sheet1 页");
        // 3、创建一行
        Row row1  = sheet.createRow(0);
        // 4、创建一个单元格
        Cell cell11 = row1.createCell(0);
        cell11.setCellValue("我是第一行第一个单元格");
        Cell cell12 = row1.createCell(1);
        cell12.setCellValue("我是第一行第二个单元格");

        // 第二行
        Row row2  = sheet.createRow(1);
        Cell cell21 = row2.createCell(0);
        cell21.setCellValue("我是第二行第一个单元格");
        Cell cell22 = row2.createCell(1);
        String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        cell22.setCellValue(time);
        // 03 版本的使用 xls 结尾
        FileOutputStream fileOutputStream  = new FileOutputStream(PATH+"统计表03类型.xls");
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        System.out.println("Excel03 写入完成了");
    }
}

POI 和 EasyExcel 操作 Excel_第1张图片

2.2.2.2 07 版本
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;
import org.joda.time.DateTime;
import org.junit.Test;

import java.io.FileOutputStream;

public class ExcelWriteTest {
    String PATH ="F:\\idea_home\\poi-excel\\";

    @Test
    public void testWrite07() throws Exception {
        // 1、创建一个工作簿
        Workbook workbook = new XSSFWorkbook();
        // 2、创建一个工作表
        Sheet sheet = workbook.createSheet("我是 sheet1 页");
        // 3、创建一行
        Row row1  = sheet.createRow(0);
        // 4、创建一个单元格
        Cell cell11 = row1.createCell(0);
        cell11.setCellValue("我是第一行第一个单元格");
        Cell cell12 = row1.createCell(1);
        cell12.setCellValue("我是第一行第二个单元格");

        // 第二行
        Row row2  = sheet.createRow(1);
        Cell cell21 = row2.createCell(0);
        cell21.setCellValue("我是第二行第一个单元格");
        Cell cell22 = row2.createCell(1);
        String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        cell22.setCellValue(time);
        // 07 版本的使用 xlsx 结尾
        FileOutputStream fileOutputStream  = new FileOutputStream(PATH+"统计表07类型.xlsx");
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        System.out.println("Excel07 写入完成了");
    }
}

2.2.2 大文件写入

2.2.2.1 03 版本
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.junit.Test;

import java.io.FileOutputStream;

public class ExcelWriteTest {
    String PATH ="F:\\idea_home\\poi-excel\\";

    @Test
    public void testWrite03BigData() throws Exception {
        long begin = System.currentTimeMillis();
        // 1、创建一个工作簿
        Workbook workbook = new HSSFWorkbook();
        // 2、创建一个工作表
        Sheet sheet = workbook.createSheet();
        // 3、写入数据
        for(int rowNum =0;rowNum<65537;rowNum++){
            Row row = sheet.createRow(rowNum);
            for(int cellNum=0;cellNum<10;cellNum++){
                Cell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum);
            }
        }
        System.out.println("over");
        FileOutputStream fileOutputStream  = new FileOutputStream(PATH+"统计表03大数据类型.xls");
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        long end = System.currentTimeMillis();
        System.out.println((double)(end-begin)/1000);
    }
}

        缺点:最多只能处理 65536 行,否则会抛出异常。

POI 和 EasyExcel 操作 Excel_第2张图片

        优点:写入过程中写入缓存,不操作磁盘,最后一次性写入磁盘,速度快。将 65537 改成65536 再次执行程序,结果如下,可以看到 1.692s 就完成了写入操作,速度还是很快的。

POI 和 EasyExcel 操作 Excel_第3张图片

2.2.2.2 07 版本
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;
import org.junit.Test;

import java.io.FileOutputStream;

public class ExcelWriteTest {
    String PATH ="F:\\idea_home\\poi-excel\\";
    
    @Test
    public void testWrite07BigData() throws Exception {
        long begin = System.currentTimeMillis();
        // 1、创建一个工作簿
        Workbook workbook = new XSSFWorkbook();
        // 2、创建一个工作表
        Sheet sheet = workbook.createSheet();
        // 3、写入数据
        for(int rowNum =0;rowNum<100000;rowNum++){
            Row row = sheet.createRow(rowNum);
            for(int cellNum=0;cellNum<10;cellNum++){
                Cell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum);
            }
        }
        System.out.println("over");
        FileOutputStream fileOutputStream  = new FileOutputStream(PATH+"统计表07大数据类型.xlsx");
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        long end = System.currentTimeMillis();
        System.out.println((double)(end-begin)/1000);
    }
}

        缺点:写数据时速度非常慢,非常耗内存,也会发生内存溢出,如100万条。

        优点:可以写较大的数据量,如20万条。

POI 和 EasyExcel 操作 Excel_第4张图片

2.2.2.3 07 版本优化
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;
import org.junit.Test;

import java.io.FileOutputStream;

public class ExcelWriteTest {
    String PATH ="F:\\idea_home\\poi-excel\\";

    @Test
    public void testWrite07BigDataS() throws Exception {
        long begin = System.currentTimeMillis();
        // 1、创建一个工作簿
        Workbook workbook = new SXSSFWorkbook();
        // 2、创建一个工作表
        Sheet sheet = workbook.createSheet();
        // 3、写入数据
        for(int rowNum =0;rowNum<100000;rowNum++){
            Row row = sheet.createRow(rowNum);
            for(int cellNum=0;cellNum<10;cellNum++){
                Cell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum);
            }
        }
        System.out.println("over");
        FileOutputStream fileOutputStream  = new FileOutputStream(PATH+"统计表07大数据类型优化.xlsx");
        workbook.write(fileOutputStream);
        // 清除产生的临时文件
        ((SXSSFWorkbook)workbook).dispose();
        fileOutputStream.close();
        long end = System.currentTimeMillis();
        System.out.println((double)(end-begin)/1000);
    }
}

        优点:可以写非常大的数据量,如 100万 条甚至更多条,数据速度快,占用更少的内存。

POI 和 EasyExcel 操作 Excel_第5张图片

        需要注意的是:代码在过程中会产生临时文件,需要清理临时文件。默认有 100 条记录被保存在内存中,如果超过这数量,则最前面的数据被写入临时文件。如果想自定义内存中数据的数量,可以使用 new SXSSFWorkbook(数量) 。

        SXSSFWorkbook 来至官方的解释:实现 “BigGridDemo” 策略的流式 XSSFWorkbook 版本。这允许写入非常大的文件而不会耗尽内存,因为任何时候只有可配置的行部分被保存在内存中。请注意,仍然可能会消耗大量内存,这些内存基于您正在使用的功能,例如合并区域,注释……仍然只存储在内存中,因此如果广泛使用,可能需要大量内存。

你可能感兴趣的:(java,java)