跳转至

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

简介

在Java开发中,读取Excel文件是一项常见的任务。无论是处理业务数据、进行数据迁移还是生成报表,掌握如何使用Java读取Excel文件都至关重要。本文将深入探讨使用Java读取Excel文件的相关知识,涵盖基础概念、详细的使用方法、常见实践以及最佳实践,帮助读者全面掌握这一技术。

目录

  1. 基础概念
    • Excel文件格式
    • Java处理Excel的相关库
  2. 使用方法
    • 使用Apache POI读取Excel文件
    • 使用EasyExcel读取Excel文件
  3. 常见实践
    • 读取简单Excel表格数据
    • 处理带有表头的Excel数据
    • 处理不同Sheet页的数据
  4. 最佳实践
    • 性能优化
    • 错误处理与异常处理
    • 内存管理
  5. 小结
  6. 参考资料

基础概念

Excel文件格式

Excel文件有多种格式,常见的有 .xls.xlsx.xls 是Excel 97-2003的文件格式,基于BIFF(二进制文件格式);.xlsx 是Excel 2007及以后版本的文件格式,基于Open XML标准,是一种基于XML的压缩文件格式。

Java处理Excel的相关库

  • Apache POI:一个开源的Java库,提供了处理各种Microsoft Office格式文件的功能,包括Excel。它支持读取和写入 .xls.xlsx 格式的文件,功能强大且灵活,但学习曲线相对较陡。
  • EasyExcel:阿里巴巴开源的一个轻量级Excel处理库,专注于使Excel操作变得简单高效。它在性能和易用性方面表现出色,特别适合处理大数据量的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/file.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) {
                    switch (cell.getCellType()) {
                        case STRING:
                            System.out.print(cell.getStringCellValue() + "\t");
                            break;
                        case NUMERIC:
                            if (DateUtil.isCellDateFormatted(cell)) {
                                System.out.print(cell.getDateCellValue() + "\t");
                            } else {
                                System.out.print(cell.getNumericCellValue() + "\t");
                            }
                            break;
                        case BOOLEAN:
                            System.out.print(cell.getBooleanCellValue() + "\t");
                            break;
                        default:
                            System.out.print(cell.toString() + "\t");
                    }
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

使用EasyExcel读取Excel文件

  1. 添加依赖pom.xml 中添加EasyExcel的依赖:
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.1</version>
</dependency>
  1. 创建数据模型类
import com.alibaba.excel.annotation.ExcelProperty;

public class User {
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("年龄")
    private Integer age;

    // getters and setters
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
  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/file.xlsx";
        EasyExcel.read(filePath, User.class, new AnalysisEventListener<User>() {
            @Override
            public void onReadData(List<User> dataList, AnalysisContext context) {
                for (User user : dataList) {
                    System.out.println("姓名:" + user.getName() + ", 年龄:" + user.getAge());
                }
            }
        }).sheet().doRead();
    }
}

常见实践

读取简单Excel表格数据

上述代码示例已经展示了如何读取简单Excel表格的数据,遍历每一行和每一个单元格,根据单元格的数据类型进行相应的处理。

处理带有表头的Excel数据

可以通过读取第一行数据作为表头,然后根据表头信息来处理后续行的数据。以下是使用Apache POI的示例:

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;
import java.util.ArrayList;
import java.util.List;

public class HeaderExcelExample {
    public static void main(String[] args) {
        String filePath = "path/to/your/file.xlsx";
        try (FileInputStream fis = new FileInputStream(new File(filePath));
             Workbook workbook = new XSSFWorkbook(fis)) {

            Sheet sheet = workbook.getSheetAt(0);
            Row headerRow = sheet.getRow(0);
            List<String> headers = new ArrayList<>();
            for (Cell cell : headerRow) {
                headers.add(cell.getStringCellValue());
            }

            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                for (int j = 0; j < headers.size(); j++) {
                    Cell cell = row.getCell(j);
                    String value = "";
                    if (cell != null) {
                        switch (cell.getCellType()) {
                            case STRING:
                                value = cell.getStringCellValue();
                                break;
                            case NUMERIC:
                                if (DateUtil.isCellDateFormatted(cell)) {
                                    value = cell.getDateCellValue().toString();
                                } else {
                                    value = cell.getNumericCellValue() + "";
                                }
                                break;
                            case BOOLEAN:
                                value = cell.getBooleanCellValue() + "";
                                break;
                            default:
                                value = cell.toString();
                        }
                    }
                    System.out.print(headers.get(j) + ": " + value + "\t");
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

处理不同Sheet页的数据

可以通过遍历Workbook中的所有Sheet来处理不同Sheet页的数据。以下是使用Apache POI的示例:

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 MultipleSheetsExample {
    public static void main(String[] args) {
        String filePath = "path/to/your/file.xlsx";
        try (FileInputStream fis = new FileInputStream(new File(filePath));
             Workbook workbook = new XSSFWorkbook(fis)) {

            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
                Sheet sheet = workbook.getSheetAt(i);
                System.out.println("Sheet名称:" + sheet.getSheetName());
                for (Row row : sheet) {
                    for (Cell cell : row) {
                        switch (cell.getCellType()) {
                            case STRING:
                                System.out.print(cell.getStringCellValue() + "\t");
                                break;
                            case NUMERIC:
                                if (DateUtil.isCellDateFormatted(cell)) {
                                    System.out.print(cell.getDateCellValue() + "\t");
                                } else {
                                    System.out.print(cell.getNumericCellValue() + "\t");
                                }
                                break;
                            case BOOLEAN:
                                System.out.print(cell.getBooleanCellValue() + "\t");
                                break;
                            default:
                                System.out.print(cell.toString() + "\t");
                        }
                    }
                    System.out.println();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

最佳实践

性能优化

  • 批量读取:避免逐行读取,使用批量读取的方式,如EasyExcel的 onReadData 方法,可以提高读取效率。
  • 内存管理:对于大数据量的Excel文件,避免一次性将所有数据加载到内存中。可以使用流处理的方式,边读取边处理数据。

错误处理与异常处理

  • 输入验证:在读取Excel文件之前,对文件路径、文件格式等进行验证,确保输入的正确性。
  • 异常捕获:在读取过程中,使用try-catch块捕获可能出现的异常,如 IOExceptionIllegalStateException 等,并进行适当的处理。

内存管理

  • 及时释放资源:使用 try-with-resources 语句确保在读取完成后及时关闭文件输入流和Workbook对象,释放资源。

小结

本文详细介绍了使用Java读取Excel文件的相关知识,包括基础概念、使用方法、常见实践以及最佳实践。通过学习这些内容,读者可以根据具体需求选择合适的库和方法来高效地读取Excel文件,并在实际项目中进行优化和处理。掌握这些技能将有助于提升Java开发中处理数据的能力。

参考资料