使用zip工具类打包下载压缩图片?
最近工作遇到一需求,让我把用户想要的图片下载下来,并打包成压缩包。当用户没选择时,就下载所有的图片。由于感觉很有意思,便做一下学习总计。
首先说一下,制作的思路。前端监听了table的checkbox属性,当点击图片导出按钮时,获取到选择的商品图片路径,然后向后端接口发起文件下载请求。后端接口接收得到图片路径集合,获取到图片文件,然后创建压缩包进行文件压缩,压缩完成后返回给浏览器。
前端代码
var path = { exportImg: "/goods/exportImg", }; /** * 图片打包导出 * @param data */ function exportImg(data) { var imgList=[]; for(var i=0;i<data.length;i++){ //获取图片路径,如:/2019/9/2/1567386702045.png imgList.push(data[i].goodsFirstPic); } var url= window.ptfConfig.baseUrl + path.exportImg+ "?imgList="+imgList +"&access_token=" + access_token; window.location.href = url; }
后端代码
controller层
@Controller @RequestMapping("goods") public class PtfGoodsController extends GenericController { private static final Logger LOGGER = LoggerFactory.getLogger(PtfGoodsController.class); @Autowired private PtfGoodsService ptfGoodsService; @Autowired private SecurityHandler securityHandler; /** * @Param [req, resp, imgList] * @return void * @Author youjp * @Description //TODO 商品图片导出 * @throw **/ @GetMapping("exportImg") public void exportImg(HttpServletResponse resp,@RequestParam("imgList") List<String> imgList) throws IOException{ ptfGoodsService.exportImg(resp,imgList); } }
service层
@Service @Transactional(rollbackFor = Throwable.class) public class PtfGoodsService extends GoodsService { @Autowired private PtfGoodsDao ptfGoodsDao; @Value("${image.uploadPath}") private String imageUploadPath; @Autowired private ZipService zipService; /** * @Param [resp, imgList] * @return void * @Author youjp * @Description //TODO 商品图片打包导出 * @throw **/ public void exportImg(HttpServletResponse resp,List<String> imgList) throws IOException { //压缩文件集 List<File> fileList = new ArrayList<>(); //图片集为空,则下载全部 if (!CollectionUtils.isEmpty(imgList)) { for (int i = 0; i < imgList.size(); i++) { //获取图片路径 String url = imgList.get(i); String endPrix = url.substring(url.lastIndexOf("."), url.length()); String imgPath = imageUploadPath + File.separator + url; //图片全路径 if (zipService.fileIsExists(imgPath)) { //文件存在 fileList.add(new File(imgPath)); } else { //图片文件不存在 } } } else { System.out.println(imgList.size()+":图片集为空!!!"); List<GoodsDto> goods = ptfGoodsDao.selectAllImg(); for (int i = 0; i < goods.size(); i++) { //获取图片路径 String url = goods.get(i).getGoodsFirstPic(); String endPrix = url.substring(url.lastIndexOf("."), url.length()); String imgPath = imageUploadPath + File.separator + url; //图片全路径 if (zipService.fileIsExists(imgPath)) { //文件存在 fileList.add(new File(imgPath)); } else { //图片文件不存在 } } } //定义压缩包名 Date date = new Date(); SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); String dateStr = sDateFormat.format(date); String fileZipName = dateStr + ".zip"; //以当前时间命名压缩包 String zipName = imageUploadPath + File.separator + fileZipName;//压缩包所在路径位置 ServletOutputStream outputStream = null; FileInputStream fileInputStream = null; BufferedInputStream bufferedInputStream = null; try { List images=removeDuplicate(fileList); //图片名去重 //打包压缩文件 File zipFile = new File(zipName); //创建压缩包对象 FileOutputStream fos2 = new FileOutputStream(zipFile); ZipService.toZip(images, fos2); //发头控制浏览器不要缓存 resp.setDateHeader("expries", -1); resp.setHeader("Cache-Control", "no-cache"); resp.setHeader("Pragma", "no-cache"); resp.setContentType("application/x-octet-stream"); resp.setContentLength((int) zipFile.length()); resp.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileZipName, "UTF-8")); //写流文件到前端浏览器 outputStream = resp.getOutputStream(); fileInputStream = new FileInputStream(new File(zipName)); bufferedInputStream = new BufferedInputStream(fileInputStream); byte[] b = new byte[bufferedInputStream.available()]; bufferedInputStream.read(b); outputStream.write(b); } catch (Exception e) { e.printStackTrace(); } finally { //关闭流 if (outputStream != null) { outputStream.close(); } if (bufferedInputStream != null) { bufferedInputStream.close(); } if (fileInputStream != null) { fileInputStream.close(); } //删除zip包 try { Thread.sleep(1000); zipService.deleteFile(zipName); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * @Param [list] * @return java.util.List * @Author youjp * @Description //TODO 重复图片去重 * @throw **/ public static List removeDuplicate(List<File> list) { for ( int i = 0 ; i < list.size() - 1 ; i ++ ) { for ( int j = list.size() - 1 ; j > i; j -- ) { if(j!=i){ File file1= (File) list.get(j); File file2=(File)list.get(i); if (file1.getName().equals(file2.getName())) { list.remove(j); } } } } return list; } }
zip工具类
package com.hrt.zxxc.fxspg.zip.service; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * @ClassName: * @PackageName: com.hrt.zxxc.fxspg.zip.service * @author: youjp * @create: 2019-09-11 14:55 * @description: * @Version: 1.0 */ @Service public class ZipService { @Value("${image.uploadPath}") private String imageUploadPath; private static final int BUFFER_SIZE = 10 * 1024*1024; /** * 压缩成ZIP 方法2 * @param srcFiles 需要压缩的文件列表 * @param out 压缩文件输出流 * @throws RuntimeException 压缩失败会抛出运行时异常 */ public static void toZip(List<File> srcFiles , OutputStream out)throws RuntimeException { long start = System.currentTimeMillis(); ZipOutputStream zos = null ; try { zos = new ZipOutputStream(out); for (File srcFile : srcFiles) { byte[] buf = new byte[BUFFER_SIZE]; zos.putNextEntry(new ZipEntry(srcFile.getName())); int len=0; FileInputStream in = new FileInputStream(srcFile); while ((len = in.read(buf,0,1024*10)) != -1){ zos.write(buf, 0, len); } zos.closeEntry(); in.close(); } long end = System.currentTimeMillis(); System.out.println("压缩完成,耗时:" + (end - start) +" ms"); } catch (Exception e) { e.printStackTrace(); // throw new RuntimeException("zip error from ZipUtils",e); }finally{ if(zos != null){ try { zos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * @Param [fileName] * @return boolean * @Author youjp * @Description //TODO删除文件 * @throw **/ public static boolean deleteFile(String fileName) { File file = new File(fileName); // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除 if (file.exists() && file.isFile()) { if (file.delete()) { System.out.println("删除单个文件" + fileName + "成功!"); return true; } else { System.out.println("删除单个文件" + fileName + "失败!"); return false; } } else { System.out.println("删除单个文件失败:" + fileName + "不存在!"); return false; } } /** * @Param [fileName] * @return boolean * @Author youjp * @Description //TODO 文件是否存在 * true:存在 * false:不存在 * @throw **/ public static boolean fileIsExists(String fileName){ File file = new File(fileName); if (file.exists() && file.isFile()) { return true; } else { return false; } } }
图片及压缩包导出效果图
代码下载:
https://download.csdn.net/download/qq_36654629/11759805
有兴趣的老爷,可以关注我的公众号【一起收破烂】,回复【006】获取2021最新java面试资料以及简历模型120套哦~