解析读取Excel文件(.xls .xlsx)

在日常的开发过程中,经常需要使用Excel文件来进行数据的导入或导出。在导入后,需解析数据 ,最后插入到数据库中。

在Java技术生态圈中,可以进行Excel文件处理的主流技术包括:Apache POIJXLAlibaba EasyExcel等。

JXL只支持Excel2003以下版本,所以不太常见。

Alibaba EasyExcel采用逐行读取的解析模式,将每一行的解析结果以观察者模式通知处理(AnalyEventListener),所以比较适合数据体量较大的Excel文件解析。

Apache POI基于DOM方式进行解析,将文件直接加载内存,所以速度较快,适合Excel文件数量不大的应用场景。

Apache POI使用Java编写的免费开源的跨平台的Java API。Apache POI提供给Java程序对Microso Office 格式档案进行读写功能的API开源类库。它提供了不同格式文件的解析,如下:

  • HSSF:提供读写Microsoft Excel格式档案的功能
  • XSSF:提供读写Microsoft Excel OOXML格式档案的功能
  • HWPF:提供读写Microsoft Word格式档案的功能
  • HSLF:提供读写Microsoft PowerPoint格式档案的功能
  • HDGF:提供读写Microsoft Visio格式档案的功能

这片文章主要分享,通过Apache POI进行解析Excel:

一、POM依赖

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

二、代码

1、service

    /**
     * 解析Excel
     *
     * @param path Excel文件的存放路径
     */
    List<List<String>> parseExcel(String path) throws IOException;

2、impl

HSSF用于解析旧版本(*.xls)Excel文件,由于旧版本的Excel文件只能存在65535行数据,所以目前已经不常用,现在主要采用XSSF进行新版本(*.xlsx)Excel文件的解析。

package com.***.impl;

import com.***.service.ParseExcelService;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * 解析Excel
 */
@Service
public class ParseExcelServiceImpl implements ParseExcelService {

    @Override
    public List<List<String>> parseExcel(String path) throws IOException {

        Workbook workbook = null;
        // 校验文件后缀
        String suffix = path.substring(path.lastIndexOf("."));
        if (".xls".equals(suffix)) {
            workbook = new HSSFWorkbook(Files.newInputStream(Paths.get(path)));
        } else if (".xlsx".equals(suffix)) {
            workbook = new XSSFWorkbook(Files.newInputStream(Paths.get(path)));
        } else {
            System.out.println("excel格式不正确");
        }
        List<List<String>> list = new ArrayList<>();
        // 获取sheet工作簿
        Sheet sheet = workbook.getSheetAt(0);
        // 遍历每行
        for (int i = sheet.getFirstRowNum() + 1; i <= sheet.getLastRowNum(); i++) {
            Row row = sheet.getRow(i);
            if (null == row) {
                continue;
            }
            List<String> cellList = new ArrayList<>();
            // 遍历每个单元格 并获取每个单元格数据
            for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
                Cell cell = row.getCell(j);

                // 处理单元格的数据类型,否则会报错:Cannot get a STRING value from a NUMERIC cell
                //(以下两种方法,根据你的POI版本决定,推荐方法二)

                /* 方法一:使用setCellType()方法,但该方法在poi5.0版本已经被弃用 */
                // cell.setCellType(CellType.STRING);

                /* 方法二:先获取单元格内值的属性(数字型/字符串型),再进行判断 */
                // 获取单元格内值的属性
                CellType cellType = cell.getCellType();
                if (cellType == CellType.NUMERIC) {
                    // 获取数字类型的单元格中的数据NUMERIC
                    double numericCellValue = cell.getNumericCellValue();
                    // stripTrailingZeros():去除末尾多余的0;toPlainString():输出时不用科学计数法
                    String value = new BigDecimal(String.valueOf(numericCellValue)).stripTrailingZeros().toPlainString();
                    cellList.add(value);
                } else if (cellType == CellType.STRING) {
                    String value = cell.getStringCellValue().trim();
                    cellList.add(value);
                }
            }
            list.add(cellList);
        }
        System.out.println("解析的Excel数据>>>>>>>>>>>>>>>" + list);
        return list;
    }
}

PS:如果你本地映入的POI版本低于5.0的话,上面的实现类中方法一和方法二都可使用;如果版本大于5.0,则推荐用方法二。

3、controller

    @RequestMapping("/parseExcel")
    public List<List<String>> parseExcel() throws IOException {
        String path = "C:\\Users\\admin\\Desktop\\解析Excel信息1.xls";
        //String path = "C:\\Users\\admin\\Desktop\\解析Excel信息2.xlsx";
        return parseExcelService.parseExcel(path);
    }

我本地创建的两个测试Excel文件:(注意文件后缀不同,一个是“.xls”,一个是“.xlsx”)

解析结果:

1. xls

 2.xlsx 

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、评论、收藏➕关注,您的支持是我坚持写作最大的动力。

猜你喜欢

转载自blog.csdn.net/weixin_42555014/article/details/129751743