java多线程批量下载文件打包成zip

本文叙述本文用于多个文件批量下载,提供两种下载方式 (二者利弊自行考量)1. 将文件文件全部下载到本地文件夹,之后将文件夹打包成zip最后输出到浏览器再删除文件夹跟zip文件利用本地磁盘作为过渡2. 直接在代码中拿到全部文件的byte[]数组之后,将文件的byte[]数组全部装入zip文件流,最后将zip文件流输出到浏览器,全过程不产生实体文件到磁盘中。前端调用方式: 前端调用接口方式本文是直接通过 window.location.href 方式调用接口地址 或通过以下js方式调用本文不做叙述自行了
摘要由CSDN通过智能技术生成

本文叙述

注: 本文中使用到的PdfUtil工具类暂不提供自行剔除
本文用于多个文件批量下载,提供两种下载方式 (二者利弊自行考量)
1. 将文件文件全部下载到本地文件夹,之后将文件夹打包成zip最后输出到浏览器再删除文件夹跟zip文件利用本地磁盘作为过渡
2. 直接在代码中拿到全部文件的byte[]数组之后,将文件的byte[]数组全部装入zip文件流,最后将zip文件流输出到浏览器,全过程不产生实体文件到磁盘中。

前端调用方式: 前端调用接口方式本文是直接通过 window.location.href 方式调用接口地址 或通过以下js方式调用本文不做叙述自行了解其他方式以下提供案例代码
js文件

import axios from 'axios'
import { getToken } from '@/utils/auth'

const mimeMap = {
  xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  zip: 'application/zip'
}

const baseUrl = process.env.VUE_APP_BASE_API //接口前缀换成自己的
export function downLoadZip(str, filename) {
  var url = baseUrl + str
  axios({
    method: 'get',
    url: url,
    responseType: 'blob',
    headers: { 'Authorization': 'Bearer ' + getToken() }
  }).then(res => {
    resolveBlob(res, mimeMap.zip)
  })
}
/**
 * 解析blob响应内容并下载
 * @param {*} res blob响应内容
 * @param {String} mimeType MIME类型
 */
export function resolveBlob(res, mimeType) {
  const aLink = document.createElement('a')
  var blob = new Blob([res.data], { type: mimeType })
  // //从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
  var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
  var contentDisposition = decodeURI(res.headers['content-disposition'])
  var result = patt.exec(contentDisposition)
  var fileName = result[1]
  fileName = fileName.replace(/\"/g, '')
  aLink.href = URL.createObjectURL(blob)
  aLink.setAttribute('download', fileName) // 设置下载文件名称
  document.body.appendChild(aLink)
  aLink.click()
  document.body.appendChild(aLink)
}

在具体页面模块引入该文件的downLoadZip 方法

import { downLoadZip } from "@/utils/zipdownload";

在具体事件上调用下载方法

handleGenTable(row) {
      downLoadZip("传入接口路径从controller层开始填写" , "zip文件名称");// 例如downLoadZip("/test/downLoadZip", "test");
    }

以下附上后端代码

下载工具类

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.nuoer.common.utils.aliyun.CloudConstant;
import com.nuoer.common.utils.pdf.PdfUtil;
import com.nuoer.project.cv.domain.SkillCert;
import com.nuoer.project.personalCenter.domain.MineDto;
import lombok.SneakyThrows;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 文件下载类
 * 本类提供两种多线程批量下载方式
 * 方式一 : 实体文件储存到本地磁盘后输出到浏览器
 * 方式二: 直接处理远程拉取到的文件流byte[] 数组后输出到浏览器
 */
public class DownloadUtil {

    private static Logger logger = LoggerFactory.getLogger(DownloadUtil.class);

    /**
     * 下载线程数
     */
    private static final int DOWNLOAD_THREAD_NUM = 14;

    /**
     * 下载线程池
     */
    private static ExecutorService downloadExecutorService = ThreadUtil
            .buildDownloadBatchThreadPool(DOWNLOAD_THREAD_NUM);

    /**
     * 创建文件夹,如果文件夹已经存在或者创建成功返回true
     *
     * @param path
     *      路径
     * @return boolean
     */
    private static boolean createFolderIfNotExists(String path) {
        String folderName = getFolder(path);
        if (folderName.equals(path)) {
            return true;
        }
        File folder = new File(getFolder(path));
        if (!folder.exists()) {
            synchronized (DownloadUtil.class) {
                if (!folder.exists()) {
                    return folder.mkdirs();
                }
            }
        }
        return true;
    }

    /**
     * 获取文件夹
     *
     * @param path
     *      文件路径
     * @return String
     */
    private static String getFolder(String path) {
        int index = path.lastIndexOf("/");
        return -1 != index ? path.substring(0, index) : path;
    }


    /**
     * 获取最后一个元素
     *
     * @param size
     *      列表长度
     * @param index
     *      下标
     * @return int
     */
    private static int getLastNum(int size, int index) {
        return index > size ? size : index;
    }

    /**
     * 获取划分页面数量
     *
     * @param size
     *      列表长度
     * @return int
     */
    private static int getPageNum(int size) {
        int tmp = size / DOWNLOAD_THREAD_NUM;
        return size % DOWNLOAD_THREAD_NUM == 0 ? tmp : tmp + 1;
    }


    /**
     *  通过http请求获取远程文件信息 文件下载
     *
     * @param fileUrl
     *      文件url,如:<code>https://i
  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值