若依--文件批量导出成压缩包

文章目录

项目需求,对于每一个人提交的文件,需要在后端配置统一的命名格式,批量导出压缩包

文件是存储在分布式的mino里面的,主要是前后端的联调问题。还有过程中遇到的一些报错。

后端

使用了ZipOutputstream流。

从minio中拿去文件  通过minioClient.getObject 拿到client
in = minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName) // 替换为你的音频文件路径
                        .build());  //从mino中将数据文件流读取出来
@SneakyThrows
public void addFileToZip(String objectName, ZipOutputStream zipOut,String fileName) throws IOException {
    InputStream in = null;
    try {
        in = minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName) // 替换为你的音频文件路径
                        .build());
                                //filename是统一编写的名称
        zipOut.putNextEntry(new ZipEntry(fileName)); // 将文件名称添加到 ZIP
        byte[] buffer = new byte[1024 * 10]; //创建一个字节数组  不断的往里面输入
        int length;
        while ((length = in.read(buffer)) > 0) {
            zipOut.write(buffer, 0, length); // 写入 ZIP 输出流
            zipOut.flush(); // 刷新 ZipOutputStream,确保数据被写入
        }
        zipOut.closeEntry(); // 关闭当前 ZIP 条目
    } finally {
        if (in != null) {
            in.close(); // 关闭输入流
        }
    }
}

对于Controller类

不用void返回值,直接将文件流放入到response中去,前端是通过blob拿到的。


对于blob

JSON不好解析对应的二进制文本文件,文件上传服务器的响应式一个二进制文件,不是文本数据。

传入需要下载的ids和response

@PostMapping("/download-zip")
public void downloadZip(@RequestBody List<Integer> ids, HttpServletResponse response) {
  
    taskSubService.exportFile(ids,response);
}
HttpServletResponse 直接输出到 HTTP 响应流中。Spring 框架的 HttpServletResponse 允许开发者直接操作响应流进行数据输出,而不需要通过返回值。

先拿到所有的文件地址。

ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())
需要理解这一段代码。
将数据压缩成 ZIP 格式,并将压缩后的数据直接通过 HTTP 响应流输出给客户端。
@SneakyThrows
@Override
public void exportFile(List<Integer> ids, HttpServletResponse response) {
    
    
    List<TaskInfoVO> list = taskSubMapper.seletByIds(ids);

    response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"files.zip\"");
    response.setContentType("application/zip");
    response.setHeader(HttpHeaders.TRANSFER_ENCODING, "chunked"); // 添加 chunked encoding header

    try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
    
    
        for (TaskInfoVO taskInfoVO : list) {
    
    
            String path = taskInfoVO.getFilePath();
            String objectName = path.substring(path.indexOf("file")); // 获取对象名称
            System.out.println(objectName);
            // 将文件添加到 ZIP 文件
            String filename = generateCustomFileName(taskInfoVO);
            minioTemplate.addFileToZip(objectName, zipOut, filename);
        }
    } catch (IOException e) {
    
    
        e.printStackTrace();
    }
}

private String generateCustomFileName(TaskInfoVO taskInfoVO) {
    
    
String prefix = taskInfoVO.getFilePath().substring(taskInfoVO.getFilePath().lastIndexOf(".") + 1);
String filename = taskInfoVO.getTaskName() + "_" + taskInfoVO.getClassName() + "_" + taskInfoVO.getStudentName() + "_" + taskInfoVO.getStudentId() +
"." + prefix;
return filename;
}

常用的content-

response.setContentType("application/json");
response.setContentType("application/pdf");
response.setContentType("image/png");
response.setContentType("text/plain");
response.setContentType("text/html");
response.setContentType("video/mp4");
   //二进制流
  response.setContentType("application/octet-stream");

前端

 responseType: 'blob',  //设置参数的时候 这个比较重要 让后端返回对应的二进制流文件
const apiURL = 'http://localhost:8080'; // 替换为你的 API URL

import {getToken} from '@/utils/auth'   //token的验证是放在 util/auth下面的

const handleExport = async () => {
  try {
    const response = await axios.post(`${apiURL}/tasksub/download-zip`, ids.value, {
      responseType: 'blob',
      headers: {
        'Content-Type': 'application/json; application/octet-stream',
        'Authorization': 'Bearer ' + getToken()// 添加 Bearer Token
      },
    });
    const blob = new Blob([response.data], {type: 'application/zip'});
    const fileName = 'aa'; //应该动态设置文件名
    // 创建一个链接并下载文件
    const a = document.createElement('a');
    const url = window.URL.createObjectURL(blob);
    a.href = url;
    a.download = fileName;
    document.body.appendChild(a);
    a.style.display = 'none'; // 隐藏链接
    a.click(); // 触发下载
    document.body.removeChild(a); // 下载后移除链接
    window.URL.revokeObjectURL(url); // 释放 Blob URL
  } catch (error) {
    console.error('下载文件时出错:', error); // 错误处理
  }
};

猜你喜欢

转载自blog.csdn.net/ngczx/article/details/142931979