【Apache POI】百万级数据导出Excel,并含有折线等图表

news2024/11/19 23:19:48

   需求概要

        最近接到一个需求,概要来讲就是实现百万级数据导出Excel,并根据其中的数据项自动生成折线图等图表。经技术调研,针对内存、性能等要素,Apache POI此技术可完成此需求。


        Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式文件读和写的功能。 .NET的开发人员则可以利用NPOI(POI for .NET)来访问POI的功能。

   总结构

  • HSSF - 提供读写Microsoft Excel XLS 格式文件的功能。
  • XSSF - 提供读写Microsoft Excel OOXML XLSX 格式文件的功能。
  • HWPF - 提供读写Microsoft Word DOC 格式文件的功能。
  • XWPF - 提供读写Microsoft Word DOCX 格式文件的功能。
  • HSLF - 提供读写Microsoft PowerPoint格式文件的功能。
  • HDGF - 提供读Microsoft Visio格式文件的功能。
  • HPBF - 提供读Microsoft Publisher格式文件的功能。
  • HSMF - 提供读Microsoft Outlook格式文件的功能。

 结构图

Apache POI发行版支持多种文档文件格式。这种支持在几个Jar文件中提供。并不是每种格式都需要所有的Jar。下表显示了POI组件、Maven存储库标记和项目的Jar文件之间的关系。

组件应用类型Maven 工件名
POIFSOLE2 Filesystempoi
HPSFOLE2 Property Setspoi
HSSFExcel XLSpoi
HSLFPowerPoint PPTpoi-scratchpad
HWPFWord DOCpoi-scratchpad
HDGFVisio VSDpoi-scratchpad
HPBFPublisher PUBpoi-scratchpad
HSMFOutlook MSGpoi-scratchpad
DDFEscher common drawingspoi
HWMFWMF drawingspoi-scratchpad
OpenXML4JOOXMLpoi-ooxml plus either poi-ooxml-lite or
poi-ooxml-full
XSSFExcel XLSXpoi-ooxml
XSLFPowerPoint PPTXpoi-ooxml
XWPFWord DOCXpoi-ooxml
XDGFVisio VSDXpoi-ooxml
Common SLPowerPoint PPT and PPTXpoi-scratchpad and poi-ooxml
Common SSExcel XLS and XLSXpoi-ooxml


该表将工件映射到jar文件名中。“版本yyyymmdd”是POI版本戳。

Maven 工件名先决条件
poi

log4j 2.x, commons-codec, 

commons-collections, 

commons-math3 commons-io

poi-scratchpadpoi
poi-ooxml

poi, poi-ooxml-lite, commons-compress,

 SparseBitSet
For SVG support: batik-all, xml-apis-ext, 

xmlgraphics-commons
For PDF support: pdfbox, fontbox, 

rototor graphics2d

poi-ooxml-litexmlbeans
poi-examplespoi, poi-scratchpad, poi-ooxml
poi-ooxml-full (known as ooxml-schemas)

xmlbeans
For signing: bcpkix-jdk18on, bcprov-jdk18on,

 xmlsec, slf4j-api

注意:
在POI4.0.0中添加了Apache commons-math3和commons-compression作为依赖项。
Zaxxer SparseBitSet被添加为POI 4.1.2中的依赖项
在POI 5.1.0中添加了Apache commons io作为依赖项


问题:

1.利用poi生成excel折线图,图无法在office excel中显示【发现...中的部分内容有问题。是否让我们尽量尝试恢复?如果您信任此工作簿的源,请单击“是”】

        排查问题发现:Office Excel版本为最新:(现版本为MS 365系列,Excel版本为2311.)而Apache POI相关依赖过旧,更新为最新依赖,则排除此问题。

2.【ERROR】apache POI java.lang.NoClassDefFoundError: org/apache/commons/compress/archivers/zip/ZipFile

        调整相关依赖版本为最新:

 <!--poi-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-lite</artifactId>
            <version>5.2.5</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>5.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-full</artifactId>
            <version>5.2.5</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.4</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>1.25.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlbeans</groupId>
            <artifactId>xmlbeans</artifactId>
            <version>5.2.0</version>
        </dependency>

