Apache POI 解析和处理Excel

news2025/1/20 3:50:34

摘要:由于开发需要批量导入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,最终添加到数据库的功能。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Stable Diffusion V3测评

1.引言 3月5号&#xff0c;Stability AI发布了介绍Stable Diffusion V3的研究论文&#xff0c;链接地址&#xff1a;戳我 这是目前他们发布的最先进、功能最强大的图像生成器&#xff0c;与一年多前发布的令人印象深刻的 Stable Diffusion V2.1 相比有了大幅升级。SD3所带来的…

redis进阶(一)

文章目录 前言一、Redis中的对象的结构体如下&#xff1a;二、压缩链表三、跳跃表 前言 Redis是一种key/value型数据库&#xff0c;其中&#xff0c;每个key和value都是使用对象表示的。 一、Redis中的对象的结构体如下&#xff1a; /** Redis 对象*/ typedef struct redisO…

软考65-上午题-【面向对象技术】-面向对象分析、设计、测试

一、面向对象分析OOA 1-1、面向对象分析的定义 面向对象分析的目的&#xff1a;为了获得对应用问题的理解。理解的目的是确定系统的功能、性能要求。 面向对象分析包含5个活动&#xff1a;&#xff08;背&#xff01;&#xff09; 认定对象&#xff1b;&#xff08;重要一点…

爆肝!Claude3与ChatGPT-4到底谁厉害,看完你就知道了!

前言&#xff1a; 相信大家在pyq都被这张图片刷屏了把~ 昨天&#xff0c;为大家介绍了一下什么是Claude&#xff0c;今天咱终于弄到号了&#xff08;再被ban了3个号之后终于是成功的登上去了&#xff0c;如果各位看官觉得咱文章写的不错&#xff0c;麻烦点个小小的关注~你们的…

android开发基础有哪些,985研究生入职电网6个月

不好意思久等了 这篇文章让小伙伴们久等了。 一年多以来&#xff0c;关于嵌入式开发学习路线、规划、看什么书等问题&#xff0c;被问得没有一百&#xff0c;也有大几十次了。但是无奈自己对这方面了解有限&#xff0c;所以每次都没法交代&#xff0c;搞得实在不好意思。 但…

Linux conntrack和iptables技术解析

Linux虚拟文件系统管理技术 1. netfilter解析1.1 netfilter的基础原理1.2 netfilter的相关hook 2. conntrack解析2.1 conntrack的基础原理2.2 conntrack的表记录解析 3. iptables解析3.1 iptables基础原理3.2 融合conntrack表的iptables规则 4. 疑问和思考4.1 conntrack和iptab…

【vue3之组合式API】

组合式API 一、setup1.写法2.如何访问3.语法糖4.同步返回对象 二、reactive()和ref()1.reactive()2.ref() 三、computed四、watch函数1侦听单个数据2.侦听多个数据3. immediate4. deep5.精确侦听对象的某个属性 五、生命周期函数六、组件通信1.父传子2. 子传父 七、模版引用1. …

【C++精简版回顾】20.模板的使用

1.模板起源 1.模板的定义 1.针对函数属性模板 //针对函数属性 template <class VOID > VOID print1(int a) {cout << a << endl; } 2.针对数据属性模板 //针对数据属性 template <typename INT,typename FLOAT> void print2(INT a,FLOAT b) {cout <…

网工内推 | 华为成都研究所,24届应届生人才储备计划

华为成都研究所 招聘岗位 网络工程师&#xff08;2024应届&#xff09; 岗位要求 24届的学员 本科公办院校 英语4/6级 有HCIP优先 工作地点 成都 私信小编&#xff0c;回复【内推】&#xff0c;获取内推名额申请资格~ 想获取更多『 思科 | 华为 | 红帽 认证真题 』、『 网…

正向代理和反向代理区别

正向代理和反向代理的区别&#xff1a; 特点正向代理反向代理位置位于客户端和目标服务器之间位于目标服务器和客户端之间代理对象代理服务器代表客户端发送请求到目标服务器代理服务器代表目标服务器接收客户端的请求配置客户端需要手动配置代理服务器客户端不需要知道代理服…

Redis(5.0)

1、什么是Redis Redis是一种开源的、基于内存、支持持久化的高性能Key-Value的NoSQL数据库&#xff0c;它同时也提供了多种数据结构来满足不同场景下的数据存储需求。 2、安装Redis&#xff08;Linux&#xff09; 2.1、去官网&#xff08;http://www.redis.cn/&#xff09;下…

7、Redis-事务、持久化、内存淘汰机制和过期key处理

目录 一、事务 二、持久化 三、内存淘汰机制 四、过期key处理 一、事务 Redis的事务本质上就是一个批量执行命令的操作。分为三个步骤&#xff1a; 开始事务&#xff1a;multi命令入队&#xff1a;正常输入命令即可执行事务&#xff08;依次执行命令&#xff09;&#xf…

最近开发中遇到的一些问题

puppeteer下载失败问题 使用的淘宝镜像&#xff0c;但执行命令npm i puppeteer之后&#xff0c;报错&#xff1a; npm ERR! code 1 npm ERR! path E:\项目-临时\test_install_puppeteer\node_modules\puppeteer npm ERR! command failed npm ERR! command C:\WINDOWS\system3…

Android开发教程入门,那些被大厂优化的程序员们

Binder原理 1、概述 Android系统中&#xff0c;涉及到多进程间的通信底层都是依赖于Binder IPC机制。例如当进程A中的Activity要向进程B中的Service通信&#xff0c;这便需要依赖于Binder IPC。不仅于此&#xff0c;整个Android系统架构中&#xff0c;大量采用了Binder机制作…

数据库原理(关系代数)

1.集合运算符基础 要求&#xff1a; 具有相同的目n&#xff08;即两个关系都有n 个属性&#xff09;相应的属性取自同一个域t是元组变量&#xff0c; t R表示t是R的一个元组 1.1并 符号&#xff08;&#xff09; R∪S { t|t R∨t S } 结果特征&#xff1a; 仍为n 目关…

长度为n的数组a初始值全为0,目标是把数组a变为数组b(1<=bi<=n), 可以进行任意次操作:选择长度为k的数组c,(1<=ci<=n且两两不同)

对于1<i<k, 把 a[c[i]] 改为c[i % k 1]。给定n&#xff0c;k和数组b&#xff0c;判断能否得到数组b。 题目 思路&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #d…

python使用zmail实现邮件发送

一&#xff1a;zmail介绍 1、Zmail的优势 自动填充大多数导致服务端拒信的头信息&#xff08;From To LocalHost之类的)将一个字典映射为email&#xff0c;构造信件就像构造字典一样简单自动寻找邮件服务商端口号地址&#xff0c;自动选择合适的协议&#xff08;经过认证的&am…

docker 安装 portainer

小编给友友们总结了一下 Portainer 的好处以下 Portainer是Docker的图形化管理工具&#xff0c;提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作&#xff08;包括上传下载镜像&#xff0c;创建容器等操作&#xff09;、事件日志显示、容器控制台操作、Swar…

CAPL - 如何实现弹窗提示和弹窗操作

目录 函数介绍 TestWaitForTesterConfirmation Example 使用方法一 使用方法二

Hack The Box-Perfection

目录 信息收集 nmap dirsearch gobuster whatweb WEB 信息收集 ffuf 漏洞探索 漏洞发现 模板注入 反弹shell 提权 get user and flag 信息收集 ssh登录&get root and flag 信息收集 nmap 端口探测┌──(root㉿ru)-[~/kali/hackthebox] └─# nmap -p- 10…