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

springboot 一键下载文件

依赖

  <dependency><groupId>net.lingala.zip4j</groupId><artifactId>zip4j</artifactId><version>2.11.5</version></dependency>

具体实现

package com.transport.common.method.file;import com.transport.common.response.file.BatchDownloadFileResponse;
import com.transport.common.utils.DateUtils;
import com.transport.common.utils.file.FileUtils;
import lombok.extern.slf4j.Slf4j;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.CompressionLevel;
import net.lingala.zip4j.model.enums.CompressionMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;/*** 批量将文件打包下载*/
@Slf4j
@Component
public class FileToZipUtil {/*** 创建 zip 文件** @param fileResponseList* @param tmpFileDirectory* @return*/public static BatchDownloadFileResponse createZipFile(List<BatchDownloadFileResponse> fileResponseList, String tmpFileDirectory) {String zipFileName = null;// 创建一个列表用于存放所有附件文件的路径,后续统一压缩到一个zip文件中String tempFileName = "";List<String> allFilePaths = new ArrayList<>();for (BatchDownloadFileResponse response : fileResponseList) {allFilePaths.add(response.getFilePath());String fileName = response.getFileName().substring(0, response.getFileName().lastIndexOf("."));tempFileName += fileName + "_";}tempFileName = tempFileName.substring(0, tempFileName.length() - 1);// 循环查询每个id对应的附件文件路径并添加到列表中// 里面的代码大家可能会觉得麻烦,不用细看,只需要知道这层for循环是为了找到附录文件在磁盘的地址String format = DateUtils.dateTimeNow();// 创建ZipFile对象,指定zip文件的路径tempFileName = format + tempFileName + ".zip";String cleanedFileName = cleanFileName(tempFileName);String tmpZipPath = tmpFileDirectory + File.separator + "tmpZip" + File.separator + cleanedFileName;//        File tempFile = new File(tmpZipPath);
//        if (!tempFile.exists()) {
//            tempFile.mkdirs();
//        }ZipFile zipFile = new ZipFile(tmpZipPath);zipFileName = tempFileName + ".zip";// 循环附录文件地址for (String filePath : allFilePaths) {File file = new File(filePath);if (file.exists()) {String folderNameInsideZip = tempFileName + "";// 构造在zip文件中存放的路径,格式为 "id标识的文件夹名/原文件名"try {// 尝试获取目标文件夹在zip文件中的FileHeaderFileHeader folderHeader = zipFile.getFileHeader(folderNameInsideZip + "/");
//                    log.info("文件夹在zip文件中的FileHeader:" + folderHeader);// 如果zip文件中指定目录不存在,则创建,这一步判断是必须的,不然会导致下一次文件添加动作会覆盖之前的文件if (Objects.isNull(folderHeader)) {new File(folderNameInsideZip).mkdirs();  // 创建文件夹ZipParameters folderPar = new ZipParameters();folderPar.setCompressionLevel(CompressionLevel.NORMAL);folderPar.setEncryptFiles(false);zipFile.addFolder(new File(folderNameInsideZip), folderPar);log.info("文件夹已成功添加到zip文件中。");}// 创建ZipParameters对象,用于设置添加文件的参数ZipParameters parameters = new ZipParameters();// 设置压缩方法,这里使用默认压缩方法parameters.setCompressionMethod(CompressionMethod.DEFLATE);// 设置压缩级别,这里使用默认压缩级别parameters.setCompressionLevel(CompressionLevel.NORMAL);// 设置添加文件在zip文件中的路径,格式为 "文件夹名/文件名"parameters.setFileNameInZip(folderNameInsideZip + "/" + file.getName());// 将文件添加到zip文件中的指定文件夹路径下zipFile.addFile(file, parameters);log.info("文件已成功添加到zip文件中的指定文件夹。");} catch (ZipException e) {e.printStackTrace();throw new RuntimeException(e);}}}String absolutePath = zipFile.getFile().getAbsolutePath();log.info("压缩包路径为 {}", zipFile.getFile().getAbsolutePath());BatchDownloadFileResponse batchDownloadFileResponse = new BatchDownloadFileResponse();batchDownloadFileResponse.setZipFileName(zipFileName);batchDownloadFileResponse.setZipFilePath(absolutePath);return batchDownloadFileResponse;}/*** 清理文件名中的特殊字符*/public static String cleanFileName(String fileName) {// 替换掉Windows系统不允许的特殊字符return fileName.replaceAll("[\\\\/:*?\"<>|& ]", "_");}
}

前端下载
在这里插入图片描述

systemDownLoadZipFile(fileData) {var url = baseURL + "/common/batchDownLoadFiles";axios({method: 'post',url: url,data: fileData,responseType: 'blob',headers: { 'Authorization': 'Bearer ' + getToken() }}).then((res) => {const isBlob = blobValidate(res.data);if (isBlob) {const blob = new Blob([res.data])this.saveAs(blob, decodeURIComponent(res.headers['download-filename']))} else {this.printErrMsg(res.data);}})},

调用
在这里插入图片描述

http://www.dtcms.com/a/296861.html

相关文章:

  • Linux操作系统原理与应用
  • 河南萌新联赛2025第(二)场:河南农业大学
  • 使用Docker+Nginx部署电商平台项目(服务端+管理端+商城)
  • 基于STM32智能鱼缸监控投喂系统
  • Kubernetes 集群架构和Pod创建流程
  • 优选算法:移动零
  • 激光雷达的单播和广播模式介绍
  • 2025年海外短剧独立站开发:H5+PC端双平台技术实践与增长策略
  • 处理HTTP请求体:精通`@RequestBody`、`@RequestHeader`与`@CookieValue`
  • 计算机视觉技术剖析:轮廓检测、模板匹配及特征点匹配
  • SpringBoot框架简介
  • Windows本地部署DeepSeek
  • git更新内核补丁完整指南
  • 【C++】使用中值滤波算法过滤数据样本中的尖刺噪声
  • Java 并发容器:ConcurrentHashMap 笔记(JDK 1.8)
  • 01_FOC学习之先让电机转动起来
  • 双紫擒龙紫紫红黄安装使用攻略,2025通达信指标源码,擒龙追踪源码公式学习
  • 爬虫基础概念
  • 浏览器访问[http://www.taobao.com](http://www.taobao.com/),经历了怎样的过程。
  • DNS域名解析过程
  • 通达OA二次开发
  • Impact rating 影响等级定义(学习笔记)
  • YOLOv8 剪枝模型加载踩坑记:解决 YAML 覆盖剪枝结构的问题
  • 【JAVA】使用vosk实现windows实时语音转文字,解放双手
  • vs2019 创建MFC ActiveX的详细步骤
  • JS事件基础
  • ESP-NOW无线通信协议:物联网设备间的高效对话方式
  • 前端基础知识Vue系列 - 24(axios的原理)
  • Linux(centos7)安装 docker + ollama+ deepseek-r1:7b + Open WebUI(内含一键安装脚本)
  • Windows下使用UIAutomation技术遍历桌面窗口和指定窗口内容的AutomationWalker.exe的C#源代码