Apache POI 和 easyExcel

Apache POI是一个用于处理Microsoft Office文档的Java库,支持Excel的HSSF和XSSF格式,以及Word和PowerPoint等。而EasyExcel是阿里巴巴的一个轻量级库,专注于简单易用的读写Excel。本文通过示例展示了如何使用Apache POI进行Excel03和07版本的写操作,以及EasyExcel的大数据读取,适合于Java开发者进行数据导入导出操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Apache POI 

官网:Apache POI - the Java API for Microsoft Documentshttps://poi.apache.org/

基本介绍

        Apache POI  是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”。
        Apache POI  是创建和维护操作各种符合Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API。用它可以使用Java读取和创建,修改MS Excel文件.而且,还可以使用Java读取和创建MS Word和MSPowerPoint文件。Apache POI 提供Java操作Excel解决方案(适用于Excel97-2008)。

功能结构

  • HSSF  - 提供读写Microsoft Excel XLS格式档案的功能。 (Excel 03 版本,行数最多 65536行,文件以 .xls 结尾)
  • XSSF  - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。(Excel 07 版本,行数没有限制,文件以 .xlsx 结尾)
  • HWPF  - 提供读写Microsoft Word DOC格式档案的功能。
  • HSLF  - 提供读写Microsoft PowerPoint格式档案的功能。
  • HDGF  - 提供读Microsoft Visio格式档案的功能。
  • HPBF  - 提供读Microsoft Publisher格式档案的功能。
  • HSMF  - 提供读Microsoft Outlook格式档案的功能。

 Excel 03 版本写操作

public static final String PATH = "D:\\gitProject\\excel-poi\\";

    /**
     * 测试 Excel 03 版本写操作
     */
    @Test
    public void write03versionTest() {
        // 1. 创建工作簿
        Workbook workbook = new HSSFWorkbook();
        // 2. 创建工作表
        Sheet sheet = workbook.createSheet("注册用户统计表");
        // 3. 创建第一行
        Row row = sheet.createRow(0);
        // 4. 创建单元格
        Cell cell1 = row.createCell(0);
        cell1.setCellValue("用户编号");
        Cell cell2 = row.createCell(1);
        cell2.setCellValue("用户姓名");
        Cell time = row.createCell(2);
        time.setCellValue("注册时间");
        // 5. 创建第二行
        Row row1 = sheet.createRow(1);
        Cell cell3 = row1.createCell(0);
        cell3.setCellValue("001");
        Cell cell4 = row1.createCell(1);
        cell4.setCellValue("张三");
        Cell time1 = row1.createCell(2);
        String str1 = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        time1.setCellValue(str1);
        try {
            // 6. 生成一张表(IO流),03 版本是以 .xls 结尾
            FileOutputStream stream = new FileOutputStream(PATH + "注册用户统计表.xls");
            // 7. 输出
            workbook.write(stream);
            // 用try-catch 捕获异常,会自动关闭stream流
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("生成注册用户统计表结束!!!");
    }

Excel 07 版本写操作

public static final String PATH = "D:\\gitProject\\excel-poi\\";
    
/**
     * 测试 Excel 07 版本写操作
     */
    @Test
    public void write07versionTest() {
        // 1. 创建工作簿
        Workbook workbook = new XSSFWorkbook();
        // 2. 创建工作表
        Sheet sheet = workbook.createSheet("注册用户统计表");
        // 3. 创建第一行
        Row row = sheet.createRow(0);
        // 4. 创建单元格
        Cell cell1 = row.createCell(0);
        cell1.setCellValue("用户编号");
        Cell cell2 = row.createCell(1);
        cell2.setCellValue("用户姓名");
        Cell time = row.createCell(2);
        time.setCellValue("注册时间");
        // 5. 创建第二行
        Row row1 = sheet.createRow(1);
        Cell cell3 = row1.createCell(0);
        cell3.setCellValue("001");
        Cell cell4 = row1.createCell(1);
        cell4.setCellValue("张三");
        Cell time1 = row1.createCell(2);
        String str1 = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        time1.setCellValue(str1);
        try {
            // 6. 生成一张表(IO流),07 版本是以 .xlsx 结尾
            FileOutputStream stream = new FileOutputStream(PATH + "注册用户统计表.xlsx");
            // 7. 输出
            workbook.write(stream);
            // 用try-catch 捕获异常,会自动关闭stream流
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("生成注册用户统计表结束!!!");
    }

数据批量导入        

大文件写HSSF
 缺点最多只能处理65536行数据,超出会抛异常
优点速度快,过程中写入缓存,不操作磁盘,最后一次性写入磁盘
大文件写XSSF
 缺点写数据时速度非常慢,非常耗内存,会发生内存溢出,如100万条数据
优点可以写较大的数据量,如20万条数据
大文件写SXSSF
 缺点过程中会产生临时文件,需要清理临时文件
优点可以写非常大的数据量,如100万条数据甚至更多,写数据速度非常快,占用内存更少

 批量导入数据代码 03 版本

    /**
     * 测试 Excel 03 版本大数据写操作
     */
    @Test
    public void write03versionBigDataTest() {
        long start = System.currentTimeMillis();
        // 创建工作簿
        Workbook workbook = new HSSFWorkbook();
        // 创建表
        Sheet sheet = workbook.createSheet("03版本大数据写入表");
        // 创建单元格
        for (int rowNum = 0; rowNum < 65536; rowNum++) {
            Row row = sheet.createRow(rowNum);
            for (int cellNum = 0; cellNum < 10; cellNum++) {
                Cell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum);
            }
        }
        FileOutputStream stream = null;
        try {
            // 生成表
            stream = new FileOutputStream(PATH + "03版本大数据写入表.xls");
            // 写入
            workbook.write(stream);

        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("03版本大数据写入表完成!!!");
        System.out.println("耗时时间:{}" + ((double) System.currentTimeMillis() - start) / 1000 + "秒");
    }

 批量导入数据代码 07 版本

    /**
     * 测试 Excel 07 版本大数据写操作
     */
    @Test
    public void write07versionBigDataTest() {
        long start = System.currentTimeMillis();
        // 创建工作簿
        Workbook workbook = new XSSFWorkbook();
        // 创建表
        Sheet sheet = workbook.createSheet("07版本大数据写入表");
        // 创建单元格
        for (int rowNum = 0; rowNum < 65536; rowNum++) {
            Row row = sheet.createRow(rowNum);
            for (int cellNum = 0; cellNum < 10; cellNum++) {
                Cell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum);
            }
        }
        FileOutputStream stream = null;
        try {
            // 生成表
            stream = new FileOutputStream(PATH + "07版本大数据写入表.xlsx");
            // 写入
            workbook.write(stream);

        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("03版本大数据写入表完成!!!");
        System.out.println("耗时时间:{}" + ((double) System.currentTimeMillis() - start) / 1000 + "秒");
    }

批量导入数据代码 07 版本升级版本

    /**
     * 测试 Excel 07 版本升级版大数据写操作
     */
    @Test
    public void write07SversionBigDataTest() {
        long start = System.currentTimeMillis();
        // 创建工作簿
        Workbook workbook = new SXSSFWorkbook();
        // 创建表
        Sheet sheet = workbook.createSheet("07升级版本大数据写入表");
        // 创建单元格
        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);
            }
        }
        FileOutputStream stream = null;
        try {
            // 生成表
            stream = new FileOutputStream(PATH + "07升级版本大数据写入表.xlsx");
            // 写入
            workbook.write(stream);
            //清除临时文件
            ((SXSSFWorkbook) workbook).dispose();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("03版本大数据写入表完成!!!");
        System.out.println("耗时时间:{}" + ((double) System.currentTimeMillis() - start) / 1000 + "秒");
    }

