使用POI导出数据以及性能比较

这篇具有很好参考价值的文章主要介绍了使用POI导出数据以及性能比较。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、背景

工作中难免会遇到一些导入导出数据的需求,寻找一个好用的工具是很重要的,找一款合适的工具要考虑多种因素,比如导出效率、导出过程占用内存的大小。由于Apache POI在使用过程中问题比较多,所以个人不推荐使用,常见好用的工具有EasyPOI、EasyExcel。这二者都是基于Apache POI实现的,所以本文先从Apache POI进行讲解。

2、POI介绍

2.1、POI概念

poi其英文全称“Poor Obfuscation Implementation”,意思是“简易的模糊实现”,它是Apache提供的一款免费开源跨平台的Java API,其提供的API应用于Java程序,实现对Microsoft Office格式的文档读和写功能。

官网地址

2.2、POI相关API

poi的几个重要的API:

HSSF - 提供读写Microsoft Excel格式档案的功能(.xls后缀)。优点是过程中写入缓存,不操作磁盘,最后一次性写入磁盘,导出数据速度快,但是导出数据最大行数是65536行,最大列数是256列。

XSSF - 提供读写Microsoft Excel OOXML格式档案的功能(.xlsx后缀)。XSSF支持的2007版的xlsx文件是基于XML的,因此处理它们的内存占用比HSSF支持的2003版的xls文件(基于二进制文件)要高。优点是可以导出较大的数据量,缺点导出速度慢,非常消耗内存,也会发生内存溢出,如100万条数据。

SXSSF - 是 XSSF API的兼容流式扩展,主要解决当使用 XSSF 方式导出大数据量时,内存溢出的问题,采用缓存方式进行大批量写文件。优点是可以写较大的数据量,写数据速度快,占用更少的内存。

扩展说明:

(1)过程中会产生临时文件,需要清理临时文件

(2)默认有100条记录被保存在内存中,如果超过这个数量,则最前面的数据被写入临时文件

(3)如果想自定义内存中数据的数量,可以使用new SXSSFWorkbook(数量)

HWPF(.doc后缀)- 提供读写Microsoft Word格式档案的功能(XWPF(.docx后缀):Microsoft Word OOXML格式)。

HSLF(.ppt后缀) - 提供读写Microsoft PowerPoint格式档案的功能(XSLF(.pptx后缀):Microsoft Word OOXML格式)。

HDGF(.vsd后缀) - 提供读写Microsoft Visio格式档案的功能(XDGF(.vsdx后缀):Microsoft Word OOXML格式)。

2.3、Excel2003与Excel2007

  • 两个版本的最大行数和列数不同,2003版最大行数是65536行,最大列数是256列,2007版及以后的版本最大行数是1048576行,最大列数是16384列。
  • excel2003是以二进制的方式存储,这种格式不易被其他软件读取使用;而excel2007采用了基于XML的ooxml开放文档标准,ooxml使用XML和ZIP技术结合进行文件存储,XML是一个基于文本的格式,而且ZIP容器支持内容的压缩,所以其一大优势是可以大大减小文件的尺寸。

2.3、POI读取excel的两种模式

一种是userModel,即用户模式,一种是eventModel,即sax事件驱动模式。

(1)userModel

用户模式的API接口丰富,平时使用最多的像用的HSSFWorkBook、XSSFWorkBook、SXSSFWorkBook。但是这种模式消耗内存很大,当遇到很大sheet、大数据网格、假空行、公式等问题时,很容易导致内存溢出。

POI官方推荐解决内存溢出的方式使用CVS格式解析,即SAX事件驱动模式。

(2)eventModel

这种模式将xlsx格式的文档转换成CSV格式后进行读取。

3、POI实现Excel文件导出

3.1、操作流程

(1)创建HSSFWorkbook/XSSFWorkbook/SXSSFWorkbook对象,一个excel对应一个workbook。

(2)用实例化好的Workbook创建sheet对象(一个workbook中有多个Sheet组成)。

(3)用实例化好的Sheet对象创建Row(行)对象,用Row对象创建Cell(单元格)对象(一个sheet是由多个行(row)和列(cell)组成)。

(4)对创建的cell实例对象设置要导出的数据。

(5)将生成的HSSFWorkbook放入HttpServletResponse中响应到前端页面。

3.2、文件表头

poi导出,文件相关,java,excel导出

 3.3、代码实现

3.3.1、pom核心依赖

最新版本是5.2.2,建议不要用最新的,容易引起jar包不兼容的问题。

<!--poi-->
<!--xls(03)-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>
<!--xlsx(07)-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>

3.3.2、实现代码

【03版本xls】 测试导出

