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

Spring boot接收zip包并获取其中excel文件的方法

1、问题

 工作中遇到一个需求,接收一个zip包,读取其中的excel文件并处理,减少用户多次选择目录和文件的痛点,该zip包包含多级目录

2、依赖

 需要用到apache的Workbook类来操作Excel,引入以下依赖

<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.9</version>
</dependency>

3、具体实现

public List<Workbook> getExcelsFromZip(MultipartFile multipartFile) {ZipInputStream zis = null;List<Workbook> workbooks = new ArrayList<>();try {// 构建zip流zis = new ZipInputStream(multipartFile.getInputStream());// 获取文件条目,此方法读取的问zip包中所有条目(目录和文件),多级目录下的所有文件和目录均会被读取ZipEntry zipEntry = zis.getNextEntry();while (zipEntry != null) {// 判断类型是否为文件if (!zipEntry.isDirectory()) {// 获取文件名String fileName = zipEntry.getName();/* 后缀名 */int suffixIndex = fileName.lastIndexOf(".");String suffix = suffixIndex >= 0 ? fileName.substring(suffixIndex) : "";// 判断是否为excel文件if (".xls".equals(suffix) || ".xlsx".equals(suffix)) {/* 读取文件 */ByteArrayOutputStream out = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len;// 在调用了getNextEntry()后,zis就指向了获取到的ZipEntry,读取zis流实际就是读取当前ZipEntry,不会读取到其他条目while ((len = zis.read(buffer)) > 0) {out.write(buffer, 0, len);}ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());/* 构建Workbook */Workbook wb;if (".xls".equals(suffix)) {// 老版excel格式,使用HSSFWorkbookwb = new HSSFWorkbook(in);}else {// 新版excel格式,使用XSSFWorkbookwb = new XSSFWorkbook(in);}workbooks.add(wb);// 关闭当前ZipEntry,确保不会重复处理zis.closeEntry();// 获取下一条目zipEntry = zis.getNextEntry();}}}} catch (IOException e) {throw new RuntimeException(e);}finally {if (zis != null) {try {zis.close();} catch (IOException e) {throw new RuntimeException(e);}}}return workbooks;}

3、技术要点

(1)ZipInputStream.getNextEntry()方法

 【1】该方法可获取到zip包内的各级目录及各级目录下的文件,并不需要进行递归处理。
 【2】ZipInputStream实例调用该方法后,将会指向获取到的条目,这时使用ZipInputStream实例操作的就是获取到的ZipEntry对象。可通过ZipInputStream.closeEntry()和ZipInputStream.getNextEntry()迭代到下一个ZipEntry条目。

(2)为什么选择ByteArrayInputStream和ByteArrayInputStream获取Workbook

 二者是在内存中处理字节的IO流,不同于磁盘IO流会在磁盘中创建临时文件读写,处理速度会更快,在内存中处理数据也符合业务需求。

(3)为什么不使用Workbook wb = WorkbookFactory.create(zis);直接转化

  实测使用WorkbookFactory.create(zis)会关闭流,导致无法读取后续条目

http://www.lryc.cn/news/180386.html

相关文章:

  • Ubuntu镜像源cn.arichinve.ubuntu.com不可用原因分析和解决
  • Java基础面试,String,StringBuffer,StringBuilder区别以及使用场景
  • 基于SpringBoot的高校学科竞赛平台
  • excel如何让线条消失,直接设置网格即可,碰到不方便的地方优先百度,再采取蛮干
  • 抖音短视频seo矩阵系统源代码开发系统架构及功能解析
  • 在pycharm中弹出图后,需要关闭才会显示Process finished with exit code 0
  • 【计算机网络笔记六】应用层(三)HTTP 的 Cookie、缓存控制、代理服务、短连接和长连接
  • Vue中的数据分页与分页组件设计
  • TCP串流场景剖析
  • Windows历史版本下载
  • 企业级磁盘阵列存储系统由硬到软全析
  • V4L2 驱动架构介绍
  • 掌握这些技巧,让Excel批量数据清洗变得简单高效!
  • 成都瀚网科技:抖音上线地方方言自动翻译功能
  • 【k8s】【docker】web项目的部署
  • 【视频去噪】基于全变异正则化最小二乘反卷积是最标准的图像处理、视频去噪研究(Matlab代码实现)
  • 国庆day3---网络编程知识点脑图整合
  • 链表经典面试题(六)
  • SM2签名算法中随机数K的随机性对算法安全的影响
  • 郁金香2021年游戏辅助技术中级班(六)
  • 毛玻璃员工卡片悬停效果
  • 闪存工作原理
  • 从0到一配置单节点zookeeper
  • 【JVM】第三篇 JVM对象创建与内存分配机制深度剖析
  • 【信创】麒麟v10(arm)-mysql8-mongo-redis-oceanbase
  • maven settings.xml文件(包含了配置阿里云镜像)
  • 分类预测 | MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结合支持向量机分类预测
  • Redis是否要分库的实践
  • String 进阶
  • ESP32设备通信-两个ESP32间UART通信