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