当前位置: 首页 > article >正文

前后端传值响应下载文件压缩包

前端代码:

// 多分文件压缩成一个压缩包下载
BatchDownloadFile() {
    debugger;
    let ids = this.frameContext.appContext.frameContextManager.getFrameContextById("data-grid-component").viewModel.uiState['ids'] as string[];
    if (ids.length == 0) {
        this.msgService.error("请选择需要下载的文件!");
        return;
    }
    // 将选中的文件对应的目录的id拼接成一个长字段串传给后端
    let idss = "";
    for (let i = 0; i < ids.length; i++) {
        idss = idss + ids[i] + ",";
    }

    debugger;
    const repository = this.frameContext.repository as BefRepository<any>;
    const requestInfo = repository.restService.buildRequestInfo();
    //eapi上增加的BE自定义动作对应的URI的末尾的值
    const actionUri = '/api/wxgl/wxtzgl/v1.0/wxtzxz080901_frm/service/exportfiles';
    // const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
    const body = {
        requestInfo: requestInfo,
        id: idss   // 将选中的数据的id传到后端,用于下载这几条数据对应的改单
    }
    this.formNotifyService.success("正在下载请稍等!");
    this.httpClient.put(actionUri, body, { responseType: 'blob', observe: 'response' }).subscribe(
        data => {
            const link = document.createElement('a');
            const blob = new Blob([data.body], { type: 'application/force-download;charset=UTF-8' })   // 压缩包zip格式
            const url = window.URL.createObjectURL(blob);
            link.setAttribute("href", url);
            link.setAttribute("download", '文件压缩包下载.zip');
            link.style.display = 'none';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            window.URL.revokeObjectURL(url);
        }
    )
    // window.location.href = "http://服务器IP:8090/wx/wxglwxtzxz080901?ids=" + id;

}



// 下载Excel
ExportChangeDetailList() {
    debugger;
    this.loadingService.show();
    const uri = new Uri(this.uriService.extendUri(this.apiUrl) + '/service/downloadchangedetail', {});
    const url = uri.toString();
    const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
    const option = {
        responseType: 'blob' as any,
        headers: headers,
        observe: 'response' as any
    }

    this.httpClient.put(url, "", option).subscribe((response: any) => {
        this.loadingService.hide();
        const contentType = "application/octet-stream;charset=utf-8";
        let fileName = response.headers.get("Content-Disposition").split(";")[1].split("filename=")[1];
        fileName = decodeURI(fileName);
        if ('msSave0rOpenBlob' in navigator) {//IE导出
            const blob = new Blob([response.body], { type: contentType });
            window.navigator.msSaveBlob(blob, fileName);
        } else {
            this.downloadFile(response, fileName, contentType);
        }
    },
        error => {
            this.loadingService.hide();
            this.msgService.info("下载失败。");
            return EMPTY;
        }
    );
}

//下载附件
downloadFile(response, fileName, contentType) {
    const blob = new Blob([response.body], { type: contentType });
    const url = window.URL.createObjectURL(blob);
    // 打开新窗口方式进行下载
    // window.open(url); 
    // 以动态创建a标签进行下载
    const a = document.createElement('a');
    a.href = url;
    a.download = fileName;
    a.click();
    window.URL.revokeObjectURL(url);
}

后端下载文件并用流响应的代码:

public class ExportFilesVOAction extends AbstractFSAction<String> {

	private String id;
	public ExportFilesVOAction(String id) {
		this.id = id;
	}
	private static final RestTemplate template = new RestTemplate();
	@Override
	public void execute() {
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
		String projectPath = null;
		try {
			projectPath = new File("..").getCanonicalPath();
		} catch (IOException e) {
			e.printStackTrace();
		}
		String fileName = "文件压缩包下载.zip";
		String rootFloder = projectPath + "\\" + fileName;
		try {
			// 调用内部服务 生成Excel
            String url = "http://服务器IP:8090/wx/wxglwxtzxz080901?ids=" + this.id;
			ResponseEntity<Resource> entity = template.getForEntity(url, Resource.class);
			InputStream stream = entity.getBody().getInputStream();
			// 响应前端
			ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
			HttpServletResponse response = servletRequestAttributes.getResponse();
			try {
				// 清空response
				response.reset();
				// 以流的形式下载文件。
				InputStream fis = new BufferedInputStream(stream);
				byte[] buffer = new byte[fis.available()];
				fis.read(buffer);
				fis.close();
				fileName = URLEncoder.encode(fileName, "UTF-8");
				response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes()));
				OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
				response.setContentType("application/force-download");
				response.setCharacterEncoding("UTF-8");
				outputStream.write(buffer);
				outputStream.flush();
				outputStream.close();
				setResult("ok");
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			File file = new File(rootFloder);
			if (file.exists()) {
				file.delete();
			}
		}
	}
}

