• Apache POI 解析和处理Excel


    摘要:由于开发需要批量导入Excel中的数据,使用了Apache POI库,记录下使用过程

     1. 背景  

            Java 中操作 Excel 文件的库常用的有Apache POI 和阿里巴巴的 EasyExcel 。Apache POI 是一个功能比较全面的 Java 库,适合处理复杂的 Office 文件操作需求;而 EasyExcel 则是一个专注于 Excel 文件读写的简单、高效工具,更适合处理 Excel 文件的批量读写需求,并且易于上手。当Excel的数据量很大时推荐使用EasyExcel更合适。

            Apache的POI 用于处理 Microsoft Office 格式文件(如Excel、Word、PowerPoint)。它支持读取、写入和操作 Excel 文件,可以处理各种 Excel 格式(如 .xls 和 .xlsx)。
    Apache POI - the Java API for Microsoft Documentsicon-default.png?t=N7T8https://poi.apache.org/

            阿里的EasyExcel
    关于Easyexcel | Easy ExcelEasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目,在尽可能节约内存的情况下支持读写百M的Excel。icon-default.png?t=N7T8https://easyexcel.opensource.alibaba.com/docs/current/

    2. Apache POI的使用

    2.1 引入依赖poi和poi-ooxml

            首先,在pom.xml中配置相关依赖,并使用Maven引入

    1. <dependency>
    2. <groupId>org.apache.poigroupId>
    3. <artifactId>poiartifactId>
    4. <version>3.16version>
    5. dependency>
    6. <dependency>
    7. <groupId>org.apache.poigroupId>
    8. <artifactId>poi-ooxmlartifactId>
    9. <version>3.16version>
    10. dependency>
    2.2 使用POI读取Excel中数据填充对象

            使用Apache POI解析Excel大体过程:通过输入流FileInputStream读取Excel中的数据,使用XSSFWorkbook类加载输入流,创建了一个新版本的Excel工作簿(下例子为workbook),从创建的工作簿中获取第一个工作表 firstsheet,再通过迭代器逐行逐个单元格遍历工作表,将单元格中的数据填充到对象中,并将对象添加到列表。此时,对得到的列表遍历,执行相应的数据库操作,实现批量导入的功能。

    1. public void addProductByExcel(File destFile) throws IOException {
    2. // 从Excel文件中读取商品信息,并转换为商品列表
    3. List products = readProductsFromExcel(destFile);
    4. for (int i = 0; i < products.size(); i++) {
    5. Product product = products.get(i);
    6. Product productOld = productMapper.selectByName(product.getName()); // 通过商品名称来查询数据库中是否已存在同名商品
    7. if (productOld != null) { // 查询到同名商品,则抛出自定义异常
    8. throw new ImoocMallException(ImoocMallExceptionEnum.NAME_EXISTED);
    9. }
    10. int count = productMapper.insertSelective(product); // 不存在同名商品,则向数据库中插入当前商品信息,存储受影响的行数
    11. if (count == 0) {
    12. throw new ImoocMallException(ImoocMallExceptionEnum.CREATE_FAILED);
    13. }
    14. }
    15. }
    16. private List readProductsFromExcel(File excelFile) throws IOException {
    17. ArrayList listProducts = new ArrayList<>(); // 用于存储读取到的商品信息
    18. FileInputStream inputStream = new FileInputStream(excelFile); // 文件输入流 inputStream,用于读取Excel文件中的数据
    19. XSSFWorkbook workbook = new XSSFWorkbook(inputStream); // 使用XSSFWorkbook类加载输入流,创建了一个新版本的Excel工作簿workbook
    20. XSSFSheet firstsheet = workbook.getSheetAt(0); // 获取第一个工作表,index从0还是1开始需要根据实际情况确认
    21. Iterator iterator = firstsheet.iterator(); // 通过工作表的迭代器创建一个行迭代器iterator,用于逐行遍历工作表中的数据
    22. while(iterator.hasNext()) {
    23. Row nextRow = iterator.next(); // 逐行遍历
    24. Iterator cellIterator = nextRow.cellIterator(); // 逐个单元格遍历
    25. Product aProduct = new Product(); // 创建Product对象aProduct,用于存储当前行数据对应的商品信息
    26. // 读取单元格填充aProduct
    27. while (cellIterator.hasNext()) {
    28. Cell nextCell = cellIterator.next();
    29. int columnIndex = nextCell.getColumnIndex(); //获取单元格的索引,即列号
    30. switch (columnIndex) {
    31. case 0:
    32. aProduct.setName((String) ExcelUtil.getCellValue(nextCell)); // 针对不同的列号执行相应的操作,将单元格数据填充到aProduct对象的相应属性中
    33. break;
    34. case 1:
    35. aProduct.setImage((String) ExcelUtil.getCellValue(nextCell));
    36. break;
    37. case 2:
    38. aProduct.setDetail((String) ExcelUtil.getCellValue(nextCell));
    39. break;
    40. case 3:
    41. Double cellValue = (Double) ExcelUtil.getCellValue(nextCell); // excel中数字类型默认为Double
    42. aProduct.setCategoryId(cellValue.intValue());
    43. break;
    44. case 4:
    45. cellValue = (Double) ExcelUtil.getCellValue(nextCell); // excel中数字类型默认为Double
    46. aProduct.setPrice(cellValue.intValue());
    47. break;
    48. case 5:
    49. cellValue = (Double) ExcelUtil.getCellValue(nextCell); // excel中数字类型默认为Double
    50. aProduct.setStock(cellValue.intValue());
    51. break;
    52. case 6:
    53. cellValue = (Double) ExcelUtil.getCellValue(nextCell); // excel中数字类型默认为Double
    54. aProduct.setStatus(cellValue.intValue());
    55. break;
    56. default:
    57. break;
    58. }
    59. }
    60. listProducts.add(aProduct); // 将填充好数据的aProduct对象添加到商品列表listProducts中
    61. }
    62. workbook.close(); // 关闭Excel工作簿
    63. inputStream.close(); // 关闭文件输入流
    64. return listProducts;
    65. }

            综上,实现了读取Excel中的数据,填充进入对象listProducts,最终添加到数据库的功能。

  • 相关阅读:
    STM32的四种输出模式
    73、SpringBoot 直接整合 JDBC
    python之文件操作
    英文翻译意大利语-批量英文翻译意大利语工具免费
    [2022CCPC华为云1005] 带权子集和 (NTT)
    BER转Q
    针对大型商场的现状,3d全景有哪些解决方案?
    元宇宙电商-NFG系统,让你的数字藏品得到保障
    nginx详细升级步骤
    【数据结构】——链表面试题详解
  • 原文地址:https://blog.csdn.net/weixin_61933613/article/details/136519804