3.大量数据导出注意使用SXSSFWorkbook处理Excel文件(.xlsx)的工作簿

  • XSSFWorkbook:XSSFWorkbook是POI中的XLSX格式(Excel 2007及更高版本)的工作簿实现。它使用XML文件格式存储数据,并且在内存中将整个工作簿加载到内存中进行操作。这意味着对于大型或复杂的Excel文件,可能会占用大量的内存。
  • SXSSFWorkbook:SXSSFWorkbook是POI中的SXSSF流式工作簿实现。它专为处理大型Excel文件而设计,并通过限制内存使用来提供更好的性能和可伸缩性。它使用一种称为流式写入(Streaming Write)的技术,在内存中只保留一部分数据,然后将其写入硬盘,以便在需要时释放内存。

主要区别:

  • 内存占用:XSSFWorkbook会将整个工作簿加载到内存中,而SXSSFWorkbook只保留部分数据,将剩余数据写入硬盘。
  • 性能和可伸缩性:SXSSFWorkbook在处理大型Excel文件时可以获得更好的性能和可伸缩性,因为它可以有效地处理大量数据而无需消耗大量内存。
  • 使用场景:如果处理的Excel文件较小或简单,可以使用XSSFWorkbook。如果需要处理大型Excel文件或需要更好的性能和可伸缩性,则可以考虑使用SXSSFWorkbook。

        总之,XSSFWorkbook适用于较小的Excel文件,而SXSSFWorkbook适用于大型或复杂的Excel文件。选择哪个取决于具体需求和资源限制。当然亦可选取学习成本更低且对内存消耗更低的EasyExcel实现大数据导出

4.【ERRO】Exception in thread "Thread-0" org.apache.poi.ooxml.POIXMLException:org.apache.poi.openxml4j.exceptions.InvalidOperationException: You can't add a part with a part name derived from another part ! [M1.11]

        注意POI中XSSFWorkbook不可采用多线程写入不同sheet:

5.SXSSFDrawing不可生成Chart图表,XSSFDrawing可实现此功能。

        SXSSFDrawing是Apache POI库中的一种轻量级方式来处理大型Excel文件,它主要用于写入和操作Excel文件,而不是生成图表。可以使用XSSFWorkbookXSSFSheet类来创建图表,并使用相应的数据填充图表。

6.SXSSFWorkbook的close和dispose

        Apache POI库中的SXSSFWorkbook(Streaming Usermodel for Excel)是一种用于处理大型Excel文件的类,特别适用于内存有限的情况。它通过限制在内存中保持的数据行数来实现流式写入。

1. `close()`方法:
   - 当你完成对工作簿的所有操作后,应调用`close()`方法。此方法会将任何未写出到磁盘的剩余数据强制写出,并关闭所有相关的资源,如临时文件等。
   - 如果不调用`close()`,可能会导致部分数据未被正确保存到输出文件,或者占用的系统资源没有被释放。

2. `dispose()`方法:
   - 在POI 5.0.0版本之后,SXSSFWorkbook引入了`dispose()`方法作为替代`close()`的方法。
   - `dispose()`方法同样用于清理和关闭SXSSFWorkbook对象,确保所有数据都被妥善地写出,并释放与之关联的资源。
   - 官方推荐使用`dispose()`而不是`close()`,因为`dispose()`在内部会更彻底地清理资源,特别是对于SXSSF工作簿来说,可以更有效地管理其使用的临时文件。

总结:在使用完SXSSFWorkbook后,建议调用`dispose()`方法以确保所有数据被正确写入并释放资源。在旧版本POI中如果不存在`dispose()`,则应该调用`close()`。

7.利用XSSFWorkbook生成图表,导致系统堆内存剧增

  • org.apache.xmlbeans.impl.store.ElementXobj    347,831,616 B (21.1%)    3,623,246 (11.1%)
  • org.apache.xmlbeans.impl.store.AttrXobj    314,479,968 B (19%)    3,275,833 (10%)
  • byte[]    286,741,680 B (17.3%)    5,227,004 (15.9%)

        经过研究POI API文档发现,SXSSFWorkbook可利用getXSSFWorkbook方法获取XSSFSheet,之前由于不了解POI,为了利用XSSFSheet生成图表,竟然玩起了俄罗斯套娃,将SXSSFWorkbook写入ByteArrayOutputStream流中,再通过构造器new XSSFWorkbook(new ByteArrayInputStream(baos.toByteArray()))获取XSSFWorkbook对象,进而生成图像,导致JVM堆内存剧增!

       致使内存剧增的代码:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            wb.write(baos);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
             xssfWB = new XSSFWorkbook(new ByteArrayInputStream(baos.toByteArray()));

            for (DeviceInfoBO item : deviceInfoBOList) {
                XSSFSheet xssfSheet = xssfWB.getSheet(item.getSheetName());
                //TODO 生成图表
            }
            return new SXSSFWorkbook(xssfWB);
        } catch (IOException e) {
            e.printStackTrace();
        }

        优化后的代码:

