整个思路是这样的:

1.查询数据库中的文件流放到datatable中
2.循环datatable将文件流一个个生成文件,放到对应的文件夹中,
3.下载某个文件夹下的所有文件
a.循环这个文件夹下的所有文件,调用zip()方法压缩到zipSteam中
b.将zipStream流保存为一个.zip文件
4.返回给前端压缩成功
5.前端用window.open(“压缩文件.zip”)下载压缩文件

这个程序是几年前写的,比较绕,不是个最佳方法,应该有更好的。

优化思路:

1.将数据库中查询出来的文件流直接调用zip()方法压缩到zipSteam,然后将zipSteam压缩文件流直接输出给前端,这样优化后才是最好的做法,待优化

 private void DownLaodZip2017(HttpContext context)
        {
            

                ZipFloClass zc = new ZipFloClass();
                
                string res_str = context.Request.Form["list"].ToString();
                //string res_str = "2,4,6";
                string[] data = res_str.Split(',');
                OunamesFilesToFiles(data);
                for (int i = 0; i < data.Length; i++)
                {
                    string doc_path = context.Server.MapPath("~/ProjectMgt/Doc2017") + "\\" + data[i].Trim() + "\\";
                    string zip_path = context.Server.MapPath("~/ProjectMgt/Doc2017/zip/zip") + "\\" + data[i].Trim() + ".zip";
                    if (Directory.Exists(doc_path))
                    {
                        zc.ZipFile(doc_path, zip_path);
                    }

                }
                string zip_Path = context.Server.MapPath("~/ProjectMgt/Doc2017/zip/zip");
                string zip_Name = context.Server.MapPath("~/ProjectMgt/Doc2017/zip/打包数据.zip");
                if (File.Exists(zip_Name))
                {
                    File.Delete(zip_Name);
                }

                zc.ZipFile(zip_Path, zip_Name);


                string[] paths = Directory.GetFiles(zip_Path);
                for (int n = 0; n < paths.Length; n++)
                {
                    File.Delete(paths[n]);
                }
                context.Response.Write("{success:true, files:'生成文件成功'}");

                
            
        }
        
        private void DownLaodZip(HttpContext context)
        {
            if (context.Request["type"] != null)
            {

                ZipFloClass zc = new ZipFloClass();
                string type = context.Request["type"].ToString();
                switch (type)
                {
                    case "rc": type = "常规"; break;
                    case "ic": type = "工控"; break;
                    case "lp": type = "等保"; break;
                }
                string res_str = context.Request.Form["list"].ToString();
                //string res_str = "2,4,6";
                string[] data = res_str.Split(',');
                for (int i = 0; i < data.Length; i++)
                {
                    string doc_path = context.Server.MapPath("~/ProjectMgt/Doc") + "\\" + data[i].Trim() + "\\" + type;
                    string zip_path = context.Server.MapPath("~/ProjectMgt/Doc/zip/zip") + "\\" + data[i].Trim() + ".zip";
                    if (Directory.Exists(doc_path))
                    {
                        zc.ZipFile(doc_path, zip_path);
                    }

                }
                string zip_Path = context.Server.MapPath("~/ProjectMgt/Doc/zip/zip");
                string zip_Name = context.Server.MapPath("~/ProjectMgt/Doc/zip/打包数据.zip");
                if (File.Exists(zip_Name))
                {
                    File.Delete(zip_Name);
                }

                zc.ZipFile(zip_Path, zip_Name);


                string[] paths = Directory.GetFiles(zip_Path);
                for (int n = 0; n < paths.Length; n++)
                {
                    File.Delete(paths[n]);
                }
                context.Response.Write("{success:true, files:'生成文件成功'}");

                #region
                //List<string> downloadurl = new List<string>();
                //ExtFacade ef = new ExtFacade();
                //for (int i = 0; i < data.Length; i++) {
                //    string query = string.Format(@"select top 1 t.LoadUrl from 
                //    tbl_Net_SecurityCheck t
                //    where t.OUID in(
                //     select t.OUID from tbl_Base_OUInfo t where substring (OUCode,0,21)in
                //     (
                //      select m.OUCode from tbl_Base_OUInfo m
                //      where m.OUID='{0}')
                //    )
                //    and t.DocType='{1}' order by t.SubmitTime desc", data[i],type);
                //    DataTable dt = ef.GetBySQLText(query);
                //    downloadurl.Add(dt.Rows[0]["LoadUrl"].ToString());
                //}
                #endregion
            }
        }
		
		
		private void OunamesFilesToFiles(string[] OUNAMES)
        {
            for (int i = 0; i < OUNAMES.Length; i++)
            {
                var dt= GetContentByOuname(OUNAMES[i]);
                DataTableToFiles(dt, OUNAMES[i]);
            }
        }
        private void DataTableToFiles(DataTable dt,string OUName)
        {
            string LoadUrl = HttpContext.Current.Server.MapPath("~/ProjectMgt/Doc2017") + "\\" + OUName;
            if (Directory.Exists(LoadUrl))
            {
                Directory.Delete(LoadUrl, true);
            }
            Directory.CreateDirectory(LoadUrl);
            for (int i=0;i<dt.Rows.Count;i++)
            {
                ToFile(dt.Rows[i]["OUName"].ToString(), (byte[])dt.Rows[i]["Content"], dt.Rows[i]["DownLoadFileName"].ToString());
            }
        }
        private void ToFile(string OUName, byte[] Content, string DownLoadFileName)
        {
            string LoadUrl = HttpContext.Current.Server.MapPath("~/ProjectMgt/Doc2017") + "\\" + OUName + "\\"+ DownLoadFileName;
            
            MemoryStream m = new MemoryStream(Content);
            FileStream fs = new FileStream(LoadUrl, FileMode.OpenOrCreate);
            m.WriteTo(fs);
            m.Close();
            fs.Close();
            m = null;
            fs = null;

        }
		
		
		/// <summary>
    /// 压缩文件类
    /// </summary>
    public class ZipFloClass
    {
        /// <summary>
        /// 压缩方法
        /// </summary>
        /// <param name="strFile"></param>
        /// <param name="strZip"></param>
        public void ZipFile(string strFile, string strZip)
        {
            if (strFile[strFile.Length - 1] != Path.DirectorySeparatorChar)
                strFile += Path.DirectorySeparatorChar;
            ZipOutputStream s = new ZipOutputStream(File.Create(strZip));
            s.SetLevel(6); // 0 - store only to 9 - means best compression
            zip(strFile, s, strFile);
            s.Finish();
            s.Close();
        }
        /// <summary>
        /// 压缩
        /// </summary>
        /// <param name="strFile"></param>
        /// <param name="s"></param>
        /// <param name="staticFile"></param>
        private void zip(string strFile, ZipOutputStream s, string staticFile)
        {
            if (strFile[strFile.Length - 1] != Path.DirectorySeparatorChar) strFile += Path.DirectorySeparatorChar;
            Crc32 crc = new Crc32();
            string[] filenames = Directory.GetFileSystemEntries(strFile);
            foreach (string file in filenames)
            {

                if (Directory.Exists(file))
                {
                    zip(file, s, staticFile);
                }

                else // 否则直接压缩文件
                {
                    //打开压缩文件
                    FileStream fs = File.OpenRead(file);

                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, buffer.Length);
                    string tempfile = file.Substring(staticFile.LastIndexOf("\\") + 1);
                    ZipEntry entry = new ZipEntry(tempfile);

                    entry.DateTime = DateTime.Now;
                    entry.Size = fs.Length;
                    fs.Close();
                    crc.Reset();
                    crc.Update(buffer);
                    entry.Crc = crc.Value;
                    s.PutNextEntry(entry);

                    s.Write(buffer, 0, buffer.Length);
                }
            }
        }

    }
	
	
	private void DownLoad2017(HttpContext context)
        {
            string zip_Path = context.Server.MapPath("~/ProjectMgt/Doc2017/zip/zip");
            string zip_Name = context.Server.MapPath("~/ProjectMgt/Doc2017/zip/打包数据.zip");

            //zip_Name = context.Server.MapPath("~/ProjectMgt/Doc/安徽销售公司/常规/2016年网络安全检查-常规安全-准备阶段-安徽销售公司.xls");
            FileStream fs = new FileStream(zip_Name, FileMode.Open);
            byte[] bytes = new byte[(int)fs.Length];
            fs.Read(bytes, 0, bytes.Length);
            fs.Close();
            context.Response.ContentType = "application/octet-stream";
            //通知浏览器下载文件而不是打开 
            context.Response.AddHeader("Content-Disposition", "attachment;  filename=" + HttpUtility.UrlEncode("打包数据.zip", System.Text.Encoding.UTF8));
            context.Response.BinaryWrite(bytes);
            context.Response.Flush();
            File.Delete(zip_Name);
            context.Response.End();
        }
		
		
js代码: Ext.Ajax.request({ url: 'Ashx/NetCheckViewAll.ashx?flag=DownLoad2017', method: 'post', async:false, params: { list: Ids }, success: function (response, opts) { //var url = 'Ashx/NetCheckViewAll.ashx?flag=downzip'; //window.open(url); Ext.Msg.confirm("下载", "确定要下载选中项吗?", function (button) { if (button == "yes") { var url = 'Ashx/NetCheckViewAll.ashx?flag=downzip2017'; window.open(url); } }); } //failure: function (response, opts) { // console.log('server-side failure with status code ' + response.status); //} });