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

SpringBoot 导出多个Excel文件,压缩成.zip格式下载

前言


之前写过一篇极其简单的excel导入导出,是单个文件的:
Springboot 最简单的结合MYSQL数据实现EXCEL表格导出及数据导入_小目标青年的博客-CSDN博客

还有指定模板的: 

Springboot 指定自定义模板导出Excel文件_小目标青年的博客-CSDN博客

今天有人问到,多个文件导出,放到zip压缩包里面怎么搞?

不多说,开搞。

正文 

三步:

1. 引入 核心依赖

2. 复制粘贴已经给你们写好的工具类

3. 送一步,自测看效果

第一步,引依赖

<!-- 导入和导出-->
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-base</artifactId>
    <version>3.0.3</version>
</dependency>
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-web</artifactId>
    <version>3.0.3</version>
</dependency>
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-annotation</artifactId>
    <version>3.0.3</version>
</dependency>

第二步,加工具类

ExcelUtil.java

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import org.apache.poi.ss.usermodel.Workbook;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;


/**
 * @Author: JCccc
 * @Date: 2022-7-13 16:02
 * @Description: excel工具类
 */
public class ExcelUtil {

    /**
     * 导出
     * @param list
     * @param title
     * @param sheetName
     * @param pojoClass
     * @param fileName
     * @param response
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) {
        defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName));
    }

    /**
     * 导出excle转换成 bytes
     * @param list
     * @param title
     * @param sheetName
     * @param pojoClass
     * @param fileName
     * @param response
     * @return
     * @throws IOException
     */
    public static byte[] getExportExcelBytes(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) throws IOException {
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(title, sheetName), pojoClass, list);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        workbook.write(os);
        return os.toByteArray();
    }

    private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        downLoadExcel(fileName, response, workbook);
    }
    private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition",
                    "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        }
    }

}

ZipUtils.java

import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import static org.springframework.util.StreamUtils.BUFFER_SIZE;

/**
 * @Author: JCccc
 * @Date: 2022-7-13 16:02
 * @Description: zip工具类
 */
public class ZipUtils {