XSSFSheet xssfSheet = wb.getXSSFWorkbook().getSheet(deviceInfoBO.getSheetName());
//TODO 生成图表

        优雅从不过时~

        效果图:

参考资料:

Apache POI简介icon-default.png?t=N7T8https://en.wikipedia.org/wiki/Apache_POIApache POI官网icon-default.png?t=N7T8https://poi.apache.org/index.htmlApache POI官网代码示例icon-default.png?t=N7T8https://svn.apache.org/repos/asf/poi/trunk/poi-examples/src/main/java/org/apache/poi/examples/

stackoverflow相关BUG解决icon-default.png?t=N7T8https://stackoverflow.com/questions/52381075/apache-poi-java-lang-noclassdeffounderror-org-apache-commons-compress-archivers

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

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

相关文章

《教我兄弟学Android逆向15 xpose改机开发03-写一款自己的改机软件》

上一篇 《教我兄弟学Android逆向14 xpose改机开发02-改机代码基础编写》我带你熟悉了一下改机的流程,搭建了改机的基础代码,改机参数数据储存方面我们用的是SharedPreferences存储数据,界面方面写了一个一键新机的按钮,点一键新机的时候会随机生成imei数据存储到xml数据中,然后…

isctf---re

crackme 解压得到crackme.exe 运行得到flag babyRe 先猜e65537的rsa 先用Z3强行求出p、q&#xff0c;算出常规rsa中的phi&#xff0c;然后套用公式求出m exp #babyre wp from z3 import * import libnum from Crypto.Util.number import * p,q,cInts(p q c) S Solver() S…

【前端web入门第一天】02 HTML图片标签 超链接标签 音频标签 视频标签

文章目录: 1.HTML图片标签 1.1 图像标签-基本使用1.2 图像标签-属性1.3 路径 1.3.1 相对路径 1.3.2 绝对路径 2.超链接标签 3.音频标签 4.视频标签 1.HTML图片标签 1.1 图像标签-基本使用 作用:在网页中插入图片。 <img src"图片的URL">src用于指定图像…

前端框架---Vue2学习教程(上)

从HTML到现在一路跟过来的小伙伴们&#xff0c;坚持固然不容易&#xff0c;但我相信大家已经学到了不少&#xff0c;那么我们开始马不停蹄的进入前端的框架吧&#xff0c;下面讲的是Vue2&#xff0c;大家继续加油鸭&#xff01;&#xff01;&#xff01;&#xff01; Vue2 Vu…

遗传算法优化最大化效应的某些需求点可不配送的vrptw问题

标题&#xff1a;遗传算法优化最大化效应的某些需求点可不配送的vrptw问题 摘要&#xff1a; 在可不配送的车辆路径配送问题&#xff08;VRPTW&#xff09;中&#xff0c;我们面临着优化路径规划以最大化效用的挑战。本文提出了一种基于遗传算法的方法&#xff0c;旨在解决具…

【Shell实战案例面试题】输入网卡的名字,来输出网卡的IP

1.问题 参数后判断要加"" 名字为空时显示ip 2.分析 把本机的所有网卡名列出来&#xff0c;来引导用户输入 使用命令列出所有网卡信:ifconfig/ip a 设计一个函数&#xff0c;把网卡名作为参数&#xff0c;函数返回网卡的IP 在获取某个网卡IP时&#xff0c;考虑网…

Redis面试(三)

1.Redis报内存不足怎么处理 Redis内存不足的集中处理方式&#xff1a; 修改配置文件redis.cof的maxmemory参数&#xff0c;增加Redis的可用内存通过命令修改set maxmemory动态设置内存上限修改内存淘汰策略&#xff0c;及时释放内存使用Redis集群&#xff0c;及时进行扩容 2…

