需求是多个文件需要同时打包成zip压缩文件并下载到本地,首先我需要的是知道下载文件的路径。我有一个专门的sys_file_info表,表中有对应的文件路径。业务表中的文件地址放的就是文件表的id值。下面是代码:
1.Mapper层
<select id="selectScriptPathList" parameterType="String" resultType="map"> SELECT i.file_path filePath, i.file_name fileName FROM ves_data_poc p LEFT JOIN sys_file_info i ON p.script_url = i.file_id WHERE i.file_path IS NOT NULL AND p.id IN <foreach item="id" collection="array" open="(" separator="," close=")"> #{id} </foreach> </select>
List<Map<String, String>> selectScriptPathList(String[] ids);
2.Service层
idStr 是前端传来的多个id值用逗号连接的字符串
/** * 下载ZIP包 * @param idStr * @param response */ void download(String idStr, HttpServletResponse response);
@Override public void download(String idStr, HttpServletResponse response) { if (StringUtils.isNotEmpty(idStr)) { String[] ids = idStr.split(","); List<Map<String, String>> filePaths = vesDataPocMapper.selectScriptPathList(ids); String zipName = "POC_" + ((int) (Math.random() * 10000)) + ".zip"; String zipPath = Global.getProfile() + "/" + zipName; CompressUtil.compress(filePaths, zipPath, false); File pocZipFile = new File(zipPath); CompressUtil.downloadZip(response, zipName, pocZipFile); } }
3.Controller层
/** * 下载poc文件 支持多个下载 * 格式 zip包 * * @param ids */ @Log(title = "数据管理-POC", businessType = BusinessType.EXPORT) @GetMapping("/download") public void download(String ids, HttpServletResponse response) { vesDataPocService.download(ids, response); }
4.工具类
import org.apache.commons.lang3.StringUtils; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class CompressUtil { /** * 生成zip压缩文件 * @param filePaths * @param zipFilePath * @param keepDirStructure */ public static void compress(List<Map<String, String>> filePaths, String zipFilePath, Boolean keepDirStructure) { byte[] buf = new byte[1024]; File zipFile = new File(zipFilePath); try { ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile)); for (int i = 0; i < filePaths.size(); i++) { String relativePath = filePaths.get(i).get("filePath"); String relativeName = filePaths.get(i).get("fileName"); if (StringUtils.isEmpty(relativePath)) { continue; } File sourceFile = new File(relativePath); if (sourceFile == null || !sourceFile.exists()) { continue; } FileInputStream fis = new FileInputStream(sourceFile); if (keepDirStructure != null && keepDirStructure) { zos.putNextEntry(new ZipEntry(relativePath)); } else { zos.putNextEntry(new ZipEntry(i + "_" + relativeName)); } int len; while ((len = fis.read(buf)) > 0) { zos.write(buf, 0, len); } zos.closeEntry(); // zos.close(); } zos.close(); if (!zipFile.exists()) { zipFile.createNewFile(); } } catch (Exception e) { e.printStackTrace(); } } /** * 下载zip * * @param response * @param zipName 浏览器header中zip名称 * @param zipFile zipFile文件 */ public static void downloadZip(HttpServletResponse response, String zipName, File zipFile) { //下载文件 try { response.setCharacterEncoding("utf-8"); response.setContentType("application/zip"); response.setHeader("Content-Disposition", "attachment;FileName=" + zipName); ServletOutputStream out = response.getOutputStream(); int len = 0; byte[] buffer = new byte[1024]; FileInputStream fis = new FileInputStream(zipFile); while ((len = fis.read(buffer)) > 0) { out.write(buffer, 0, len); out.flush(); } out.close(); fis.close(); response.flushBuffer(); } catch (IOException e) { e.printStackTrace(); } } }