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

不管现实多么惨不忍睹,都要持之以恒地相信,这只是黎明前短暂的黑暗而已。不要惶恐眼前的难关迈不过去,不要担心此刻的付出没有回报,别再花时间等待天降好运。真诚做人,努力做事!你想要的,岁月都会给你。解析读取Excel文件(.xls .xlsx),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

在日常的开发过程中,经常需要使用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”)

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

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

解析结果:

1. xls

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/161436.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!