@GetMapping("/export03xls")
public void export03xls(HttpServletResponse response) throws IOException {
    String fname = "【03版本xls】-测试导出";
    fname = new String(fname.getBytes("GBK"), "iso8859-1");
    OutputStream os = response.getOutputStream();
    response.reset();
    response.setHeader("Content-disposition", "attachment; filename=" + fname + ".xls");
    response.setCharacterEncoding("utf-8");
    response.setContentType("application/msexcel");

    long begin = System.currentTimeMillis();
    exportData(new HSSFWorkbook(), os);
    long end = System.currentTimeMillis();
    System.out.println("03版本时间(秒):" + ((double) (end - begin) / 1000));
}

【07版本xlxs】 测试导出

@GetMapping("/export07xlsx")
public void export07xlsx(HttpServletResponse response) throws IOException {
    String fname = "【07版本xlxs】 测试导出";
    fname = new String(fname.getBytes("GBK"), "iso8859-1");
    OutputStream os = response.getOutputStream();
    response.reset();
    response.setHeader("Content-disposition", "attachment; filename=" + fname + ".xlsx");
    response.setCharacterEncoding("utf-8");
    response.setContentType("application/msexcel");

    long begin = System.currentTimeMillis();
    exportData(new XSSFWorkbook(), os);
    long end = System.currentTimeMillis();
    System.out.println("07版本时间(秒):" + ((double) (end - begin) / 1000));
}

【07版本-加强版xlxs】 测试导出

@GetMapping("/export07Plusxlsx")
public void export07Plusxlsx(HttpServletResponse response) throws IOException {
    String fname = "【07版本-加强版xlxs】测试导出";
    fname = new String(fname.getBytes("GBK"), "iso8859-1");
    OutputStream os = response.getOutputStream();
    response.reset();
    response.setHeader("Content-disposition", "attachment; filename=" + fname + ".xlsx");
    response.setCharacterEncoding("utf-8");
    response.setContentType("application/msexcel");

    long begin = System.currentTimeMillis();
    SXSSFWorkbook workbook = new SXSSFWorkbook();
    exportData(workbook, os);
    //清除临时文件
    workbook.dispose();
    long end = System.currentTimeMillis();
    System.out.println("07加强版时间(秒):" + ((double) (end - begin) / 1000));
}

公共方法-模拟导出数据

// 模拟数据导出
private void exportData(Workbook workbook, OutputStream os) throws IOException {
    //创建一个工作表
    Sheet sheet = workbook.createSheet("第一个sheet");
    CellStyle cellStyle = getCellStyle(workbook, sheet);

    /**
     *  遍历数据-创建单元格
     *  从第五行,第二列开始
     *  列不变,行增加
     */
    // 除去表头,数据从第5行开始。一共65536条数据
    Random random = new Random();
    for (int rowNumber = 4; rowNumber < 65536; rowNumber++) {
        Row sheetRow5 = sheet.createRow(rowNumber);//创建行--创建新行会覆盖旧行
        //创建单元格
        Cell cell5_0 = sheetRow5.createCell(0);//地点
        Cell cell5_1 = sheetRow5.createCell(1);//男
        Cell cell5_2 = sheetRow5.createCell(2);//女
        Cell cell5_3 = sheetRow5.createCell(3);//总数
        //样式
        cell5_0.setCellStyle(cellStyle);
        cell5_1.setCellStyle(cellStyle);
        cell5_2.setCellStyle(cellStyle);
        cell5_3.setCellStyle(cellStyle);
        //赋值
        cell5_0.setCellValue("公司" + (rowNumber - 4));
        int manNum = random.nextInt(100);
        cell5_1.setCellValue(manNum);
        int womanNum = random.nextInt(100);
        cell5_2.setCellValue(womanNum);
        cell5_3.setCellValue(manNum + womanNum);
    }
    try {
        workbook.write(os);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //关闭资源
        os.close();
    }
}

公共方法-设置表格样式