基于springboot的美发管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

让Unity迭代器性能提升5倍

最近在研究Unity il2cpp的代码生成和编译优化&#xff0c;结合之前遇到过的一个优化案例&#xff0c;给大家讲讲在Unity中迭代器相关代码生成的底层原理&#xff0c;以及在写代码过程中需要注意的一些特殊情况。 案例 首先我们来看一个非常简单的案例&#xff0c;代码如下&am…

3338 蓝桥杯 wyz的数组IV 简单

3338 蓝桥杯 wyz的数组IV 简单 //C风格解法1&#xff0c;通过率50% #include<bits/stdc.h>int main(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);int n; std::cin >> n;int ans 0;std::vector<int>a(n);for(auto &am…

Docker本地部署APITable结合内网穿透实现公网访问

文章目录 前言1. 部署APITable2. cpolar的安装和注册3. 配置APITable公网访问地址4. 固定APITable公网地址 前言 vika维格表作为新一代数据生产力平台&#xff0c;是一款面向 API 的智能多维表格。它将复杂的可视化数据库、电子表格、实时在线协同、低代码开发技术四合为一&am…

【C语言】socket编程接收问题

一、recv()函数接收到的返回值为0表示对端已经关闭 在TCP套接字编程中&#xff0c;通过recv()函数接收到的返回值为0通常表示对端已经关闭了套接字的发送部分。这是因为TCP是一个基于连接的协议&#xff0c;其中有定义明确的连接建立和终止流程&#xff1b;当对端调用close()或…

C语言指针进阶(1)(超详细)

前言&#xff1a; 指针其实就是地址&#xff0c;而凡是存储在内存中的值都会有属于自己的地址&#xff0c;指针指向地址&#xff0c;这样我们就能通过指针间接操作变量。我们在指针初阶中介绍了指针的基本概念&#xff1a;如指针大小、野指针问题、指针间的关系运算等&#xff…

Hugging Face创始人分享:企业如何在ChatGPT浪潮下实现战略布局

Hugging Face创始人兼首席执行官 Clem Delangue在IBM一年一度的 THINK大会中研讨了当前人工智能发展趋势&#xff0c;特别是ChatGPT模型以及其对行业的影响。他的演讲还涉及到一个关键的议题&#xff0c;在ChatGPT这样的通用模型出现后&#xff0c;企业如何在人工智能领域找到自…

自定义vue通用左侧菜单组件(未完善版本)

使用到的技术: vue3、pinia、view-ui-plus 实现的功能: 传入一个菜单数组数据,自动生成一个左侧菜单栏。菜单栏可以添加、删除、展开、重命名,拖动插入位置等。 效果预览: 代码: c-menu-wrap.vue <template><div class="main-container">&l…

【嵌入式学习】C++QT-Day3-C++基础

笔记 见我的博客&#xff1a;https://lingjun.life/wiki/EmbeddedNote/19Cpp 作业 设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函…

当包容结构体遇见灵活的内存管理

&#x1f308;个人主页&#xff1a;小田爱学编程 &#x1f525; 系列专栏&#xff1a;c语言从基础到进阶 &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于c语言的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎来到小田代码世界~ &#x…

课时7:shell基础_shell简介

1.3.1 shell简介 学习目标 这一节&#xff0c;我们从 运维、shell语言、小结 三个方面来学习。 运维 简介 运维是什么&#xff1f;所谓的运维&#xff0c;其实就是公司的内部项目当中的一个技术岗位而已&#xff0c;它主要做的是项目的维护性工作。它所涉及的内容范围非常…

方法、数组

方法 是语句的集合&#xff0c;在一起执行一个功能 它是解决一类问题的步骤的有序集合 包含于类或对象中 在程序中创建&#xff0c;在其他地方被引用 设计方法的原则&#xff1a;方法的本意是功能块&#xff0c;就是实现某一个功能的语句块的集合。设计时&#xff0c;最好保持…

基于go mod模式创建项目最佳实践

希望能带给你成功的喜悦&#xff01; 除go get、vendor这两种方式外&#xff0c;Go版本在1.11之后推出了go module模式来管理依赖&#xff0c;使用go mod时下载的依赖文件在$GOPATH/pkg/mod/下。本文以两种办法介绍如何创建go mod项目。 目录 goland开启玩法 本地手动创建项目…