奥展项目笔记12-批量下载文件

1.批量下载文件

最近项目有个需求,用户批量下载pdf文件,下面记录我实现的解决方案。

 

前端代码(基于vue):

//批量下载用户选中的一些质量证明书
            downloadSomeQualityPaper() {
                let trs = document.getElementById("check-state").getElementsByTagName("tr");
                let inputs=document.getElementById("check-state").getElementsByTagName("input");
                let lotnoid="";
                for (let i = 1; i <inputs.length ; i++) {
                    if(inputs[i].checked){
                        let tds=trs[i].getElementsByTagName("td");
                        lotnoid=lotnoid+tds[2].innerText+",";
                    }
                }
                console.log(lotnoid);
                this.form.lotnoid=lotnoid;
                aozhan.http.post("/user/downloadSomeQualityPaper", aozhan.stringify(this.form),{responseType: 'blob'})
                    .then(resp => {
                        if (resp.status === 200) {
                            const link = document.createElement('a');
                            let blob = new Blob([resp.data],{type: 'application/zip'});
                            link.style.display = 'none';
                            link.href = URL.createObjectURL(blob);
                            link.setAttribute('download',   '质保书.zip');
                            document.body.appendChild(link);
                            link.click();
                            document.body.removeChild(link);

                        }
                    })
                    .catch(() => this.msg = '')

            },

后端代码(基于springboot):