// 设置表格样式
private CellStyle getCellStyle(Workbook workbook, Sheet sheet) {
    /**
     * 设置页边距
     * 打印前的页边距设置【设置上下左右】
     * 可以用打印预览查看
     */
    sheet.setMargin(HSSFSheet.BottomMargin, 0.1);
    sheet.setMargin(HSSFSheet.LeftMargin, 0.1);
    sheet.setMargin(HSSFSheet.RightMargin, 0.1);
    sheet.setMargin(HSSFSheet.TopMargin, 0.1);
    sheet.setHorizontallyCenter(true);//是否在页面上水平居中
    sheet.setVerticallyCenter(false);//是否在页面上垂直居中

    /**
     * 设置列宽-列从0开始
     * 设置约为15个英文字符的宽度【15*256】
     */
    sheet.setColumnWidth(0, 15 * 256);
    sheet.setColumnWidth(1, 15 * 256);
    sheet.setColumnWidth(2, 15 * 256);
    sheet.setColumnWidth(3, 15 * 256);

    /**
     * 定义字体
     */
    Font font = workbook.createFont();
    font.setColor(HSSFFont.COLOR_RED);
    font.setFontName("黑体");


    /**
     *  表头单元格的样式
     */
    CellStyle titleStyle = workbook.createCellStyle(); //创建一个样式
    titleStyle.setAlignment(HorizontalAlignment.CENTER);//设置垂直对齐的样式为居中对齐;
    titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);//设置垂直对齐的样式为居中对齐;
    titleStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex()); //设置背景色-天蓝色
    titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);//填充颜色的模式-实心
    titleStyle.setFont(font);

    /**
     *  定义其他单元格的样式
     */
    CellStyle cellStyle = workbook.createCellStyle(); //创建一个样式
    cellStyle.setBorderTop(BorderStyle.MEDIUM);//上边框
    cellStyle.setBorderBottom(BorderStyle.MEDIUM); //底部边框-中等边框
    cellStyle.setBorderLeft(BorderStyle.MEDIUM); //左边框
    cellStyle.setBorderRight(BorderStyle.MEDIUM);//右边框

    cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());//顶部边框颜色
    cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());//底部边框颜色
    cellStyle.setLeftBorderColor(IndexedColors.BLACK.index);//左边框颜色
    cellStyle.setRightBorderColor(IndexedColors.BLACK.index);//右边框颜色

    cellStyle.setAlignment(HorizontalAlignment.CENTER);//设置水平对齐的样式为居中对齐;
    cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//设置垂直对齐的样式为居中对齐;

    cellStyle.setFont(font);//使用字体


    /**
     * 创建4行
     * 从0开始算
     * 创建出固定需要的行,用于设计表格格式
     */
    Row row1 = sheet.createRow(0);
    Row row3 = sheet.createRow(2);
    Row row4 = sheet.createRow(3);


    /**
     *  合并单元格
     *  4个参数【起始行,结束行,起始列,结束列】
     *  行和列都是从0开始计数,且起始结束都会合并
     */
    sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 3));
    sheet.addMergedRegion(new CellRangeAddress(2, 3, 0, 0));
    sheet.addMergedRegion(new CellRangeAddress(2, 2, 1, 2));
    sheet.addMergedRegion(new CellRangeAddress(2, 3, 3, 3));


    /**
     * 创建单元格
     * 从0开始算
     */
    Cell cell1 = row1.createCell(0);
    cell1.setCellValue("统计分析");
    cell1.setCellStyle(titleStyle);


    Cell cell2 = row3.createCell(0);
    cell2.setCellValue("公司");
    cell2.setCellStyle(cellStyle);

    Cell cell3 = row3.createCell(1);
    cell3.setCellValue("性别");
    cell3.setCellStyle(cellStyle);

    Cell cell4 = row4.createCell(1);
    cell4.setCellValue("男");
    cell4.setCellStyle(cellStyle);

    Cell cell5 = row4.createCell(2);
    cell5.setCellValue("女");
    cell5.setCellStyle(cellStyle);

    Cell cell6 = row3.createCell(3);
    cell6.setCellValue("总人数");
    cell6.setCellStyle(cellStyle);
    row4.createCell(3).setCellStyle(cellStyle);//把边框补充完整
    return cellStyle;
}

3.3.3、使用三种方式导出测试结果

导出1000条数据

版本

测试10次用时时长(单位:秒)

平均用时时间(单位:秒)

03版本xls

0.089、0.012、0.013、0.012、0.012、0.012、0.012、0.021、0.013、0.013

0.0209

07版本xlxs

0.366、0.055、0.05、0.051、0.051、0.053、0.054、0.052、0.058、0.05

0.084

07版本-加强版xlxs

0.103、0.027、0.023、0.021、0.026、0.027、0.021、0.024、0.022、0.022

0.0316

导出65536条数据

版本

测试10次用时时长(单位:秒)

平均用时时间(单位:秒)

03版本xls

1.175、2.12、0.749、0.676、0.654、1.947、1.943、1.348、1.952、1.993

1.4557

07版本xlxs

2.711、2.486、2.537、2.481、2.558、2.431、2.548、2.6、2.233、2.268

2.4853

07版本-加强版xlxs

0.47、0.486、0.356、0.352、0.366、0.364、0.352、0.353、0.366、0.352

0.381

4、总结

对于导出数据量不大的情况下,推荐使用HSSF导出xls文件,效率上更高一些。对于导出大数据量的场景,推荐使用SXSSF,加强版的SXSSF导出效率比XSSF高出很多,但是会产生临时文件,记得用dispose()清除生成的临时文件。

