• .net WebApi 批量文件进行压缩zip以二进制流传输至前端(Vue)下载


    前言:最近接了个项目,需要进行将服务端生成的文件进行打包压缩供前端下载,百度查了下资料,决定采用SharpZipLib C#开园的压缩解压库进行服务器文件压缩,在实现过程,郁闷的是前端接收下载下来的压缩包,解压的时候一直报“文件损坏或文件格式不正确”,

    在此记录下这过程,避免以后采坑。

    接口端压缩方法(以二进制文件流传输至Http):

            /// <summary>
            /// 批量下载PDF word 文件压缩
            /// </summary>
            /// <param name="downloadZipReportModel"></param>
            /// <returns></returns>
            [HttpGet, HttpPost]
            public void DownLoadZipByReporlFilename(DownloadZipReportModel downloadZipReportModel)
            {
                MemoryStream ms = new MemoryStream();//创建内存存储
                byte[] buffer = null;
                using (ZipFile file = ZipFile.Create(ms))
                {
                    file.BeginUpdate();
                    file.NameTransform = new MyNameTransfom();
                    foreach (var r in downloadZipReportModel.ReportPdfAndWordModel)//downloadZipReportModel 是报告数据对象 里面保存着相关需要下载的文件路径
                    {
                        file.Add(HttpContext.Current.Server.MapPath($"~/" + r.WordUrl));
                        file.Add(HttpContext.Current.Server.MapPath($"~/" + r.PdfUrl));
    
                    }
                    file.CommitUpdate();
                    buffer = new byte[ms.Length];
                    ms.Position = 0;
                    ms.Read(buffer, 0, buffer.Length);
                    ms.Flush();
                    ms.Close();
                }
                HttpContext.Current.Response.ContentType = "application/octet-stream;charset=GBK";
                HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=download.zip");
                HttpContext.Current.Response.BinaryWrite(buffer);
                HttpContext.Current.Response.Flush();
                HttpContext.Current.Response.End();
    
            }
    public class MyNameTransfom : ICSharpCode.SharpZipLib.Core.INameTransform
            {
    
    
                #region INameTransform 成员
    
    
                public string TransformDirectory(string name)
                {
                    return null;
                }
    
    
                public string TransformFile(string name)
                {
                    return Path.GetFileName(name);
                }
    
    
                #endregion
            }

    Vue 前端接收后端二进制文件流:

                async downLoadZipByReportFilename(postData){//下载报告,postData 保存的是需要下载的文件路径对象
                    
                    let that = this
                    var ajax = new XMLHttpRequest()
                    var strategyDownloadUrl=process.env.BASE_URL+"api/Report/DownLoadZipByReporlFilename";
                    ajax.responseType = 'blob'
                    ajax.open("post",strategyDownloadUrl,true)
                    ajax.setRequestHeader('Authorization','Bearer ' + this.$store.state.token)
                    ajax.setRequestHeader("Content-Type","application/json; charset=utf-8")
                 
                    ajax.onreadystatechange = function(){
                        if(this.readyState == 4) {
                        if(this.status == 200) {
                            //console.log(this.response) // should be a blob
                            if(this.response.type == "application/octet-stream"){
                            that.downloadHandler(this.response,'download.zip')
                            }else{
                             that.$message('您要下载的资源已被删除!','' , 'error')
                            }
                        } else if(this.responseText != "") {
                        }
                        } else if(this.readyState == 2) {
                        if(this.status == 200) {
                            this.responseType = "blob"
                        } else {
                            this.responseType = "text"
                        }
                        }
                    };
                    ajax.send(JSON.stringify(postData));
                },
    
    
                downloadHandler(content, filename) {//下载处理 
                    var eleLink = document.createElement('a')
                    eleLink.download = filename
                    eleLink.style.display = 'none'
                    // 字符内容转变成blob地址
                    var blob = new Blob([content],{type: "application/octet-stream"})
                    eleLink.href = URL.createObjectURL(blob)
                    // 触发点击
                    document.body.appendChild(eleLink)
                    eleLink.click()
                    // 然后移除
                    document.body.removeChild(eleLink)
                }

    之前前端接收二进制文件流解压报错代码:

                 async downLoadZipByReporlFilename(postData){
                    var resp=await downLoadZipByReporlFilename(postData);//后端接口
                    if(resp){
                        console.log(resp);
                         let blob = new Blob([resp], {type: "application/octet-stream"}); 
    let url
    = window.URL.createObjectURL(blob);
    window.location.href
    = url;
    }
                 }

    解压报错原因:接口请求文件媒体格式没有声明成功

  • 相关阅读:
    论文阅记 YOLOv4: Optimal Speed and Accuracy of Object Detection
    【项目实战】yolov3-tiny人脸数据模型训练
    面试题54. 二叉搜索树的第k大节点
    102. 二叉树的层序遍历
    107. 二叉树的层次遍历 II
    连续子数组的最大和
    172. 阶乘后的零
    26 进制
    405. 数字转换为十六进制数
    504. 七进制数
  • 原文地址:https://www.cnblogs.com/zty-Love/p/11571174.html
Copyright © 2020-2023  润新知