Java 处理 Excel 概述

在 Java 中处理 Microsoft Excel 文件,需要用到第三方库,因为Java标准库并不直接支持Excel格式。常用到的第三方库包括 Apache POI, JExcel, Fastexcel, EasyExcel等,它们可以帮助开发者动态读取、写入或者修改 Excel 中的内容。

Excel

Apache POI

Apache POI 库支持.xls和.xlsx文件,并且是一个比处理 Excel 文件的其他 Java 库更复杂的库。

依赖引入

POI 需要引入两个依赖库:

<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>5.2.5</version>
</dependency>
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>5.2.5</version>
</dependency>

它提供了用于对Excel文件进行建模的Workbook接口,以及对 Excel 文件的元素进行建模的Sheet、Row 和Cell接口,并且支持两种Excel文件格式。

使用较新的.xlsx文件格式时,将使用到XSSFWorkbook、XSSFSheet、XSSFRow和XSSFCell类。

处理旧的.xls格式,将使用到HSSFWorkbook、HSSFSheet、HSSFRow和HSSFCell类。

读取Excel文件

先创建一个方法来打开.xlsx文件,然后从该文件的第一页读取内容。

读取单元格内容的方法根据单元格中数据的类型而变化。可以使用Cell接口的getCellType()方法确定单元格内容的类型。

首先,创建文件对象:

FileInputStream file = new FileInputStream(new File(fileLocation));
Workbook workbook = new XSSFWorkbook(file);

然后,检索文件的第一页并循环迭代每一行:

Sheet sheet = workbook.getSheetAt(0);

Map<Integer, List<String>> data = new HashMap<>();
int i = 0;
for (Row row : sheet) {
    data.put(i, new ArrayList<String>());
    for (Cell cell : row) {
        switch (cell.getCellType()) {
            case STRING: ... break;
            case NUMERIC: ... break;
            case BOOLEAN: ... break;
            case FORMULA: ... break;
            default: data.get(new Integer(i)).add(" ");
        }
    }
    i++;
}

Apache POI 有不同的方法来读取每种类型的数据。

JExcel

JExcel 库是一个轻量级库,优点是比 Apache POI 更容易使用,但缺点是它只提供对处理.xls (1997-2003) 格式的 Excel 文件的支持,不支持.xlsx文件。

依赖引入

<dependency>
  <groupId>org.jxls</groupId>
  <artifactId>jxls-jexcel</artifactId>
  <version>1.0.9</version>
</dependency>

JExcel 只需要引入一个依赖库,但是该依赖最新版停留在 2019 年,已经多年未更新。

读取Excel文件

为了处理 Excel 文件,该库提供了一系列代表 Excel 文件不同部分的类。Workbook类代表整个工作表集合。 Sheet类表示单个工作表,Cell类表示电子表格的单个单元格。

public Map<Integer, List<String>> readJExcel(String fileLocation) 
      throws IOException, BiffException {

        Map<Integer, List<String>> data = new HashMap<>();

        Workbook workbook = Workbook.getWorkbook(new File(fileLocation));
        Sheet sheet = workbook.getSheet(0);
        int rows = sheet.getRows();
        int columns = sheet.getColumns();

        for (int i = 0; i < rows; i++) {
            data.put(i, new ArrayList<String>());
            for (int j = 0; j < columns; j++) {
                data.get(i)
                  .add(sheet.getCell(j, i)
                  .getContents());
            }
        }
        return data;
    }

Fastexcel

Fastexcel 是一个易于使用的库,与 Apache POI 相比,功能有限且内存占用较低。

它使用CompletableFuture的多线程支持使其成为处理功能不广泛的大型文件时的绝佳选择。目前,该库仅支持基本样式,不支持图形。

依赖引入

<dependency>
    <groupId>org.dhatim</groupId>
    <artifactId>fastexcel-reader</artifactId>
    <version>0.17.0</version>
</dependency>
<dependency>
    <groupId>org.dhatim</groupId>
    <artifactId>fastexcel</artifactId>
    <version>0.17.0</version>
</dependency>

Fastexcel 需要引入两个依赖。

读取Excel文件

下面简单演示Fastexcel读取 excel 文件:

