.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;
}
             }

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

 

posted @ 2019-09-23 10:56  zty_Love  阅读(1969)  评论(0编辑  收藏  举报