当前位置: 首页 > news >正文

使用Hutool-poi封装Apache POI进行Excel的上传与下载

介绍

Hutool-poi是针对Apache POI的封装,因此需要用户自行引入POI库,Hutool默认不引入。到目前为止,Hutool-poi支持:

  • Excel文件(xls, xlsx)的读取(ExcelReader)
  • Excel文件(xls,xlsx)的写出(ExcelWriter)

#使用

#引入POI依赖

推荐引入poi-ooxml,这个包会自动关联引入poi包,且可以很好的支持Office2007+的文档格式

<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>${poi.version}</version>
</dependency>

如果需要使用Sax方式读取Excel,需要引入以下依赖(POI-4.x以上这个非必须):

<dependency><groupId>xerces</groupId><artifactId>xercesImpl</artifactId><version>${xerces.version}</version>
</dependency>

说明
hutool-4.x的poi-ooxml 版本需高于 3.17(别问我3.8版本为啥不行,因为3.17 > 3.8 )
hutool-5.x的poi-ooxml 版本需高于 4.1.2
hutool-5.6.x支持poi-ooxml 版本高于 5.0.0
xercesImpl版本高于2.12.0(非必须)

引入后即可使用Hutool的方法操作Office文件了,Hutool提供的类有:

  • ExcelUtil Excel工具类,读取的快捷方法都被封装于此
  • ExcelReader Excel读取器,Excel读取的封装,可以直接构造后使用。
  • ExcelWriter Excel生成并写出器,Excel写出的封装(写出到流或者文件),可以直接构造后使用。

#常见问题

部分用户使用POI模块时会提示:

You need to add dependency of 'poi-ooxml' to your project, and version >= 4.1.2

一般以下几个原因:

  1. 没有引入POI相关jar或引入版本太低
  2. 引入了多个版本的POI,导致包冲突了
  3. 没有引入关联依赖,这个具体要看下堆栈中的Cause By

Excel上传和下载

Excel上传

前端

<el-form-item> <el-upload :shaw-file-list="false" :on-change="onChange" :auto-upload="false"> <el-button type="primary">&nbsp导入</el-button></el-upload></el-form-item>const onChange = (uploadFile: any, _uploadFiles: any) => {let name = uploadFile.namelet reader = new FileReader()reader.readAsDataURL(uploadFile.raw) // 异步的读reader.onload = (file) => {callUploadApi(name, file.target?.result)}}const callUploadApi = (name: string, base64: any) => {productApi.upload.call({ name, base64 }).then((res: any) => {ElMessage.success("上传成功")})
}

后端

@PostMapping("upload")public String upload(@RequestBody UploadDto uploadDto) throws IOException {String base64 = uploadDto.getBase64();String[] base64s = StrUtil.splitToArray(base64, "base64,");byte[] decode = Base64.decode(base64s[1]);//用于创建一个基于字节数组的输入流。它允许你从一个字节数组中读取数据。ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decode);//创建Excel读取器,用于后续的Excel数据读取操作ExcelReader reader = ExcelUtil.getReader(byteArrayInputStream);//通过反射机制读取所有产品数据。List<Product> readAll = reader.readAll(Product.class);productService.insert(readAll);byteArrayInputStream.close();return "success";}

Excel下载

前端

<el-form-item><el-button type="primary" @click="exportExcel">&nbsp导出                    </el-button></el-form-item>const exportExcel = () => {let name = formData.name == '' ? undefined : formData.namewindow.open('/api/pro/download?name='+name, '_blank', '')
}

后端

 @GetMapping("download")public void download(HttpServletResponse response, ProductQuery productQuery) throws IOException {List<Product> productList = productService.select(productQuery);// 初始化Excel写入器 加true指定Excel文件是xlsx格式ExcelWriter writer = ExcelUtil.getWriter(true);writer.addHeaderAlias("id", "Id");writer.addHeaderAlias("name", "姓名");writer.addHeaderAlias("subName", "介绍");writer.addHeaderAlias("status", "状态");writer.addHeaderAlias("price", "价格");// 写入当前批次的数据writer.write(productList,true);//response为HttpServletResponse对象   设置响应的内容类型为Excel文件response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("UTF-8");//test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码//设置响应头,告诉浏览器以附件形式下载文件,文件名为test.xlsx。这样设置可以让浏览器弹出文件下载对话框。String time = System.currentTimeMillis() +"";response.setHeader("Content-Disposition", "attachment;filename=product"+time+".xlsx");//获取响应输出流,它是用于将响应的数据发送给客户端的流。ServletOutputStream out = response.getOutputStream();//将Excel数据写入输出流。第二个参数为true表示追加写入,即将数据追加到已有的Excel文件中。writer.flush(out, true);//关闭输出流out.close();}

通过线程池来完成百万级别数据插入

通过线程池来完成百万级别数据插入

相关文章:

  • 将图片资源保存到服务器的盘符中
  • FGPA实验——触摸按键
  • 3D 模型GLTF、GLB格式文件介绍使用;FBX格式
  • Linux网络之UDP与TCP协议详解
  • 水面巡检船垃圾漂浮物检测系统源码分享
  • AI智能时代:哪款编程工具让你的工作效率翻倍?
  • 前端vuex
  • 【HarmonyOS】分页滚动文本组件
  • C++不同的头文件中各种函数的操作使用(长期更新,找到新的就补充进来)
  • IntelliJ IDEA 2024.1.4 (Ultimate Edition)找不到Add Framework Support解决方法
  • 【MySQL】基本查询
  • 侧边菜单的展开和折叠
  • 领域驱动DDD三种架构-分层架构、洋葱架构、六边形架构
  • 通过openAI的Chat Completions API实现一个支持追问的ChatGPT功能集成
  • 初试AngularJS前端框架
  • [deviceone开发]-do_Webview的基本示例
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • 07.Android之多媒体问题
  • Android框架之Volley
  • CSS 专业技巧
  • Date型的使用
  • golang中接口赋值与方法集
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • Promise面试题2实现异步串行执行
  • Python_网络编程
  • Python连接Oracle
  • Python学习之路16-使用API
  • Web设计流程优化:网页效果图设计新思路
  • 包装类对象
  • 创建一个Struts2项目maven 方式
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 两列自适应布局方案整理
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 通过git安装npm私有模块
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • 整理一些计算机基础知识!
  • ​LeetCode解法汇总518. 零钱兑换 II
  • ​secrets --- 生成管理密码的安全随机数​
  • # .NET Framework中使用命名管道进行进程间通信
  • (70min)字节暑假实习二面(已挂)
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (一)Docker基本介绍
  • .gitignore
  • .htaccess 强制https 单独排除某个目录
  • .NET : 在VS2008中计算代码度量值
  • .net core docker部署教程和细节问题
  • .net core 管理用户机密
  • .NET 服务 ServiceController
  • .Net 中Partitioner static与dynamic的性能对比
  • .NET简谈设计模式之(单件模式)
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc