EasyExcel多次写入数据多个EasyExcel文件导出到zip压缩文件

news/2024/7/21 4:30:27 标签: java, easyExcel, excel, zip

笔者最近需要导出一百多万条数据到Excel,已经超出单张工作表的最大容量(2^20=1048576),需要导出到多个工作表或多个Excel文件。

海量数据导出面临的问题有以下几个:

  1. 如果一次性查出所有数据,很可能内存溢出,所以需要分页导出,分页导出就必须解决大分页查询的性能问题。
    该问题网上有很多解决办法,本文不涉及。

  2. 如果使用POI进行数据导出,内存、CPU占用都很高,而且速度很慢,所以采用EasyExcel进行数据导出。在上一篇使用EasyExcel读写Excel文件中,数据是一次性写入的,本文介绍EasyExcel多次写入数据的方法。

  3. 将多个EasyExcel的数据写入到zip文件中。通过将EasyExcel写入到ByteArrayOutputStream,再将ByteArrayOutputStream转成byte数组,写入到zip中。


1.在pom.xml中添加POI相关依赖

        <!-- easyexcel -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel-core</artifactId>
            <version>3.3.2</version>
        </dependency>

2.实体类

java">package com.example.study.entity;


import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;

import java.util.Date;

@Getter
@Setter
public class StudentEntity {
    @ExcelProperty(value = "id", order = 1)
    private Integer id;

    @ExcelProperty(value = "生日", order = 4)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date birthday;

    @ExcelProperty(value = "名字", order = 2)
    private String name;

    @ExcelProperty(value = "性别", order = 3)
    private String sex;

    private String desc;

    private String extra;
}

3.写入数据

java">package com.example.study.common;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.example.study.entity.StudentEntity;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class EasyExcelWriteToZipDemo {
    public static void main(String[] args) {
        String writeExcel = "F:\\tmp\\batch_export.zip";
        write(writeExcel);
    }

    private static void write(String writeExcel) {
        // 设置不需要导出的字段
        Set<String> excludeColumnFieldNames = new HashSet<>();
        excludeColumnFieldNames.add("desc");
        excludeColumnFieldNames.add("extra");
        WriteSheet sheet = EasyExcel.writerSheet("花名册")
                .excludeColumnFieldNames(excludeColumnFieldNames)
                .needHead(Boolean.TRUE)
                .build();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ExcelWriter workbook = EasyExcel.write(baos, StudentEntity.class).build();
        int sheetMaxSize = 1001;
        int currentExcelSize = 0;
        int count = 0;
        int total = 3111;
        int fileIndex = 1;
        try (FileOutputStream fos = new FileOutputStream(writeExcel);
             ZipOutputStream zos = new ZipOutputStream(fos)) {
            while (count < total) {
                List<StudentEntity> page = getPage(count + 1, total);
                if (currentExcelSize + page.size() > sheetMaxSize) {
                    // 超过单个文件最大数据条数后,写入到zip文件,并将当前页面数据写入新的excel文件
                    workbook.close();
                    zos.putNextEntry(new ZipEntry(String.format("数据导出文件_%s.xlsx", fileIndex++)));
                    zos.write(baos.toByteArray());
                    baos = new ByteArrayOutputStream();
                    workbook = EasyExcel.write(baos, StudentEntity.class).build();
                    currentExcelSize = page.size();
                } else {
                    currentExcelSize += page.size();
                }
                workbook.write(page, sheet);
                count += page.size();
            }
            if (currentExcelSize > 0) {
                workbook.close();
                zos.putNextEntry(new ZipEntry(String.format("数据导出文件_%s.xlsx", fileIndex++)));
                zos.write(baos.toByteArray());
            }
            zos.flush();
            fos.flush();
        } catch (IOException exception) {
            exception.printStackTrace();
        }
    }

    private static List<StudentEntity> getPage(int lastMaxId, int total) {
        List<StudentEntity> page = new ArrayList<>();
        for (int index = lastMaxId; index < Math.min(lastMaxId + 100, total + 1); index++) {
            StudentEntity student = new StudentEntity();
            student.setId(index);
            student.setName("名字_" + index);
            student.setSex(index % 2 == 0 ? "女" : "男");
            student.setBirthday(new Date());
            student.setDesc("test desc");
            student.setExtra("test extra");
            page.add(student);
        }
        return page;
    }
}

http://www.niftyadmin.cn/n/4934181.html

相关文章

深度学习常用的python库学习笔记

文章目录 数据分析四剑客Numpyndarray数组和标量之间的运算基本的索引和切片数学和统计方法线性代数 PandasMatplotlibPIL 数据分析四剑客 Numpy Numpy中文网 ndarray 数组和标量之间的运算 基本的索引和切片 数学和统计方法 线性代数 Pandas Pandas中文网 Matplotlib Mat…

Mac下⬇️Git如何下载/上传远程仓库

使用终端检查电脑是否安装Git git --version 通过此文章安装Git ➡️ ​​​​​​​传送门&#x1f310; 方式1⃣️使用终端操作 1.下载——克隆远程仓库到本地 git clone [远程地址] 例&#xff1a;git clone https://gitee.com/lcannal/movie.git​ 2.编…

tensorflow 1.14 的 demo 02 —— tensorboard 远程访问

tensorflow 1.14.0&#xff0c; 提供远程访问 tensorboard 服务的方法 第一步生成 events 文件&#xff1a; 在上一篇demo的基础上加了一句&#xff0c;如下&#xff0c; tf.summary.FileWriter("./tmp/summary", graphsess1.graph) hello_tensorboard_remote.py …

MySQL数据库表的增删查改 - 进阶

一&#xff0c;数据库约束 1.1 约束对象 not null - 该列不能为空unique - 保证该列的每一行都不一样default - 规定没有给列赋值时的默认值&#xff08;自定义&#xff09;primary key - not null 和 unique 的结合&#xff0c;会给该列添加一个索引&#xff0…

OptaPlanner笔记4

2.2.8. 创建应用程序 创建SolverFactory 来为每个数据集构建Solver加载数据集使用Solver.solve()进行求解输出数据集的解决方案 通常一个应用包含一个SolverFactory 来为每个要求解的问题数据集构建新的Solver实例。SolverFactory是线程安全的&#xff0c;但Solver不是。 im…

PyTorch翻译官网教程-LANGUAGE MODELING WITH NN.TRANSFORMER AND TORCHTEXT

官网链接 Language Modeling with nn.Transformer and torchtext — PyTorch Tutorials 2.0.1cu117 documentation 使用 NN.TRANSFORMER 和 TORCHTEXT进行语言建模 这是一个关于训练模型使用nn.Transformer来预测序列中的下一个单词的教程。 PyTorch 1.2版本包含了一个基于论…

Linux tar包安装 Prometheus 和 Grafana(知识点:systemd Unit/重定向)

0. 介绍 用tar包的方式安装 Prometheus 和 Grafana Prometheus:开源的监控方案Grafana:将Prometheus的数据可视化平台 1. Prometheus 1. 下载 与 解压 官网下载: https://prometheus.io/download/#prometheus上传至机器解压命令:tar -xzf prometheus-*.tar.gz 2. 启动与暂…

vector【1】介绍与使用(超详解哦)

vector 引言vector介绍接口使用默认成员函数迭代器容量元素访问数据修改 总结 引言 在string部分&#xff0c;我们详细的介绍了各个接口的使用&#xff0c;虽然其不属于STL的一部分&#xff0c;但是接口与STL中的容器相似&#xff0c;所以我们在学习使用vector等STL容器的使用…