服务器上下载文件:

@RestController
@RequestMapping("/wxglwxtzxz080901")
@Slf4j
@CrossOrigin
public class Wxglwxtzxz080901Controller {

    private Wxglwxtzxz080901ServiceImpl wxglwxtzxz080901Service;

    @Autowired
    public void setWxglwxtzxz080901Service(Wxglwxtzxz080901ServiceImpl wxglwxtzxz080901Service) {
        this.wxglwxtzxz080901Service = wxglwxtzxz080901Service;
    }

    @Value("${wxfile.path}")
    private String basePath;

    private static final DateTimeFormatter DF = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter DF_DOWN = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH时mm分ss秒");
    private SnowFlakeUtil snowFlakeUtil;

    @Autowired
    public void setSnowFlakeUtil(SnowFlakeUtil snowFlakeUtil) {
        this.snowFlakeUtil = snowFlakeUtil;
    }

    @GetMapping
    @ResponseBody
    public void downloadFile(@RequestParam("ids") String ids, HttpServletResponse response) {
        if (ObjectUtils.isEmpty(ids)) {
            return;
        }
        String pathTime = DF_DOWN.format(LocalDateTime.now());
        String targetPath = basePath + pathTime;
        File targetFile = new File(targetPath);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        final String[] idList = ids.split(",");
        final List<Wxglwxtzxz080901> wxglwxtzxz080901s = wxglwxtzxz080901Service.listByIds(Arrays.asList(idList));
        File zipFile = null;
        try {
            copyTargetFiles(targetPath, wxglwxtzxz080901s);
            // 压缩文件
            zipFile = new File(targetPath + ".zip");
            if (zipFile.exists()) {
                zipFile.delete();
            }
            System.out.println(targetFile);
            ZipUtils.toZip(targetFile, zipFile.getAbsolutePath(), true);
            // 将下载成功的图纸属性设置为已下载
            wxglwxtzxz080901s.forEach((bean) -> {
                bean.setSfyxz("是");
                bean.setXzrq(DF.format(LocalDateTime.now()));
                wxglwxtzxz080901Service.updateById(bean);
            });
            // 将文件传给前端
            FileUtils.downFile(zipFile.getAbsolutePath(), "文件压缩包下载.zip", response);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (zipFile != null && zipFile.exists()) {
                zipFile.delete();
            }
            if (targetFile != null && targetFile.exists()) {
                FileUtils.delDirs(targetFile);
                targetFile.delete();
            }
        }
    }

    private void copyTargetFiles(String targetPath, List<Wxglwxtzxz080901> wxglwxtzxz080901s) throws IOException {
        for (Wxglwxtzxz080901 wxglwxtzxz080901 : wxglwxtzxz080901s) {

            // 将文件拷贝至统一路径
            final String srcPath = basePath + wxglwxtzxz080901.getFjlj();
            // 路径层级 工程号/专业
            String filePath = targetPath + "/" + wxglwxtzxz080901.getGch() + "/" + wxglwxtzxz080901.getSjzy();
            File targetWxFile = new File(filePath);
            if (!targetWxFile.exists()) {
                targetWxFile.mkdirs();
            }
            // 拷贝至一个文件夹下 并改名图纸文件夹名称格式
            String folderName = "";
            if (srcPath.contains("DWG")) {
                // DWG表示为初版图纸
                folderName = "【初版图纸】" + wxglwxtzxz080901.getGch() + "_图号:" + wxglwxtzxz080901.getTh() + "_图名:" + wxglwxtzxz080901.getTzmc();
            } else {
                folderName = "【变更图纸】" + wxglwxtzxz080901.getGch() + "_改单号:" + wxglwxtzxz080901.getGdh() + "_图号:" + wxglwxtzxz080901.getTh() + "_图名:" + wxglwxtzxz080901.getTzmc();
            }
            FileUtils.copyFolder(new File(srcPath), targetWxFile, folderName);
        }
    }