参考资料

1、https://blog.csdn.net/qq_44413835/article/details/124174996

2、cnblogs.com/swordfall/p/8298386.html文章来源地址https://www.toymoban.com/news/detail-525068.html

到了这里,关于使用POI导出数据以及性能比较的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用POI设计一个限制导出日期为三十天,且导出文件为excel

    使用POI设计一个限制导出日期为三十天,且导出文件为excel,前端使用Vue的element ui进行设计,前端可以通过选择时间来导出具体的表格数据,根据用户选择的时间进行Excel文件的数据导出。 按照需求来设计代码,根据element ui对前端代码进行设计。 后端使用 Java,依赖 Apache

    2024年02月15日
    浏览(38)
  • hutool poi、apache poi实现导入导出以及解析excel

    一、前言 看了例子之后后续需要更加深入学习或者更多理解其他API的话,建议看官方文档。hutool项目是中国人维护的,有中文文档,阅读起来很方便。apache poi比较底层一点,可以更加自由去二次开发自己所需的功能。 hutool官方文档 hutool官方gitee apache poi官方文档 二、基于

    2024年02月09日
    浏览(54)
  • poi实现excel文件导入导出(基本数据导出、含格式导出、含批注导出、含图片图表导出)——springboot

    本文主要是介绍springboot + poi实现基本的excel文件导入导出,包含数据导出导入时数据的其他需求校验,导出含有批注信息、导出含有图片信息、导出含有图表信息等的介绍等等,主要是一个demo尽可能简单明了的来介绍相关功能即可。有什么问题可以在留言哦!并在文章末尾附

    2024年02月08日
    浏览(81)
  • 使用Apache POI数据导出及EasyExcel进行十万、百万的数据导出

    Apache POI 是基于 Office Open XML 标准( OOXML )和 Microsoft 的 OLE 2 复合⽂档 格式( OLE2 )处理各种⽂件格式的开源项⽬。 简⽽⾔之,您可以使⽤ Java 读写 MS Excel ⽂件,可以使⽤ Java 读写 MS Word 和 MS PowerPoint ⽂件。 1.HSSF - 提供读写 Microsoft Excel XLS 格式 (Microsoft Excel 97 (-2003)) 档案

    2024年02月15日
    浏览(42)
  • Apache POI 以及 导出Excel表

    Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是,我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。 一般情况下,POI 都是用于操作 Excel 文件。 导依赖 将数据写入Excel文件 读取Excel文件数据 学习

    2024年02月11日
    浏览(39)
  • Java使用poi导出excel针对不同数据列配置设置不同单元格格式(适用于通用导出excel数据)

    公司大部分业务都是查询相关的业务, 所以建了一个项目专门做数据查询, 数据中转等抽象通用的业务, 有一天给我安排了一个功能, 做excel导出, 配置好查询sql和表头字段映射后即可导出excel, 无需修改代码 后来因为导出数据要求保留几位小数或者转换成百分比等设置单元格格

    2024年02月07日
    浏览(55)
  • poi实现Excel文件的导入导出

    poi结构说明 引入poi依赖包 第一步、获取表内容数据: 根据表头内容与实体类属性对应的map,利用反射机制获取get方法来取出该实体数据 第二步、开始导出 编辑表格内样式 第三步、设定响应请求头格式,发送文件到客户端 判断表格行数据是否为空 判断表格列值是否为空 设

    2024年02月12日
    浏览(47)
  • poi实现Excel文件导出【SpringBoot篇】

    在系统中,数据库的excel文件导出是一项及为基础的功能。此篇文章将通过实例利用poi实现excel文件导出。 Jakarta POI 是apache的子项目,目标是处理ole2对象。它提供了一组操纵Windows文档的Java API 。目前比较成熟的是HSSF接口,处理MS Excel(97-2002)对象。它不象我们仅仅是用csv生

    2024年02月05日
    浏览(44)
  • 12、POI之数据导入导出

    【简介】: POI简介(Apache POI),Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。 【官网】: Apacche POI 官网 【主要包含模块】: HSSF - 提供读写Microsoft Excel格式档案的功能。(.xls) XSSF - 提供读写Microsoft Excel OOXML格

    2024年02月07日
    浏览(48)
  • Java POI (2)—— Excel文件的上传与导出(实例演示)

             这里是一个demo的流程图,下面按照这个流程图做了一个简单的实现,有部分判断没有加上,实际操作中,可以根据自己的需求进行增加或者修改。并且此处还是在接受文件传入后将文件进行了下载,保存到本地的操作,这个要按照具体情况具体分析,看需求是否

    2024年02月11日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包