public Map<Integer, List<String>> readExcel(String fileLocation) throws IOException {
        Map<Integer, List<String>> data = new HashMap<>();

        FileInputStream file = new FileInputStream(fileLocation); 
        ReadableWorkbook wb = new ReadableWorkbook(file)) {
            Sheet sheet = wb.getFirstSheet();
            try (Stream<Row> rows = sheet.openStream()) {
                rows.forEach(r -> {
                    data.put(r.getRowNum(), new ArrayList<>());

                    for (Cell cell : r) {
                        data.get(r.getRowNum()).add(cell.getRawValue());
                    }
                });
            }
        return data;
    }

在这里,使用的是 cell.getRawValue() 它将该单元格的值作为字符串返回。或者,基于CellType ,也可以使用 Row 类中的 getCellAsBoolean(int cellIndex)、getCellAsDate(int cellIndex)、getCellAsString(int cellIndex) 或getCellAsNumber(int cellIndex)方法来读取单元格的内容。

EasyExcel

EasyExcel 是阿里巴巴开源的基于Java的Excel操作工具,它可以处理大量数据,具有高性能和低内存占用。开源地址:https://github.com/alibaba/easyexcel

依赖引入

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.4</version>
</dependency>

Fastexcel 需要引入一个依赖,其内部引用了 easyexcel-core 依赖。

读取Excel文件

EasyExcel 处理 Excel 数据是基于实体对象的,因此先要创建一个 Java Bean:

@Data  //生成getter、setter、toString等方法
public class ReadDemoData {

    private String string;

    private Date date;

    private Double doubleData;
}

EasyExcel 默认一行行的读取excel,所以需要创建excel一行一行的回调监听器:

public class ReadDemoDataListener implements ReadListener<ReadDemoData> {

        //在读取 Excel 文件表头时调用的方法。可用于对表头进行校验或者记录日志等操作
        @Override
        public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {

        }

        //在读取到一行数据时调用的方法。泛型<T>表示读取到的数据类型。可以在该方法中对读取到的数据进行处理
        @Override
        public void invoke(ReadDemoData readDemoData, AnalysisContext analysisContext) {
            log.info("解析到一行数据:{}", readDemoData.toString());
        }
}

读取文件时,传入文件路径与解析监听器:

    public void simpleRead() {
        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
        // 这里 需要指定读用哪个class去读,然后读取第一个sheet  同步读取会自动finish
        EasyExcel.read(fileName, ReadDemoData.class, new ReadDemoDataListener()).sheet().doRead();
    }

当然,如果业务场景简单,也可以不创建回调监听器:

    EasyExcel.read(fileName, ReadDemoData.class, new PageReadListener<DemoData>(dataList -> {
        for (ReadDemoData demoData : dataList) {
            log.info("读取到一条数据{}", JSON.toJSONString(demoData));
        }
    })).sheet().doRead();

总结

Apache POI

  • 支持.xls和.xlsx格式的文件。
  • 提供了丰富的API来操作Excel文件,包括读取、写入和修改。
  • 包含Workbook、Sheet、Row和Cell接口以及相应的实现类。

JExcel

  • 轻量级库,易于使用。
  • 仅支持.xls格式(1997-2003)的Excel文件。
  • 提供了Workbook、Sheet和Cell类来操作Excel文件。

Fastexcel

  • 易于使用的库,内存占用较低。
  • 支持多线程读取大型Excel文件。
  • 目前仅支持基本样式,不支持图形。

EasyExcel

  • 阿里巴巴开源的高性能Excel操作工具。
  • 适合处理大量数据,具有低内存占用。
  • 基于实体对象操作Excel数据,支持自定义读取监听器。

处理Excel文件是Java开发中的常见任务,尤其是在数据分析和报表生成方面。Apache POI、JExcel、Fastexcel和EasyExcel是几个流行的库,它们提供了不同程度的功能和易用性。开发者可以根据项目需求、Excel文件的格式以及对性能和内存的要求来选择合适的库。Apache POI以其全面的功能和广泛的社区支持而闻名,而JExcel则因其简单性而受到欢迎。Fastexcel和EasyExcel则提供了更现代的API和优化的性能。在选择库时,还应考虑库的维护状态和社区支持,以确保能够获得必要的帮助和更新。

转载请注明出处:码谱记录 » Java 处理 Excel 概述

相关推荐

  • 暂无文章