    @GetMapping("/changedetail")
    public String downloadChangeTail(@RequestParam("path") String path, HttpServletResponse response) {
        QueryWrapper<Wxglwxtzxz080901> wrapper = new QueryWrapper<>();
        wrapper.isNotNull("GDH");
        String fileName = "D:\\wxFiles\\" + path;
        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
        EasyExcel.write(fileName, Wxglwxtzxz080901.class).sheet("改单清单").doWrite(wxglwxtzxz080901Service.list(wrapper));

        try {
            FileInputStream inputStream = new FileInputStream(fileName);
            byte[] data = new byte[inputStream.available()];
            inputStream.read(data);
            response.setContentType("video/avi");
            path = URLEncoder.encode(path, "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + path + "\"");
            response.setContentLength(data.length);
            response.setHeader("Content-Range", "" + Integer.valueOf(data.length - 1));
            response.setHeader("Accept-Ranges", "bytes");
            OutputStream os = response.getOutputStream();

            os.write(data);
            //先声明的流后关掉!
            os.flush();
            os.close();
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            File file = new File(fileName);
            if (file.exists()) {
                file.delete();
            }
        }
        return path;
    }
}













public class ZipUtils {
    private static final int  BUFFER_SIZE = 2 * 1024;
    /**
     * 压缩成ZIP 方法1
     * @param sourceFile 压缩文件夹
     * @param zipFilePathName    压缩文件输出地址与名字
     * @param KeepDirStructure  是否保留原来的目录结构,true:保留目录结构;
     *                          false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     * @throws RuntimeException 压缩失败会抛出运行时异常
     */
    public static void toZip( File sourceFile, String zipFilePathName, boolean KeepDirStructure)
            throws RuntimeException, FileNotFoundException {

        long start = System.currentTimeMillis();
        File file = new File(zipFilePathName);
        if (!file.exists()){
            file.getParentFile().mkdirs();
        }
        FileOutputStream out = new FileOutputStream(zipFilePathName);
        ZipOutputStream zos = null ;
        try {
            zos = new ZipOutputStream(out);
            compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure);
            long end = System.currentTimeMillis();
            System.out.println("压缩完成,耗时:" + (end - start) +" ms");
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils",e);
        }finally{
            if(zos != null){
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * 压缩成ZIP 方法2
     * @param srcFiles 需要压缩的文件列表
     * @param zipFilePathName           压缩文件输出地址与名字
     * @throws RuntimeException 压缩失败会抛出运行时异常
     */
    public static void toZip(List<File> srcFiles , String zipFilePathName) throws RuntimeException, FileNotFoundException {
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null ;
        File file = new File(zipFilePathName);
        if (!file.exists()){
            file.getParentFile().mkdirs();
        }
        FileOutputStream out = new FileOutputStream(zipFilePathName);
        try {
            zos = new ZipOutputStream(out);
            for (File srcFile : srcFiles) {
                byte[] buf = new byte[BUFFER_SIZE];
                zos.putNextEntry(new ZipEntry(srcFile.getName()));
                int len;
                FileInputStream in = new FileInputStream(srcFile);
                while ((len = in.read(buf)) != -1){
                    zos.write(buf, 0, len);
                }
                zos.closeEntry();
                in.close();
            }
            long end = System.currentTimeMillis();
            System.out.println("压缩完成,耗时:" + (end - start) +" ms");
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils",e);
        }finally{
            if(zos != null){
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 递归压缩方法
     * @param sourceFile 源文件
     * @param zos        zip输出流
     * @param name       压缩后的名称
     * @param KeepDirStructure  是否保留原来的目录结构,true:保留目录结构;
     *                          false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     * @throws Exception
     */
    private static void compress(File sourceFile, ZipOutputStream zos, String name,
                                 boolean KeepDirStructure) throws Exception{
        byte[] buf = new byte[BUFFER_SIZE];
        if(sourceFile.isFile()){
            // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
            zos.putNextEntry(new ZipEntry(name));
            // copy文件到zip输出流中
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while ((len = in.read(buf)) != -1){
                zos.write(buf, 0, len);
            }

            // Complete the entry
            zos.closeEntry();
            in.close();
        } else {
            File[] listFiles = sourceFile.listFiles();
            if(listFiles == null || listFiles.length == 0){
                // 需要保留原来的文件结构时,需要对空文件夹进行处理
                if(KeepDirStructure){
                    // 空文件夹的处理
                    zos.putNextEntry(new ZipEntry(name + "/"));
                    // 没有文件,不需要文件的copy
                    zos.closeEntry();
                }
            }else {
                for (File file : listFiles) {
                    // 判断是否需要保留原来的文件结构
                    if (KeepDirStructure) {
                        // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
                        // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
                        compress(file, zos, name + "/" + file.getName(), true);
                    } else {
                        compress(file, zos, file.getName(), false);
                    }

                }
            }
        }
    }
}



@Slf4j
public class FileUtils {

    /**
     * 复制文件
     *
     * @param srcFile
     * @param destFile
     * @throws IOException
     */
    public static void copyFile(File srcFile, File destFile) throws IOException {
        // 创建字节缓冲输入流对象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
        // 创建字节缓冲输出流对象
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
        //一次读入一个字节数组的数据
        byte[] bys = new byte[1024];
        int len;
        while ((len = bis.read(bys)) != -1) {
            bos.write(bys, 0, len);
        }
        //释放资源
        bos.close();
        bis.close();
    }

    /**
     * 复制文件夹
     *
     * @param srcFile
     * @param destFile
     * @throws IOException
     */
    public static void copyFolder(File srcFile, File destFile, String folderName) throws IOException {
        //如果srcFile为目录,首次调用即是判断是否为目录
        if (srcFile.isDirectory()) {
            // 获取目录名,首次调用时目录名为
            String srcFileName;
            if (ObjectUtils.isEmpty(folderName)) {
                srcFileName = srcFile.getName();
            } else {
                srcFileName = folderName;
            }
            // 在destFile下新建一个名为srcFile的目录,首次调用时即在code2目录下创建test目录
            File newFolder = new File(destFile, srcFileName);
            // 如果目录不存在,则新建目录
            if (!newFolder.exists()) {
                newFolder.mkdirs();
            }
            // 将srcFile目录下的文件或目录存入文件数组中
            File[] listFiles = srcFile.listFiles();
            // 遍历test目录下所有的文件
            for (File file : listFiles) {
                // 利用递归将file作为srcFile,newFolder作为destFile调用copyFolder方法
                copyFolder(file, newFolder, null);
            }
        } else {
            String srcFileName = srcFile.getName();
            File newFile = new File(destFile, srcFileName);
            if (!newFile.exists()) {
                newFile.createNewFile();
            }
            copyFile(srcFile, newFile);
        }
    }

    /**
     * 下载文件
     *
     * @param path
     * @param fileName
     * @param response
     */
    public static void downFile(String path, String fileName, HttpServletResponse response) {
        File file = new File(path);
        response.setCharacterEncoding("utf-8");
        String downloadFileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        response.setContentType("application/force-download");
        // 设置允许跨域的Key
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment;filename=" + downloadFileName);

        if (file.exists()) {
            try {
                byte[] buffer = new byte[1024];
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
                OutputStream os = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = bis.read(buffer);
                }
                bis.close();
            } catch (Exception e) {
                e.printStackTrace();
                log.error(String.valueOf(e.getCause()));
            }
        }
    }

    public static void main(String[] args) {
        delDirs(new File("aa"));
    }

    /**
     * 递归删除
     *
     * @param file
     * @return
     */
    public static Boolean delDirs(File file) {
        //判断是否存在
        if (!file.exists()) {
            return false;
        }
        //如果是文件就直接删除
        if (file.isFile()) {
            file.delete();
        } else {
            //该方法用 File 对象形式返回目录下的所有文件
            File[] list = file.listFiles();
            for (File f : list) {
                if (f.isFile()) {
                    f.delete();
                } else {
                    delDirs(f);
                    //删除空目录
                    f.delete();
                }
            }
        }
        return true;
    }

}


http://www.kler.cn/a/569149.html

相关文章:

  • Docker入门指南:Windows下docker配置镜像源加速下载
  • 【计算机网络】TCP协议相关总结,TCP可靠性的生动讲解
  • Android Studio中gradle一栏中出现nothing to show 提示的解决方法
  • ubuntu中ollama设置记录
  • git 鼓励频繁提交commit early, commit often,用好分支,多用分支
  • 类和对象(6)——Object类、内部类
  • 大模型工程师学习日记(六):Embedding 与向量数据库
  • leetcode 598. 区间加法 II 简单
  • springboot417-基于Spring Boot的酒店后台管理系统(源码+数据库+纯前后端分离+部署讲解等)
  • ESP-WIFI-MESH组网方案,设备物联网无线交互,WiFi通信智能联动
  • c语言getchar
  • 从统计学视角看机器学习的训练与推理
  • Svelte 开发 AI 应用:高效轻量级前端框架的 AI 集成探索
  • LM studio 加载ollama的模型
  • 阿里云ECS Ubuntu PPTP VPN无法访问以太网
  • 通信原理速成笔记(信息论及编码)
  • Spring Boot 异步编程深入剖析
  • openssl下aes128算法ofb模式加解密运算实例
  • AI人工智能机器学习之聚类分析
  • 迷你世界脚本聊天接口:Chat