    /**
     * 传入文件file
     * @param outputStream
     * @param fileList
     */
    public static void downloadZipForFiles(OutputStream outputStream, List<File> fileList){

        ZipOutputStream zipOutputStream = null;
        try {
            zipOutputStream = new ZipOutputStream(outputStream);
            for (File file : fileList) {
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zipOutputStream.putNextEntry(zipEntry);
                byte[] buf = new byte[BUFFER_SIZE];
                int len;
                FileInputStream in = new FileInputStream(file);
                while ((len = in.read(buf)) != -1) {
                    zipOutputStream.write(buf, 0, len);
                    zipOutputStream.flush();
                }
            }
            zipOutputStream.flush();
            zipOutputStream.close();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭流
            try {
                if (zipOutputStream != null ) {
                    zipOutputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 传入文件的 byte[]
     * Map<String,byte[]> fileBufMap key是文件名(包含后缀),value是文件的byte[]
     * @param outputStream
     * @param fileBufMap
     */
    public static void downloadZipForByteMore(OutputStream outputStream,Map<String,byte[]> fileBufMap)  {

            ZipOutputStream zipOutputStream = null;
            try {
                zipOutputStream = new ZipOutputStream(outputStream);
                for (String fileName:fileBufMap.keySet()){
                    ZipEntry zipEntry = new ZipEntry(fileName);
                    zipOutputStream.putNextEntry(zipEntry);
                    if (Objects.nonNull(fileBufMap.get(fileName))){
                        byte[] fileBytes = fileBufMap.get(fileName);
                        zipOutputStream.write(fileBytes);
                        zipOutputStream.flush();
                    }
                }
                zipOutputStream.flush();
                zipOutputStream.close();

            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                // 关闭流
                try {
                    if (zipOutputStream != null ) {
                        zipOutputStream.close();
                    }
                    if (outputStream != null) {
                        outputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    }

    /**
     * 返回zip包的 byte[]
     *
     * @param fileBufMap
     * @return
     */

    public static byte[] getZipForByteMore(Map<String,byte[]> fileBufMap)  {
        ByteArrayOutputStream totalZipBytes = null;
        ZipOutputStream zipOutputStream = null;
        try {
            totalZipBytes = new ByteArrayOutputStream();
            zipOutputStream = new ZipOutputStream(totalZipBytes);
            for (String fileName:fileBufMap.keySet()){
                ZipEntry zipEntry = new ZipEntry(fileName);
                zipOutputStream.putNextEntry(zipEntry);
                if (Objects.nonNull(fileBufMap.get(fileName))){
                    byte[] fileBytes = fileBufMap.get(fileName);
                    zipOutputStream.write(fileBytes);
                    zipOutputStream.flush();
                }
            }
            zipOutputStream.close();
            byte[] bytes = totalZipBytes.toByteArray();
            totalZipBytes.close();// 关闭流
            return bytes;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭流
            try {
                if (totalZipBytes != null) {
                    totalZipBytes.close();
                }
                if (zipOutputStream != null) {
                    zipOutputStream.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}

第三步,使用工具类,看看效果

回顾一下,单个excel导出,写过使用场景接口:
 

    @RequestMapping("exportUserExcel")
    public void exportUserExcel(HttpServletResponse response){
       // List<User> userList = userService.queryUserInfo();
        List<User> userList=new ArrayList<>();
        User user1=new User(1,"a","12");
        User user2=new User(1,"b","12");
        User user3=new User(1,"c","12");
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        //导出操作
        ExcelUtil.exportExcel(userList,"用户信息","sheet1",User.class,"users.xls",response);
    }

调用一下:

多个文件导出,zip方式下载:

① 已经知道存在的文件路径

接口使用代码: 

    /**
     * 将指定文件打包成zip并下载
     */
    @RequestMapping("exportExcelZipWithFile")
    public void exportExcelZipWithFile(HttpServletResponse response) throws IOException {
        // 这里还是和上面一样
        String[] filePath = new String[]{"D:\\ziptest\\11.xls", "D:\\ziptest\\22.xls"};
        List<File> fileList = new ArrayList<>();
        for (String s : filePath) {
            File file = new File(s);
            fileList.add(file);
        }
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=configDetail.zip");
        ZipUtils.downloadZipForFiles(response.getOutputStream(), fileList);
    }

效果:

②直接生成excel,转换成byte再导出zip

    /**
     * 将excel文件的Byte[]打包成zip并下载
     */
    @RequestMapping("exportExcelZipWithByte")
    public void exportExcelZipWithByte(HttpServletResponse response) throws IOException {

        Map<String,byte[]> fileBufMap=new HashMap<>();

        List<Account> accountList=new ArrayList<>();
        Account account1=new Account(1,"1234");
        Account account2=new Account(2,"12222");
        Account account3=new Account(3,"1431546");
        accountList.add(account1);
        accountList.add(account2);
        accountList.add(account3);
        //导出操作 1
        byte[] exportAccountExcelBytes = ExcelUtil.getExportExcelBytes(accountList, "账号信息", "sheet1", Account.class, "accounts.xls", response);


        List<User> userList=new ArrayList<>();
        User user1=new User(1,"a","12");
        User user2=new User(1,"b","12");
        User user3=new User(1,"c","12");
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        //导出操作
        byte[] exportUserExcelBytes =   ExcelUtil.getExportExcelBytes(userList,"用户信息","sheet1",User.class,"users.xls",response);


        fileBufMap.put("accounts.xls",exportAccountExcelBytes);
        fileBufMap.put("users.xls",exportUserExcelBytes);

        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=configDetail.zip");
        ZipUtils.downloadZipForByteMore(response.getOutputStream(), fileBufMap);
    }

代码简析:

这个map,key 是zip压缩包里面的文件名, vlaue是 excel文件的字节流: 

 生成excel文件,我们直接返回 byte[]流:

把多份excel文件的byte[] 都丢到map里面:

把每一个excel文件的 byte[]都放入 zip流:

 实现效果:

好吧,该篇就到这。

相关文章:

  • Springboot 指定自定义模板导出Excel文件
  • Mysql 我随手造200W条数据,给你们讲讲分页优化。
  • 【云原生】风云暗涌的时代,DBA们的利刃出鞘了
  • 以后面试官问你 为啥不建议使用Select *,请你大声回答他!
  • Springboot 导入导出Excel ,一对多关系,复合表格、合并单元格数据
  • 怎么清晰地理解、表达 IaaS 、 PaaS 、 SaaS ?
  • UML类图的六大关系,最佳学习理解方式
  • Springboot 整合 Socket 实战案例 ,实现 单点发送、广播群发,1对1,1对多
  • Springboot Mybatis 、JPA 调用存储过程,实战教程
  • 写代码的七八九十宗罪,多图、胆小慎入!
  • Springboot byte[] 转 MultipartFile ,InputStream 转 MultipartFile
  • Springboot 最细节全面的接口传参接参介绍,总有你喜欢的一种方式
  • Springboot 整合RabbitMq ,用心看完这一篇就够了
  • 用过Apifox这个API接口工具后,确实感觉postman有点鸡肋......
  • ClickHouse 挺快,esProc SPL 更快
  • [case10]使用RSQL实现端到端的动态查询
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 【笔记】你不知道的JS读书笔记——Promise
  • axios 和 cookie 的那些事
  • Create React App 使用
  • flask接收请求并推入栈
  • hadoop集群管理系统搭建规划说明
  • Hexo+码云+git快速搭建免费的静态Blog
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • JAVA 学习IO流
  • js
  • mysql 数据库四种事务隔离级别
  • Quartz初级教程
  • Tornado学习笔记(1)
  • Vultr 教程目录
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 将回调地狱按在地上摩擦的Promise
  • 来,膜拜下android roadmap,强大的执行力
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 三分钟教你同步 Visual Studio Code 设置
  • 深入 Nginx 之配置篇
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 微信小程序--------语音识别(前端自己也能玩)
  • Linux权限管理(week1_day5)--技术流ken
  • 阿里云移动端播放器高级功能介绍
  • ​MySQL主从复制一致性检测
  • #pragam once 和 #ifndef 预编译头
  • (7)STL算法之交换赋值
  • (JS基础)String 类型
  • (rabbitmq的高级特性)消息可靠性
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • ****Linux下Mysql的安装和配置
  • .equals()到底是什么意思?
  • .Net FrameWork总结
  • .Net6 Api Swagger配置
  • .net6 webapi log4net完整配置使用流程