跳转至

使用Java读取Excel文件:从基础到最佳实践

简介

在Java开发中,读取Excel文件是一项常见的任务。无论是处理业务数据、进行数据迁移,还是生成报表等场景,都需要从Excel文件中提取信息。本文将详细介绍如何使用Java读取Excel文件,涵盖基础概念、使用方法、常见实践以及最佳实践,帮助读者全面掌握这一重要技能。

目录

  1. 基础概念
    • Excel文件格式
    • Java操作Excel的相关库
  2. 使用方法
    • 使用Apache POI读取Excel文件
    • 使用EasyExcel读取Excel文件
  3. 常见实践
    • 读取不同版本Excel文件
    • 处理Excel中的各种数据类型
    • 处理大文件
  4. 最佳实践
    • 性能优化
    • 错误处理与异常处理
    • 代码结构与可维护性
  5. 小结
  6. 参考资料

基础概念

Excel文件格式

Excel文件主要有两种常见格式: - .xls:Excel 97-2003的文件格式,基于BIFF(Binary Interchange File Format)。 - .xlsx:Excel 2007及以后版本的文件格式,基于Open XML标准。这种格式本质上是一个压缩文件,包含多个XML文件,描述了工作表、样式、数据等信息。

Java操作Excel的相关库

  • Apache POI:是一个流行的Java库,提供了对各种Microsoft Office格式文件的读写支持,包括Excel。它支持.xls和.xlsx两种格式,功能强大,能够处理Excel文件的各种元素,如单元格、工作表、样式等。
  • EasyExcel:是阿里巴巴开源的一个轻量级Excel处理库。它基于Apache POI进行封装,简化了Excel的读写操作,特别在处理大文件时性能表现出色,同时代码更加简洁易懂。

使用方法

使用Apache POI读取Excel文件

  1. 添加依赖:在Maven项目的pom.xml文件中添加以下依赖:
<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. 添加依赖:在Maven项目的pom.xml文件中添加以下依赖:
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.0</version>
</dependency>
  1. 创建数据模型类
import com.alibaba.excel.annotation.ExcelProperty;

public class ExcelData {
    @ExcelProperty("列1")
    private String column1;
    @ExcelProperty("列2")
    private String column2;

    // Getters and Setters
    public String getColumn1() {
        return column1;
    }

    public void setColumn1(String column1) {
        this.column1 = column1;
    }

    public String getColumn2() {
        return column2;
    }

    public void setColumn2(String column2) {
        this.column2 = column2;
    }
}
  1. 读取Excel文件示例代码
import com.alibaba.excel.EasyExcel;
import java.util.List;

public class EasyExcelExample {
    public static void main(String[] args) {
        String filePath = "path/to/your/excelFile.xlsx";
        List<ExcelData> dataList = EasyExcel.read(filePath)
              .head(ExcelData.class)
              .sheet()
              .doReadSync();

        for (ExcelData data : dataList) {
            System.out.println(data.getColumn1() + "\t" + data.getColumn2());
        }
    }
}

常见实践

读取不同版本Excel文件

Apache POI可以通过不同的Workbook实现类来读取不同版本的Excel文件: - 对于.xls文件,使用HSSFWorkbook。 - 对于.xlsx文件,使用XSSFWorkbook

处理Excel中的各种数据类型

在前面的getCellValue方法中已经展示了如何处理Excel中的常见数据类型,如字符串、数字、日期、布尔值和公式。在实际应用中,需要根据业务需求对不同数据类型进行适当的转换和处理。

处理大文件

对于大的Excel文件,直接使用传统方式读取可能会导致内存不足。EasyExcel在处理大文件方面有较好的性能表现,它采用了事件驱动的方式,逐行读取数据,而不是一次性将整个文件加载到内存中。例如:

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

public class BigExcelReader {
    public static void main(String[] args) {
        String filePath = "path/to/your/bigExcelFile.xlsx";
        EasyExcel.read(filePath, ExcelData.class, new AnalysisEventListener<ExcelData>() {
            @Override
            public void invoke(ExcelData data, AnalysisContext context) {
                System.out.println(data.getColumn1() + "\t" + data.getColumn2());
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                System.out.println("读取完成");
            }
        }).sheet().doRead();
    }
}

最佳实践

性能优化

  • 使用合适的库:根据文件大小和具体需求选择合适的库,如处理大文件优先考虑EasyExcel。
  • 避免不必要的对象创建:在读取过程中,尽量复用对象,减少内存开销。
  • 批量处理:如果需要对数据进行进一步处理,可以考虑批量处理,减少I/O操作次数。

错误处理与异常处理

在读取Excel文件时,可能会遇到各种错误,如文件格式错误、权限问题等。需要对可能出现的异常进行捕获和处理,提供友好的错误提示,提高程序的稳定性。例如:

try (FileInputStream fis = new FileInputStream(new File(filePath));
     Workbook workbook = new XSSFWorkbook(fis)) {
    // 读取逻辑
} catch (IOException e) {
    System.err.println("读取Excel文件时发生错误: " + e.getMessage());
}

代码结构与可维护性

将读取Excel文件的逻辑封装成独立的方法或类,提高代码的可读性和可维护性。例如,可以将读取Excel文件的通用逻辑封装到一个工具类中:

public class ExcelReaderUtil {
    public static List<ExcelData> readExcel(String filePath) {
        return EasyExcel.read(filePath)
              .head(ExcelData.class)
              .sheet()
              .doReadSync();
    }
}

小结

本文详细介绍了使用Java读取Excel文件的相关知识,包括基础概念、使用方法、常见实践以及最佳实践。通过学习Apache POI和EasyExcel这两个库的使用,读者可以根据实际需求选择合适的方式来读取Excel文件,并在性能优化、错误处理和代码结构等方面进行改进,提高程序的质量和效率。

参考资料