通过url地址批量打包zip下载文件

通过url地址批量打包zip下载文件

controller

	@ApiOperation("通过下载url批量打包zip下载")
    @PostMapping("batchDownloadFile")
    public void batchDownloadFile(@RequestBody List<String> urlList){
        log.debug("通过下载url批量打包zip下载 入参 {} ", urlList.toString());
        if (CollectionUtils.isEmpty(attachmentVoList)){
            return;
        }
        fileService.batchDownloadFile(urlList,this.getResponse(),this.getRequest());
    }

service接口

	/**
     * 通过下载url批量打包zip下载
     * @param urlList需下载的文件信息(下载地址,文件名称)
     * @param response 响应
     */
    void batchDownloadFile(List<String> urlList, HttpServletResponse response, HttpServletRequest request);

service实现类

	/** 需要压缩的文件夹 */
    private final static String downloadDir = "download";
    /** 打包后的文件夹 */
    private final static String downloadZip = "downloadZip";

    /**
     *  重载通过下载url批量打包zip下载
     * @param urlList需下载的文件信息(下载地址,文件名称)
     * @param response 响应
     */
    @Override
    public void batchDownloadFile(List<String> urlList, HttpServletResponse response, HttpServletRequest request) {
        //下载文件
        urlList.stream().forEach(this::downloadFile);
        //把下载的图片文件夹压缩
        downloadZip(request, response);
    }
    
    /**
     * 下载文件
     * @param attachmentVo 文件
     */
    public void downloadFile(String fileUrl){
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            //获取连接
            URL url = new URL(fileUrl);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            connection.setConnectTimeout(3*1000);
            //设置请求头
            connection.setRequestProperty(
                    "User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36");
            //获取输入流
            inputStream = connection.getInputStream();
            // 创建一个文件夹 download
            File fileDir = new File(downloadDir);
            if(!fileDir.exists()){
                fileDir.mkdir();
            }

            // 将文件下载到download文件夹下 文件下载保存路径
            String filePath = downloadDir +  "/" + 此处为文件名称,可通过传入也可通过地址字符串截取;
            // 通过路径创建文件
            File file = new File(filePath);
            //创建文件,存在覆盖
            file.createNewFile();

            outputStream = new FileOutputStream(file);
            int len = 0;
            byte[] buf = new byte[1024];
            while ((len = inputStream.read(buf, 0, 1024)) != -1) {
                outputStream.write(buf, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("文件下载出错:" + e);
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                log.error("关闭流出错:" + e);
            }
        }
    }

    /**
     * 下载压缩包
     */
    public void downloadZip(HttpServletRequest request, HttpServletResponse res)  {
        OutputStream out = null;
        File zip = null;
        File fileDir = null;
        ZipOutputStream zos = null;
        BufferedInputStream bis = null;
        try{
            //多个文件进行压缩,批量打包下载文件 创建压缩文件需要的空的zip包
            String zipName = "zip文件";
            // zip文件存放路径
            String zipFilePath = downloadZip + File.separator + zipName + ".zip";
            fileDir = new File(downloadZip);
            if(!fileDir.exists()){
                fileDir.mkdir();
            }
            //压缩文件
            zip = new File(zipFilePath);
            //创建文件,存在覆盖
            zip.createNewFile();

            //创建zip文件输出流
            zos = new ZipOutputStream(new FileOutputStream(zip));
            this.zipFile(downloadDir, zos);
            if (zos != null){
                zos.close();
            }
            //将打包后的文件写到客户端,输出的方法同上,使用缓冲流输出
            bis = new BufferedInputStream(new FileInputStream(zipFilePath));
            byte[] buff = new byte[bis.available()];
            bis.read(buff);
            //IO流实现下载的功能
            res.setCharacterEncoding("UTF-8");
            // 设置下载内容类型application/octet-stream(二进制流,未知文件类型);
            res.setContentType("application/octet-stream;charset=UTF-8");
            //防止文件名乱码
            String userAgent = request.getHeader("USER-AGENT");
            //火狐浏览器
            if (userAgent.contains("Firefox") || userAgent.contains("firefox")) {
                zipName = new String(zipName.getBytes(), "ISO8859-1");
            } else {
                //其他浏览器
                zipName = URLEncoder.encode(zipName, "UTF-8");
            }
            //设置下载的压缩文件名称
            res.setHeader("Content-disposition", "attachment;filename=" + zipName);
            //创建页面返回方式为输出流,会自动弹出下载框
            out = res.getOutputStream();
            //输出数据文件
            out.write(buff);
            FileUtil.deleteDir(downloadDir);
        }catch(Exception e) {
            log.error("压缩包下载出错:" + e);
        }finally {
            try{
                if (zos != null){
                    zos.flush();
                    zos.close();
                }
                if (bis != null){
                    bis.close();
                }
                if(out != null){
                    out.flush();
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            // // 删除zip文件
            // zip.delete();
            // // 删除zip的文件夹
            // fileDir.delete();
            FileUtil.deleteDir(downloadZip);
        }
    }

    /**
     * 压缩文件
     * @param filePath	需要压缩的文件夹
     * @param zos	zip文件输出流
     */
    private void zipFile(String filePath,ZipOutputStream zos)   {
        //根据文件路径创建文件
        File inputFile = new File(filePath);
        if(inputFile.exists()) {
            //判断是否属于文件,还是文件夹
            if (inputFile.isFile()) {
                BufferedInputStream bis = null;
                try{
                    //创建输入流读取文件
                    bis = new BufferedInputStream(new FileInputStream(inputFile));
                    //将文件写入zip内,即将文件进行打包
                    zos.putNextEntry(new ZipEntry(inputFile.getName()));
                    //写入文件的方法,同上
                    int size = 0;
                    //设置读取数据缓存大小
                    byte[] buffer = new byte[1024];
                    while ((size = bis.read(buffer)) > 0) {
                        zos.write(buffer, 0, size);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    //关闭输入输出流
                    try {
                        zos.closeEntry();
                        //关闭输入输出流
                        if (bis != null){
                            bis.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            } else {
                //如果是文件夹,则使用递归的方法获取文件,写入zip
                try {
                    File[] files = inputFile.listFiles();
                    if (ObjectUtils.isNotEmpty(files)){
                        for (File fileTem : files) {
                            zipFile(fileTem.toString(),zos);
                        }
                    }
                } catch (Exception e) {
                    log.error("压缩文件出错:" + e);
                }
            }
        }
    }

FileUtil 工具类

package com.gremlin.common.core.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelUtil;
import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * File工具类,扩展 hutool 工具包
 * @author fremlin
 * @date 2013-03-08
 */
public class FileUtil extends cn.hutool.core.io.FileUtil {

    /**
     * 定义GB的计算常量
     */
    private static final int GB = 1024 * 1024 * 1024;
    /**
     * 定义MB的计算常量
     */
    private static final int MB = 1024 * 1024;
    /**
     * 定义KB的计算常量
     */
    private static final int KB = 1024;

    /**
     * 格式化小数
     */
    private static final DecimalFormat DF = new DecimalFormat("0.00");

    /**
     * MultipartFile转File
     */
    public static File toFile(MultipartFile multipartFile){
        // 获取文件名
        String fileName = multipartFile.getOriginalFilename();
        // 获取文件后缀
        String prefix="."+getExtensionName(fileName);
        File file = null;
        try {
            // 用uuid作为文件名,防止生成的临时文件重复
            file = File.createTempFile(IdUtil.simpleUUID(), prefix);
            // MultipartFile to File
            multipartFile.transferTo(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 获取文件扩展名,不带 .
     */
    public static String getExtensionName(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot >-1) && (dot < (filename.length() - 1))) {
                return filename.substring(dot + 1);
            }
        }
        return filename;
    }

    /**
     * Java文件操作 获取不带扩展名的文件名
     */
    public static String getFileNameNoEx(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot >-1) && (dot < (filename.length()))) {
                return filename.substring(0, dot);
            }
        }
        return filename;
    }

    /**
     * 文件大小转换
     */
    public static String getSize(long size){
        String resultSize;
        if (size / GB >= 1) {
            //如果当前Byte的值大于等于1GB
            resultSize = DF.format(size / (float) GB) + "GB   ";
        } else if (size / MB >= 1) {
            //如果当前Byte的值大于等于1MB
            resultSize = DF.format(size / (float) MB) + "MB   ";
        } else if (size / KB >= 1) {
            //如果当前Byte的值大于等于1KB
            resultSize = DF.format(size / (float) KB) + "KB   ";
        } else {
            resultSize = size + "B   ";
        }
        return resultSize;
    }

    /**
     * inputStream 转 File
     */
    public static File inputStreamToFile(InputStream ins, String name) throws Exception{
        File file = new File(System.getProperty("java.io.tmpdir") + File.separator + name);
        if (file.exists()) {
            return file;
        }
        OutputStream os = new FileOutputStream(file);
        int bytesRead;
        int len = 8192;
        byte[] buffer = new byte[len];
        while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.close();
        ins.close();
        return file;
    }

    /**
     * 将文件名解析成文件的上传路径
     */
    public static File upload(MultipartFile file, String filePath) {
        //String name = getFileNameNoEx(file.getOriginalFilename());
        String suffix = getExtensionName(file.getOriginalFilename());
        StringBuffer nowStr = fileRename();
        try {
            String fileName = nowStr + "." + suffix;
            String path = filePath + fileName;
            // getCanonicalFile 可解析正确各种路径
            File dest = new File(path).getCanonicalFile();
            // 检测是否存在目录
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            // 文件写入
            file.transferTo(dest);
            return dest;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String fileToBase64(File file) throws Exception {
        FileInputStream inputFile = new FileInputStream(file);
        String base64;
        byte[] buffer = new byte[(int)file.length()];
        inputFile.read(buffer);
        inputFile.close();
        base64=Base64.encode(buffer);
        return base64.replaceAll("[\\s*\t\n\r]", "");
    }

    /**
     * 导出excel
     */
    public static void downloadExcel(List<Map<String, Object>> list, HttpServletResponse response) throws IOException {
        String tempPath =System.getProperty("java.io.tmpdir") + IdUtil.fastSimpleUUID() + ".xlsx";
        File file = new File(tempPath);
        BigExcelWriter writer= ExcelUtil.getBigWriter(file);
        // 一次性写出内容,使用默认样式,强制输出标题
        writer.write(list, true);
        //response为HttpServletResponse对象
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
        response.setHeader("Content-Disposition","attachment;filename=file.xlsx");
        ServletOutputStream out=response.getOutputStream();
        // 终止后删除临时文件
        file.deleteOnExit();
        writer.flush(out, true);
        //此处记得关闭输出Servlet流
        IoUtil.close(out);
    }

    public static String getFileType(String type) {
        String documents = "txt doc pdf ppt pps xlsx xls docx";
        String music = "mp3 wav wma mpa ram ra aac aif m4a";
        String video = "avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg";
        String image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg";
        if(image.contains(type)){
            return "pic";
        } else if(documents.contains(type)){
            return "txt";
        } else if(music.contains(type)){
            return "music";
        } else if(video.contains(type)){
            return "vedio";
        } else {
            return "other";
        }
    }


    public static void checkSize(long maxSize, long size) {
        // 1M
        int len = 1024 * 1024;
        if(size > (maxSize * len)){
       		System.out.println("文件超出规定大小");
        }
    }

    /**
     * 判断两个文件是否相同
     */
    public static boolean check(File file1, File file2) {
        String img1Md5 = getMd5(file1);
        String img2Md5 = getMd5(file2);
        return img1Md5.equals(img2Md5);
    }

    /**
     * 判断两个文件是否相同
     */
    public static boolean check(String file1Md5, String file2Md5) {
        return file1Md5.equals(file2Md5);
    }

    private static byte[] getByte(File file) {
        // 得到文件长度
        byte[] b = new byte[(int) file.length()];
        try {
            InputStream in = new FileInputStream(file);
            try {
                in.read(b);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }
        return b;
    }

    private static String getMd5(byte[] bytes) {
        // 16进制字符
        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(bytes);
            byte[] md = mdTemp.digest();
            int j = md.length;
            char[] str = new char[j * 2];
            int k = 0;
            // 移位 输出字符串
            for (byte byte0 : md) {
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 下载文件
     * @param request /
     * @param response /
     * @param file /
     */
    public static void downloadFile(HttpServletRequest request, HttpServletResponse response, File file, boolean deleteOnExit){
        response.setCharacterEncoding(request.getCharacterEncoding());
        response.setContentType("application/octet-stream");
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            response.setHeader("Content-Disposition", "attachment; filename="+file.getName());
            IOUtils.copy(fis,response.getOutputStream());
            response.flushBuffer();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                    if(deleteOnExit){
                        file.deleteOnExit();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static String getMd5(File file) {
        return getMd5(getByte(file));
    }

    /**
     * 读取json文件,返回json串
     * @param fileName
     * @return
     */
    public static String readJsonFile(String fileName) {
        String jsonStr = "";
        try {
            File jsonFile = new File(fileName);
            FileReader fileReader = new FileReader(jsonFile);

            Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
            int ch = 0;
            StringBuffer sb = new StringBuffer();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            fileReader.close();
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static BufferedImage inputImage(MultipartFile file) {
        BufferedImage srcImage = null;
        try {
            FileInputStream in = (FileInputStream) file.getInputStream();
            srcImage = javax.imageio.ImageIO.read(in);
        } catch (IOException e) {
            System.out.println("读取图片文件出错!" + e.getMessage());
        }
        return srcImage;
    }
    /**
     * 自动调节精度(经验数值)
     *
     * @param size 源图片大小
     * @return 图片压缩质量比
     */
    public static float getAccuracy(long size) {
        float accuracy;
        if (size < 400) {
            accuracy = 0.85f;
        } else if (size < 900) {
            accuracy = 0.75f;
        } else if (size < 2047) {
            accuracy = 0.6f;
        } else if (size < 3275) {
            accuracy = 0.44f;
        } else {
            accuracy = 0.4f;
        }
        return accuracy;
    }

    /**
     * 上传文件重命名
     * @return 新的文件名
     */
    public static StringBuffer fileRename() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String time = sdf.format(new Date());
        StringBuffer buf = new StringBuffer(time);
        Random r = new Random();
        //循环取得三个不大于10的随机整数
        for (int x = 0; x < 3; x++) {
            buf.append(r.nextInt(10));
        }
        return buf;
    }

    /**
     * 对中文字符进行UTF-8编码
     * @param source 要转义的字符串
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String transformStyle(String source) throws UnsupportedEncodingException
    {
        char[] arr = source.toCharArray();
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < arr.length; i++)
        {
            char temp = arr[i];
            if(isChinese(temp))
            {
                sb.append(URLEncoder.encode("" + temp, "UTF-8"));
                continue;
            }
            sb.append(arr[i]);
        }
        return sb.toString();
    }

    /**
     * 判断是不是中文字符
     * @param c
     * @return
     */
    public static boolean isChinese(char c)
    {

        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);

        if(ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS

                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS

                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A

                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION

                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION

                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS)
        {

            return true;

        }

        return false;

    }

    /**
     * 判断指定的文件或文件夹删除是否成功
     * @param FileName 文件或文件夹的路径
     * @return true or false 成功返回true,失败返回false
     */
    public static boolean deleteAnyone(String FileName){
        File file = new File(FileName);//根据指定的文件名创建File对象
        if ( !file.exists() ){  //要删除的文件不存在
            System.out.println("文件"+FileName+"不存在,删除失败!" );
            return false;
        }else{ //要删除的文件存在
            if ( file.isFile() ){ //如果目标文件是文件
                return deleteFile(FileName);
            }else{  //如果目标文件是目录
                return deleteDir(FileName);
            }
        }
    }

    /**
     * 判断指定的文件删除是否成功
     * @param fileName 文件路径
     * @return true or false 成功返回true,失败返回false
     */
    public static boolean deleteFile(String fileName){
        File file = new File(fileName);//根据指定的文件名创建File对象
        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 dirName is 目录路径
     * @return true or false 成功返回true,失败返回false
     */
    public static boolean deleteDir(String dirName){
        if (dirName.endsWith(File.separator) )//dirName不以分隔符结尾则自动添加分隔符
            dirName = dirName + File.separator;
        File file = new File(dirName);//根据指定的文件名创建File对象
        if ( !file.exists() || ( !file.isDirectory() ) ){ //目录不存在或者
            System.out.println("目录删除失败"+dirName+"目录不存在!" );
            return false;
        }
        File[] fileArrays = file.listFiles();//列出源文件下所有文件,包括子目录
        for ( int i = 0 ; i < fileArrays.length ; i++ ){//将源文件下的所有文件逐个删除
            deleteAnyone(fileArrays[i].getAbsolutePath());
        }
        if ( file.delete() ){
            //删除当前目录
            System.out.println("目录"+dirName+"删除成功!" );
        }
        return true;

    }
}

你可能感兴趣的:(java,servlet,spring,zip下载)