跳转至

Java 解析 Excel 文件:从入门到实践

简介

在日常的软件开发中,处理 Excel 文件是一项常见的任务。无论是数据导入、数据处理还是生成报表,Java 都提供了丰富的库来解析 Excel 文件。本文将深入探讨 Java 解析 Excel 文件的相关知识,涵盖基础概念、使用方法、常见实践以及最佳实践,帮助读者全面掌握这一技术。

目录

  1. 基础概念
    • Excel 文件格式
    • Java 解析 Excel 的常用库
  2. 使用方法
    • 使用 Apache POI 解析 Excel 文件
    • 使用 EasyExcel 解析 Excel 文件
  3. 常见实践
    • 读取 Excel 数据
    • 写入 Excel 数据
    • 处理 Excel 中的复杂数据结构
  4. 最佳实践
    • 性能优化
    • 错误处理
    • 兼容性
  5. 小结
  6. 参考资料

基础概念

Excel 文件格式

Excel 文件主要有两种常见格式:.xls.xlsx.xls 是 Excel 97 - 2003 版本使用的二进制文件格式,而 .xlsx 是 Excel 2007 及更高版本采用的基于 XML 的文件格式。理解这两种格式的差异对于选择合适的解析库和处理方式至关重要。

Java 解析 Excel 的常用库

  • Apache POI:一个强大的 Java 库,提供了处理各种 Microsoft Office 格式文件的 API,包括 Excel。它支持 .xls.xlsx 格式,功能全面,但 API 相对复杂。
  • EasyExcel:阿里巴巴开源的一个轻量级 Excel 处理库,基于 Apache POI 进行了封装,使用起来更加简单快捷,特别适合处理大数据量的 Excel 文件。

使用方法

使用 Apache POI 解析 Excel 文件

  1. 添加依赖pom.xml 文件中添加 Apache POI 的依赖:
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.0.0</version>
</dependency>
  1. 读取 Excel 文件示例
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class ApachePOIExample {
    public static void main(String[] args) {
        String filePath = "path/to/your/excelFile.xlsx";
        try (FileInputStream fis = new FileInputStream(new File(filePath));
             Workbook workbook = new XSSFWorkbook(fis)) {
            Sheet sheet = workbook.getSheetAt(0);
            for (Row row : sheet) {
                for (Cell cell : row) {
                    String cellValue = getCellValue(cell);
                    System.out.print(cellValue + "\t");
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static String getCellValue(Cell cell) {
        if (cell == null) {
            return "";
        }

        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    return String.valueOf(cell.getNumericCellValue());
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return "";
        }
    }
}

使用 EasyExcel 解析 Excel 文件

  1. 添加依赖pom.xml 文件中添加 EasyExcel 的依赖:
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.1</version>
</dependency>
  1. 读取 Excel 文件示例
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

import java.util.List;

public class EasyExcelExample {
    public static void main(String[] args) {
        String filePath = "path/to/your/excelFile.xlsx";
        EasyExcel.read(filePath, new ExcelDataListener()).sheet().doRead();
    }

    static class ExcelDataListener extends AnalysisEventListener<List<Object>> {
        @Override
        public void invoke(List<Object> data, AnalysisContext context) {
            for (Object cell : data) {
                System.out.print(cell + "\t");
            }
            System.out.println();
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            System.out.println("All data has been analysed.");
        }
    }
}

常见实践

读取 Excel 数据

无论是使用 Apache POI 还是 EasyExcel,读取 Excel 数据的核心步骤都是打开文件、获取工作表、遍历行和单元格。在实际应用中,需要根据数据的结构和类型进行适当的处理,例如将单元格数据转换为合适的 Java 数据类型。

写入 Excel 数据

  1. 使用 Apache POI 写入 Excel 文件
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class ApachePOIWriteExample {
    public static void main(String[] args) {
        String filePath = "path/to/output/excelFile.xlsx";
        try (Workbook workbook = new XSSFWorkbook();
             FileOutputStream fos = new FileOutputStream(new File(filePath))) {
            Sheet sheet = workbook.createSheet("Sheet1");
            Row row = sheet.createRow(0);
            Cell cell = row.createCell(0);
            cell.setCellValue("Hello, Excel!");
            workbook.write(fos);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  1. 使用 EasyExcel 写入 Excel 文件
import com.alibaba.excel.EasyExcel;

import java.util.ArrayList;
import java.util.List;

public class EasyExcelWriteExample {
    public static void main(String[] args) {
        String filePath = "path/to/output/excelFile.xlsx";
        List<List<String>> data = new ArrayList<>();
        List<String> row1 = new ArrayList<>();
        row1.add("Hello");
        row1.add("World");
        data.add(row1);

        EasyExcel.write(filePath).sheet("Sheet1").doWrite(data);
    }
}

处理 Excel 中的复杂数据结构

在实际业务中,Excel 数据可能包含复杂的结构,如嵌套表格、合并单元格等。处理这些情况时,需要结合具体的库提供的 API 进行特殊处理。例如,使用 Apache POI 处理合并单元格可以通过 Sheet.getMergedRegions() 方法获取合并区域信息,然后在读取数据时进行相应的调整。

最佳实践

性能优化

  • 使用流处理:对于大数据量的 Excel 文件,使用流处理可以避免一次性将所有数据加载到内存中,提高性能。EasyExcel 在这方面表现出色,它基于事件驱动的方式进行解析,减少内存占用。
  • 批量操作:在写入数据时,尽量采用批量操作,减少文件写入的次数,提高写入效率。

错误处理

  • 输入验证:在读取或写入 Excel 文件之前,对文件路径、文件格式等进行验证,确保操作的合法性。
  • 异常捕获:在代码中合理捕获和处理可能出现的异常,如文件不存在、格式错误等,提供友好的错误提示。

兼容性

  • 版本兼容性:确保所使用的库与 Excel 文件格式以及 Java 版本兼容。例如,Apache POI 的不同版本对 Excel 文件格式的支持可能有所差异,需要根据实际情况选择合适的版本。
  • 跨平台兼容性:在开发过程中,考虑应用程序在不同操作系统和环境下的兼容性,确保 Excel 处理功能的稳定性。

小结

本文详细介绍了 Java 解析 Excel 文件的相关知识,包括基础概念、常用库的使用方法、常见实践以及最佳实践。通过学习这些内容,读者可以根据具体需求选择合适的库和方法来处理 Excel 文件,提高开发效率和代码质量。无论是简单的数据读取还是复杂的报表生成,Java 都提供了强大的工具和方法来满足各种业务场景。

参考资料