二、easyExcel

官网:nullhttps://easyexcel.opensource.alibaba.com/docs/current/

<!-- EasyExcel -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.1.6</version>
</dependency>

 

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    /**
     * 学生姓名
     */
    @ExcelProperty(value = "学生姓名")
    private String name;
    /**
     * 学生性别
     */
    @ExcelProperty(value = "学生性别")
    private String gender;

    /**
     * 学生出生日期
     */
    @ExcelProperty(value = "学生出生日期")
    @DateTimeFormat("yyyy-MM-dd")
    private String birthday;
    /**
     * id
     */
    @ExcelIgnore
    private String id;

调用EasyExcel的API读取的`Excel`文件的测试类StudentReadDemo

package com.zc.listener;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.builder.ExcelReaderSheetBuilder;
import com.zc.pojo.Bill;
import com.zc.pojo.Student;

import java.io.File;

/**
 * @Classname StudentReadDemo
 * @Description TODO
 * @Version 1.0.0
 * @Date 2022/7/9 15:01
 * @Created by 海贼王
 */
public class StudentReadDemo {

    public static final String HOUZHUI = "xlsx";

    public static void main(String[] args) throws Exception {

        // 获取当前项目路径
        String path = System.getProperty("user.dir") + File.separator;
        // 获取文件名称
        String fileName = path + "票据模板.xlsx";
        String substring = fileName.substring(fileName.lastIndexOf(".") + 1);
        if (!HOUZHUI.equals(substring)) {
            throw new Exception("请使用新票据模板填写");
        }
        System.out.println(substring);

        // 读取文件,读取完之后会自动关闭
        /*
        	pathName  		文件路径;"d:\\杭州黑马在线202003班学员信息.xls"
        	head			每行数据对应的实体;Student.class
        	readListener	读监听器,每读一样就会调用一次该监听器的invoke方法

        	sheet方法参数: 工作表的顺序号(从0开始)或者工作表的名字,不传默认为0
        */
        // 封装工作簿对象

        ExcelReaderBuilder workBook = EasyExcel.read(fileName, Bill.class, new StudentReadListener());

        // 封装工作表
        ExcelReaderSheetBuilder sheet1 = workBook.sheet(0);
        // 读取
        sheet1.doRead();

    }
}

读取Excel的监听器,用于处理读取产生的数据

package com.zc.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.zc.pojo.Bill;
import com.zc.pojo.Student;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;

@Slf4j
public class StudentReadListener extends AnalysisEventListener<Bill> {
    // 每读一样,会调用该invoke方法一次
    @Override
    public void invoke(Bill data, AnalysisContext context) {
        System.out.println("data = " + data);
        System.out.println("插入数据库成功!");
    }

    // 全部读完之后,会调用该方法
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // TODO......
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值