使用Java如何实现批量下载
创始人
2024-11-19 06:04:23
0次

引言

        批量下载思路,首先前端发送下载请求,携带必要参数,也可无参默认批量下载页面全部数据;后台接收后进行数据处理拿到要下载文件的下载地址,循环下载地址,用压缩流,将文件直接写入压缩包,最后利用文件下载将压缩包输出给前端。

一、前端JS发送下载请求

1、ajax无法发送下载请求

        关于下载的常见需求无非就是点击按钮下载或者选中点击批量下载,点击下载或批量下载后,携带参数向后台发送下载请求,但是JS中的ajax无法触发浏览器的下载机制,这也是处于安全考虑,所以下载请求不可以通过发送ajax请求实现。

2、js发送下载请求:超链接方式

        我们可以通过< a >标签实现,在a标签的href中拼接get请求并携带所需参数,如下

下载

批量下载,前端可以传每条数据的id,用逗号拼接成字符串,后台接收后进行数据处理,然后进行批量下载,但是此方式有局限性,如果我选中了很多条数据,每条数据的id都是32位UUID,那get请求无法携带大量参数,所以这种方式并不适合批量下载,只适合单条数据下载。

3、js发送下载请求:拼接Form表单,并提交

        form表单也有局限性,例如form表单不能传输json格式的数据,也就是说用此方式提交,后台不能用@RequestBody注解

$('.download-btn').click(function () {
 // 如果要传选中行的id,则从页面获取到所有id,可以拿逗号拼接,放到输入框传给后台
 // 如果需要把选中行整行数据传到后台,form表单不支持传json格式数据,所以可以把
 // 选中行数据放入数组,转为json放入输入框,后台用String接收,然后再转回Obj
 var $dataForm = $(
 "
" + "" + "
" ); $dataForm.attr("action", 'localhost:8080/download'); $(document.body).append($dataForm); //提交表单,实现下载 $dataForm.submit(); });

        如上边代码所示,传参为ids,那如果你想传obj,可以用JSON.stringify()将前端对象或数组类型转为json字符串,然后赋值给表单的输入框,一并提交给后台,后台用String接收,然后再转回Object,我在测试过程中 js提交数据到后台(json)," 被转译 成了& quot;,如果你也遇到,请看这篇文章:文章链接

二、后台处理

        此处省略接收参数,获取需要下载的文件的url,直接写死模拟:

@RequestMapping(value = "/download", method = RequestMethod.POST)
public void plistDownLoad(HttpServletResponse response) throws Exception {
 // 此处模拟处理ids,拿到文件下载url
 List paths = new ArrayList<>();
 paths.add("C:\\Users\\E480\\Desktop\\Study\\casul笔记.txt");
 paths.add("C:\\Users\\E480\\Desktop\\Study\\config配置中心笔记.txt");
 paths.add("C:\\Users\\E480\\Desktop\\Study\\GateWay.txt");
 if (paths.size() != 0) {
 // 创建临时路径,存放压缩文件
 String zipFilePath = "D:\\workspace-IDEA\\zip\\我的zip.zip";
 // 压缩输出流,包装流,将临时文件输出流包装成压缩流,将所有文件输出到这里,打成zip包
 ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFilePath));
 // 循环调用压缩文件方法,将一个一个需要下载的文件打入压缩文件包
 for (String path : paths) {
  // 该方法在下面定义
  fileToZip(path, zipOut);
 }
 // 压缩完成后,关闭压缩流
 zipOut.close();

 //拼接下载默认名称并转为ISO-8859-1格式
 String fileName = new String(("我的压缩文件.zip").getBytes(),"ISO-8859-1");
 response.setHeader("Content-Disposition", "attchment;filename="+fileName);

 //该流不可以手动关闭,手动关闭下载会出问题,下载完成后会自动关闭
 ServletOutputStream outputStream = response.getOutputStream();
 FileInputStream inputStream = new FileInputStream(zipFilePath);
 // 如果是SpringBoot框架,在这个路径
 // org.apache.tomcat.util.http.fileupload.IOUtils产品
 // 否则需要自主引入apache的 commons-io依赖
 // copy方法为文件复制,在这里直接实现了下载效果
 IOUtils.copy(inputStream, outputStream);

 // 关闭输入流
 inputStream.close();

 //下载完成之后,删掉这个zip包
 File fileTempZip = new File(zipFilePath);
 fileTempZip.delete();
 }
}

        将文件打包的方法,需要传一个压缩路径,和一个文件,一次只将一个文件写入压缩包

public static void fileToZip(String filePath,ZipOutputStream zipOut) throws IOException {
 // 需要压缩的文件
 File file = new File(filePath);
 // 获取文件名称,如果有特殊命名需求,可以将参数列表拓展,传fileName
 String fileName = file.getName();
 FileInputStream fileInput = new FileInputStream(filePath);
 // 缓冲
 byte[] bufferArea = new byte[1024 * 10];
 BufferedInputStream bufferStream = new BufferedInputStream(fileInput, 1024 * 10);
 // 将当前文件作为一个zip实体写入压缩流,fileName代表压缩文件中的文件名称
 zipOut.putNextEntry(new ZipEntry(fileName));
 int length = 0;
 // 最常规IO操作,不必紧张
 while ((length = bufferStream.read(bufferArea, 0, 1024 * 10)) != -1) {
 zipOut.write(bufferArea, 0, length);
 }
 //关闭流
 fileInput.close();
 // 需要注意的是缓冲流必须要关闭流,否则输出无效
 bufferStream.close();
 // 压缩流不必关闭,使用完后再关
}

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...