java+vue多文件打包zip下载

java+vue实现多文件打包下载

前端传过下载文件编号,在数据库中根据编号查出对应文件存储的路径,根据路径将文件写入到HttpServletResponse中,设置文本传输类型为二进制流response.setContentType("APPLICATION/OCTET-STREAM"),将其返回给前端。

1.java后台

1.1.controller

@GetMapping("/download/{contractId}")
    public void download(@PathVariable("contractId")String contractId, HttpServletResponse response) throws IOException {
        String zipName = System.currentTimeMillis()+"myfile.zip";
        //根据contractId找到下载文件的路径
        List<String> filePath = erpContractFileService.queryErpContractFilePathByContractId(contractId);
        response.setContentType("APPLICATION/OCTET-STREAM");
        response.setHeader("Content-Disposition","attachment; filename="+zipName);
        ZipOutputStream out = new ZipOutputStream(response.getOutputStream());
        try {
            for (String fPath : filePath) {
                ZipUtils.doCompress(fPath, out);
                response.flushBuffer();
            }
        }
        catch (Exception e) {
            throw new RuntimeException("下载文件失败",e);
        }finally{
            out.close();
        }
    }

1.2.zipUtils

package com.lyw.erp.contract.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipUtils {
    private ZipUtils(){
    }

    public static void doCompress(String srcFile, String zipFile) throws IOException {
        doCompress(new File(srcFile), new File(zipFile));
    }

    public static void doCompress(File srcFile, File zipFile) throws IOException {
        ZipOutputStream out = null;
        try {
            out = new ZipOutputStream(new FileOutputStream(zipFile));
            doCompress(srcFile, out);
        } catch (Exception e) {
            throw e;
        } finally {
            out.close();//记得关闭资源
        }
    }

    public static void doCompress(String filelName, ZipOutputStream out) throws IOException{
        doCompress(new File(filelName), out);
    }

    public static void doCompress(File file, ZipOutputStream out) throws IOException{
        doCompress(file, out, "");
    }

    public static void doCompress(File inFile, ZipOutputStream out, String dir) throws IOException {
        if ( inFile.isDirectory() ) {
            File[] files = inFile.listFiles();
            if (files!=null && files.length>0) {
                for (File file : files) {
                    String name = inFile.getName();
                    if (!"".equals(dir)) {
                        name = dir + "/" + name;
                    }
                    ZipUtils.doCompress(file, out, name);
                }
            }
        } else {
            ZipUtils.doZip(inFile, out, dir);
        }
    }

    public static void doZip(File inFile, ZipOutputStream out, String dir) throws IOException {
        String entryName = null;
        if (!"".equals(dir)) {
            entryName = dir + "/" + inFile.getName();
        } else {
            entryName = inFile.getName();
        }
        ZipEntry entry = new ZipEntry(entryName);
        out.putNextEntry(entry);

        int len = 0 ;
        byte[] buffer = new byte[1024];
        FileInputStream fis = new FileInputStream(inFile);
        while ((len = fis.read(buffer)) > 0) {
            out.write(buffer, 0, len);
            out.flush();
        }
        out.closeEntry();
        fis.close();
    }
}

2.vue前端

2.1 api(axios) 需要指定返回的类型,不然会出现乱码, responseType:‘blob’

//文件下载
export function download(contractId) {
  return request({
    url: '/contract/download/'+contractId,
    method: 'get',
    responseType:'blob'
  })
}

2.2 views

<template>
  <div class="app-container">
      <!-- ------省略----- -->
      <el-table-column label="合同附件" align="center" prop="file" >
        <el-button
          slot-scope="scope"
          size="mini"
          type="text"
          v-hasPermi="['contract:contract:download']"
          @click="downloadFile(scope.row.contractId)"
        >点击下载
        </el-button>
      </el-table-column>
  </div>
</template>

2.3 js

import { listContract, getContract, delContract,download } from "@/api/basic/contract/contract";
import {blobValidate} from "@/utils/ruoyi";
import errorCode from "@/utils/errorCode";
import { saveAs } from 'file-saver';
export default {
//省略

  methods: {
      downloadFile(contractId){
      // console.log(contractId);
      download(contractId).then(async data => {
        const isLogin = await blobValidate(data);
        console.log(data)
        let name = contractId + "附件.zip";
        if (isLogin) {
          const blob = new Blob([data])
          saveAs(blob, name);
        } else {
          const resText = await data.text();
          const rspObj = JSON.parse(resText);
          const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
          Message.error(errMsg);
        }
        downloadLoadingInstance.close();
      }).catch(error => {
        console.error(r)
        Message.error('下载文件出现错误,请联系管理员!')
        downloadLoadingInstance.close();
      });
    },
  }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值