/**
     * 功能介绍:根据产品批号集合批量下载质量证明书
     * @param request http request请求
     * @param response http response 响应
     * @param lotnoid 批号集合
     */
    @PostMapping("downloadSomeQualityPaper")
    public ResponseEntity<Void> downloadSomeQualityPaper(HttpServletRequest request, HttpServletResponse response,String lotnoid) {
        //1.定义存放文件名和路径的集合
        List<String> names=new ArrayList<>();
        List<String> paths=new ArrayList<>();
        String[] lotnoids = lotnoid.split(",");
        for (int i = 0; i <lotnoids.length ; i++) {
            QualityPaperMessage qualityPaperMessage=new QualityPaperMessage();
            qualityPaperMessage.setLotno(lotnoids[i]);
            List<QualityPaperMessage> qualityPaperMessageList = qualityPaperMessageMapper.select(qualityPaperMessage);
            QualityPaperMessage queryResult=null;
            if(qualityPaperMessageList.size()>0){
                queryResult=qualityPaperMessageList.get(qualityPaperMessageList.size()-1);
                String path=queryResult.getResourcelocation();
                String filename=queryResult.getLotno()+".pdf";
                names.add(filename);
                paths.add(path);
            }
        }

        //服务器上存放zip文件的目录
        String directory = "D:\\repository\\ziptemp";
        File directoryFile=new File(directory);
        if(!directoryFile.isDirectory() && !directoryFile.exists()){
            directoryFile.mkdirs();
        }
        //设置最终输出zip文件的目录+文件名
        SimpleDateFormat formatter  = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
        String zipFileName = formatter.format(new Date())+"质保书.zip";
        String strZipPath = directory+"\\"+zipFileName;

        ZipOutputStream zipStream = null;
        FileInputStream zipSource = null;
        BufferedInputStream bufferStream = null;
        File zipFile = new File(strZipPath);
        try{
            //构造最终压缩包的输出流
            zipStream = new ZipOutputStream(new FileOutputStream(zipFile));
            for (int i = 0; i<paths.size() ;i++){
                //解码获取真实路径与文件名
                String realFileName = names.get(i);
                String realFilePath = paths.get(i);
                File file = new File(realFilePath);
                //TODO:未对文件不存在时进行操作,后期优化。
                if(file.exists())
                {
                    zipSource = new FileInputStream(file);//将需要压缩的文件格式化为输入流
                    /**
                     * 压缩条目不是具体独立的文件,而是压缩包文件列表中的列表项,称为条目,就像索引一样这里的name就是文件名,
                     * 文件名和之前的重复就会导致文件被覆盖
                     */
                    ZipEntry zipEntry = new ZipEntry(realFileName);//在压缩目录中文件的名字
                    zipStream.putNextEntry(zipEntry);//定位该压缩条目位置,开始写入文件到压缩包中
                    bufferStream = new BufferedInputStream(zipSource, 1024 * 10);
                    int read = 0;
                    byte[] buf = new byte[1024 * 10];
                    while((read = bufferStream.read(buf, 0, 1024 * 10)) != -1)
                    {
                        zipStream.write(buf, 0, read);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                if(null != bufferStream) bufferStream.close();
                if(null != zipStream){
                    zipStream.flush();
                    zipStream.close();
                }
                if(null != zipSource) zipSource.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //判断系统压缩文件是否存在:true-把该压缩文件通过流输出给客户端后删除该压缩文件  false-未处理
        if(zipFile.exists()){
            DownloadUtil.downloadFile(strZipPath, zipFileName, response, request);
            //downImg(response,zipFileName,strZipPath);
            zipFile.delete();
        }

        return new ResponseEntity<>(HttpStatus.OK);
    }

文件下载工具类:

package lucky.aozhan.user.utils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/***
 * 将文件内容响应到浏览器
 */
public class DownloadUtil {

    // 字符编码格式
    private static String charsetCode = "utf-8";


    /**
     * 文件的内容类型
     */
    private static String getFileContentType(String name){
        String result = "";
        String fileType = name.toLowerCase();
        if (fileType.endsWith(".png")) {
            result = "image/png";
        } else if (fileType.endsWith(".gif")) {
            result = "image/gif";
        } else if (fileType.endsWith(".jpg") || fileType.endsWith(".jpeg")) {
            result = "image/jpeg";
        } else if(fileType.endsWith(".svg")){
            result = "image/svg+xml";
        }else if (fileType.endsWith(".doc")) {
            result = "application/msword";
        } else if (fileType.endsWith(".xls")) {
            result = "application/x-excel";
        } else if (fileType.endsWith(".zip")) {
            result = "application/zip";
        } else if (fileType.endsWith(".pdf")) {
            result = "application/pdf";
        } else if (fileType.endsWith(".xlsx")) {
            result = "application/vnd.ms-excel";
        }else {
            result = "application/octet-stream";
        }
        return result;
    }

    /**
     * 下载文件
     * @param path 文件的位置
     * @param fileName 自定义下载文件的名称
     * @param resp http响应
     * @param req http请求
     */
    public static void downloadFile(String path, String fileName, HttpServletResponse resp, HttpServletRequest req){

        try {
            File file = new File(path);
            /**
             * 中文乱码解决
             */
            String type = req.getHeader("User-Agent").toLowerCase();
            if(type.indexOf("firefox")>0 || type.indexOf("chrome")>0){
                /**
                 * 谷歌或火狐
                 */
                fileName = new String(fileName.getBytes(charsetCode), "iso8859-1");
            }else{
                /**
                 * IE
                 */
                fileName = URLEncoder.encode(fileName, charsetCode);
            }
            // 设置响应的头部信息
            resp.setHeader("content-disposition", "attachment;filename=" + fileName);
            // 设置响应内容的类型
            String contentType=getFileContentType(fileName)+"; charset=" + charsetCode;
            resp.setContentType(contentType);
            System.out.println("contentType:"+contentType);
            // 设置响应内容的长度
            //resp.setContentLength((int) file.length());

            resp.setHeader("Content-Length", String.valueOf(file.length()));
            // 输出
            outStream(new FileInputStream(file), resp.getOutputStream());
        } catch (Exception e) {
            System.out.println("执行downloadFile发生了异常:" + e.getMessage());
        }
    }

    /**
     * 基础字节数组输出
     */
    private static void outStream(InputStream is, OutputStream os) {
        try {
            byte[] buffer = new byte[1024];
            int length = -1;
            while ((length = is.read(buffer)) != -1) {
                os.write(buffer, 0, length);
                os.flush();
            }
        } catch (Exception e) {
            System.out.println("执行 outStream 发生了异常:" + e.getMessage());
        } finally {
            try {
                os.close();
            } catch (IOException e) {
            }
            try {
                is.close();
            } catch (IOException e) {
            }
        }
    }

}

 参考文献:https://blog.csdn.net/zf18234031156/article/details/83744097?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

posted @ 2020-03-09 14:44  雨后观山色  阅读(240)  评论(0编辑  收藏  举报