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引入

<!--引入处理Excel的POI类
  poi:这是Apache POI的核心模块,用于处理Excel 97-2003格式的.xls 文件。
  poi-ooxml:这个模块则用于处理Office Open XML格式的.xlsx 文件,它是基于XML的Office文件格式,对应于较新版本的Excel。
-->
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>3.16</version>
</dependency>
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>3.16</version>
</dependency>
2.2 使用POI读取Excel中数据填充对象

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

public void addProductByExcel(File destFile) throws IOException {
    // 从Excel文件中读取商品信息,并转换为商品列表
    List<Product> products = readProductsFromExcel(destFile);
    for (int i = 0; i < products.size(); i++) {
        Product product =  products.get(i);
        Product productOld = productMapper.selectByName(product.getName()); // 通过商品名称来查询数据库中是否已存在同名商品
        if (productOld != null) {  // 查询到同名商品,则抛出自定义异常
            throw  new ImoocMallException(ImoocMallExceptionEnum.NAME_EXISTED);
        }
        int count = productMapper.insertSelective(product); // 不存在同名商品,则向数据库中插入当前商品信息,存储受影响的行数
        if (count == 0) {
            throw new ImoocMallException(ImoocMallExceptionEnum.CREATE_FAILED);
        }
    }
}

private List<Product> readProductsFromExcel(File excelFile) throws IOException {
    ArrayList<Product> listProducts = new ArrayList<>();  // 用于存储读取到的商品信息
    FileInputStream inputStream = new FileInputStream(excelFile);  // 文件输入流 inputStream,用于读取Excel文件中的数据

    XSSFWorkbook workbook = new XSSFWorkbook(inputStream); // 使用XSSFWorkbook类加载输入流,创建了一个新版本的Excel工作簿workbook
    XSSFSheet firstsheet =  workbook.getSheetAt(0); // 获取第一个工作表,index从0还是1开始需要根据实际情况确认
    Iterator<Row> iterator = firstsheet.iterator();  // 通过工作表的迭代器创建一个行迭代器iterator,用于逐行遍历工作表中的数据
    while(iterator.hasNext()) {
        Row nextRow = iterator.next(); // 逐行遍历
        Iterator<Cell> cellIterator = nextRow.cellIterator();  // 逐个单元格遍历
        Product aProduct = new Product();  // 创建Product对象aProduct,用于存储当前行数据对应的商品信息
        // 读取单元格填充aProduct
        while (cellIterator.hasNext()) {
            Cell nextCell = cellIterator.next();
            int columnIndex = nextCell.getColumnIndex(); //获取单元格的索引,即列号
            switch (columnIndex) {
                case 0:
                    aProduct.setName((String) ExcelUtil.getCellValue(nextCell)); // 针对不同的列号执行相应的操作,将单元格数据填充到aProduct对象的相应属性中
                    break;
                case 1:
                    aProduct.setImage((String) ExcelUtil.getCellValue(nextCell));
                    break;
                case 2:
                    aProduct.setDetail((String) ExcelUtil.getCellValue(nextCell));
                    break;
                case 3:
                    Double cellValue = (Double) ExcelUtil.getCellValue(nextCell); // excel中数字类型默认为Double
                    aProduct.setCategoryId(cellValue.intValue());
                    break;
                case 4:
                    cellValue = (Double) ExcelUtil.getCellValue(nextCell); // excel中数字类型默认为Double
                    aProduct.setPrice(cellValue.intValue());
                    break;
                case 5:
                    cellValue = (Double) ExcelUtil.getCellValue(nextCell); // excel中数字类型默认为Double
                    aProduct.setStock(cellValue.intValue());
                    break;
                case 6:
                    cellValue = (Double) ExcelUtil.getCellValue(nextCell); // excel中数字类型默认为Double
                    aProduct.setStatus(cellValue.intValue());
                    break;
                default:
                    break;
            }
        }
        listProducts.add(aProduct); // 将填充好数据的aProduct对象添加到商品列表listProducts中
    }
    workbook.close();  // 关闭Excel工作簿
    inputStream.close();  // 关闭文件输入流
    return listProducts;
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/434718.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

errno 和 strerror函数

今天写了一个很简单的代码&#xff0c;编译时没啥错误和警告&#xff08;主要编译选项没开启警告&#xff09;&#xff0c;然后运行时居然 segmentation fault&#xff0c;把我给看傻了&#xff0c;代码如下&#xff1a; #include <stdio.h> #include <stdlib.h> …

2024护网面试题精选(一)

0x00.基础漏洞篇 00-TOP10漏洞 1.SQL注入 2.失效的身份认证和会话管理 3.跨站脚本攻击XSS 4.直接引用不安全的对象 5.安全配置错误 6.敏感信息泄露 7.缺少功能级的访问控制 8.跨站请求伪造CSRF 9.实验含有已知漏洞的组件 10.未验证的重定向和转发 01-SQL注入漏洞 …

PackagesNotFoundError:学习利用报错信息找到解决方法

反思&#xff1a;之前看到报错经常是直接复制报错信息去网上搜&#xff0c;但很多情况下报错信息里其实就给出了解决方案 报错信息&#xff1a; Collecting package metadata (current_repodata.json): done Solving environment: unsuccessful initial attempt using frozen …

关于Mybatis-Plus报错 Not Found TableInfoCache 解决办法

0. 接口结构&#xff1a;1. 方法报错&#xff1a;2. 解决方法&#xff1a;3. 原因分析&#xff1a; 0. 接口结构&#xff1a; 【接口】&#xff1a; public interface PurchaseOrderService extends IService<PurchaseOrder> {}【接口实现类】&#xff1a; public cla…

某多多anti_token(先水个文后续会完善)第一部分

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018…

某酷ckey140逆向(之前下架了重新上传补发)

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018…

[R] Underline your idea with ggplot2

Preview: # 介绍&#xff1a;之前的教程中&#xff0c;我们学习了如何使条形图或直方图看起来更好 比如&#xff1a; 1. How to select a graph calibrate the geom part 2. How to select variables calibrate the aes part 3. How to add a title calibrate the labs …

【Mybatis】批量映射优化 分页插件PageHelper 逆向工程插件MybatisX

文章目录 一、Mapper批量映射优化二、插件和分页插件PageHelper2.1 插件机制和PageHelper插件介绍2.2 PageHelper插件使用 三、逆向工程和MybatisX插件3.1 ORM思维介绍3.2 逆向工程3.3 逆向工程插件MyBatisX使用 总结 一、Mapper批量映射优化 需求: Mapper 配置文件很多时&…

16:00面试,16:08就出来了,问的问题过于变态了。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到2月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…

Sparse A*算法的时间复杂度

Sparse A*(SAS)算法是A*算法的变型算法&#xff0c;下面将结合A*算法的流程分析SAS的时间复杂度。对于SAS算法而言&#xff0c;其航迹规划的时间 T T T主要由两部分组成&#xff1a; T s T_s Ts​&#xff1a;在当前结点扩展可行子结点的时间&#xff1b; T 0 T_0 T0​&#…

Qt QPainter的使用方法

重点&#xff1a; 1.QPainter在QWidget窗口的paintEvent中使用。 2.QPainter通常涉及到设置画笔、设置画刷、绘图&#xff08;QPen、QBrush、drawxx&#xff09;三个流程。 class Widget : public QWidget {Q_OBJECTprotected:void paintEvent(QPaintEvent *event) Q_DEC…

基于51单片机的四位并行数据主从机传输设计

基于51单片机的四位并行数据主从机传输设计[proteus仿真] 主从机通信系统这个题目算是课程设计和毕业设计中常见的题目了&#xff0c;本期是一个基于51单片机的四位并行数据主从机传输设计 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文…

机器学习---数据分割

之前的文章中写过&#xff0c;我们可以通过实验测试来对学习器的泛化误差进行评估并进而做出选择。 为此&#xff0c;需使用一个“测试集"(testing set)来测试学习器对新样本的判别能力&#xff0c;然后以测试集上的“测 试误差”(testing error)作为泛化误差的近似。通…

操作系统系列学习——内核级线程实现

文章目录 前言内核级线程实现 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招&#xff0c;计划学习操作系统并完成6.0S81&#xff0c;加油&#xff01; 本文总结自B站【哈工大】操作系统 李治军&#xff08;全32讲&#xff09; 老师课程讲的非常好&#xff0c;感谢 【哈工…

Linux第71步_将linux中的多个文件编译成一个驱动模块

学习目的&#xff1a;采用旧字符设备测试linux系统点灯&#xff0c;进一步熟悉其设计原理。采用多文件参与编译&#xff0c;深度学习编写Makefile&#xff0c;有利于实现驱动模块化设计。 1、创建MyOldLED目录 输入“cd /home/zgq/linux/Linux_Drivers/回车” 切换到“/home…

softmax和sigmoid的区别

sigmoid 公式&#xff1a; s i g m o i d ( x ) 1 1 e − x sigmoid(x) \frac{1}{1 e^{-x}} sigmoid(x)1e−x1​ 函数曲线如下&#xff1a; 导数公式&#xff1a; f ( x ) ′ e − x ( 1 e − x ) 2 f ( x ) ( 1 − f ( x ) ) f(x)\prime \frac{ e^{-x}}{(1 e^{-x})…

备战蓝桥杯————二分搜索(一)

引言 一、二分查找 基本概念 代码框架 二、二分查找 题目描述 解题思路及代码 结果展示 三、寻找左侧边界的二分搜索 使用背景 基本代码 引言 在计算机科学的世界里&#xff0c;二分查找算法无疑是一种经典且强大的工具。它以其高效的性能&#xff0c;在有序数据集中…

95、评估使用多线程优化带来的性能提升

本节评估一下&#xff0c;通过对卷积的 co 维度进行多线程切分之后&#xff0c;对于模型的性能提升。 评估下性能 在进行多线程程序运行时&#xff0c;建议电脑中的 CPU 不要有其他繁重的任务执行。 在相同的环境下&#xff0c;分别运行 5th_codegen 和 6th_multi_thread 下的…

Pytorch 复习总结 6

Pytorch 复习总结&#xff0c;仅供笔者使用&#xff0c;参考教材&#xff1a; 《动手学深度学习》Stanford University: Practical Machine Learning 本文主要内容为&#xff1a;Pytorch 计算机视觉。 本文先介绍了计算机视觉中两种常见的改进模型泛化性能的方法&#xff1a…

香港投资+移民计划高峰论坛圆满落幕洞察趋势,探索未来财富之路

3月4日&#xff0c;由中国香港太阳联合资本有限公司牵头举办的「香港投资移民计划高峰论坛」在港交所圆满结束。吸引超260位高净值人士参加&#xff0c;已收到近600个投资移民意向。此次论坛汇聚了来自世界各地的投资移民专家、企业家、以及潜在投资者&#xff0c;共同探讨香港…