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

左手的ㄟ右手 2023-09-27 16:38 87阅读 0赞

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

  1. <!-- poi -->
  2. <dependency>
  3. <groupId>org.apache.poi</groupId>
  4. <artifactId>poi</artifactId>
  5. <version>5.2.2</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.apache.poi</groupId>
  9. <artifactId>poi-ooxml</artifactId>
  10. <version>5.2.2</version>
  11. </dependency>

二、代码

1、service

  1. /**
  2. * 解析Excel
  3. *
  4. * @param path Excel文件的存放路径
  5. */
  6. List<List<String>> parseExcel(String path) throws IOException;

2、impl

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

  1. package com.***.impl;
  2. import com.***.service.ParseExcelService;
  3. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  4. import org.apache.poi.ss.usermodel.*;
  5. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  6. import org.springframework.stereotype.Service;
  7. import java.io.IOException;
  8. import java.math.BigDecimal;
  9. import java.nio.file.Files;
  10. import java.nio.file.Paths;
  11. import java.util.ArrayList;
  12. import java.util.List;
  13. /**
  14. * 解析Excel
  15. */
  16. @Service
  17. public class ParseExcelServiceImpl implements ParseExcelService {
  18. @Override
  19. public List<List<String>> parseExcel(String path) throws IOException {
  20. Workbook workbook = null;
  21. // 校验文件后缀
  22. String suffix = path.substring(path.lastIndexOf("."));
  23. if (".xls".equals(suffix)) {
  24. workbook = new HSSFWorkbook(Files.newInputStream(Paths.get(path)));
  25. } else if (".xlsx".equals(suffix)) {
  26. workbook = new XSSFWorkbook(Files.newInputStream(Paths.get(path)));
  27. } else {
  28. System.out.println("excel格式不正确");
  29. }
  30. List<List<String>> list = new ArrayList<>();
  31. // 获取sheet工作簿
  32. Sheet sheet = workbook.getSheetAt(0);
  33. // 遍历每行
  34. for (int i = sheet.getFirstRowNum() + 1; i <= sheet.getLastRowNum(); i++) {
  35. Row row = sheet.getRow(i);
  36. if (null == row) {
  37. continue;
  38. }
  39. List<String> cellList = new ArrayList<>();
  40. // 遍历每个单元格 并获取每个单元格数据
  41. for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
  42. Cell cell = row.getCell(j);
  43. // 处理单元格的数据类型,否则会报错:Cannot get a STRING value from a NUMERIC cell
  44. //(以下两种方法,根据你的POI版本决定,推荐方法二)
  45. /* 方法一:使用setCellType()方法,但该方法在poi5.0版本已经被弃用 */
  46. // cell.setCellType(CellType.STRING);
  47. /* 方法二:先获取单元格内值的属性(数字型/字符串型),再进行判断 */
  48. // 获取单元格内值的属性
  49. CellType cellType = cell.getCellType();
  50. if (cellType == CellType.NUMERIC) {
  51. // 获取数字类型的单元格中的数据NUMERIC
  52. double numericCellValue = cell.getNumericCellValue();
  53. // stripTrailingZeros():去除末尾多余的0;toPlainString():输出时不用科学计数法
  54. String value = new BigDecimal(String.valueOf(numericCellValue)).stripTrailingZeros().toPlainString();
  55. cellList.add(value);
  56. } else if (cellType == CellType.STRING) {
  57. String value = cell.getStringCellValue().trim();
  58. cellList.add(value);
  59. }
  60. }
  61. list.add(cellList);
  62. }
  63. System.out.println("解析的Excel数据>>>>>>>>>>>>>>>" + list);
  64. return list;
  65. }
  66. }

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

3、controller

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

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

051134416a4547d7a29c482879ddfb08.jpeg

b188b39ad4cb483a82a8170dab7111b2.jpeg

解析结果:

  1. xls

4f33f065716d415a99bd0b76895f25d9.jpeg

2.xlsx 39646883d06e4ca8ac474b9c999dd287.jpeg

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

发表评论

表情:
评论列表 (有 0 条评论,87人围观)

还没有评论,来说两句吧...

相关阅读