1. 程式人生 > >C# 匯出excel的壓縮包到瀏覽器頁面

C# 匯出excel的壓縮包到瀏覽器頁面

需求背景:TCX_1710專案產品質量匯出功能,客戶希望每個總成匯出到一個Excel表中

實現分析:客戶選擇時間段,點選匯出按鈕,預設匯出開始時間當天的資料,每個總成一個Excel,將各個Excel打包壓縮,返回壓縮包到瀏覽器頁面供客戶下載

控制器類:

     /// <summary>
        /// 匯出產品質量資訊(每個總成一個Excel)
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
public void exportExcel(string keyword) { string SNum = Request.QueryString["SNum"]; string PSCode = Request.QueryString["PSCode"]; string StartTime = Request.QueryString["StartTime"]; string EndTime = Request.QueryString["EndTime"];
//dictionary根據以上查詢條件查詢的資料字典 Dictionary<string, Dictionary<string, List<PR_Product>>> dictionary = new Dictionary<string, Dictionary<string, List<PR_Product>>>(); if (keyword == "TimeAndSnum") { dictionary = this.CreateService<IProductInfoAppServices>().GetDictionary("
TimeAndSnum", SNum, PSCode, StartTime, EndTime); } else { dictionary = this.CreateService<IProductInfoAppServices>().GetDictionary("NoTimeNoSnum", SNum, PSCode, StartTime, EndTime); } //初始化需要匯出欄位 List<ExportFieldInfo> fieldInfo10 = new List<ExportFieldInfo>(); var tableInfo10 = this.CreateService<IProductInfoAppServices>().getFiledByTable(); for (var i = 0; i < tableInfo10.Count; i++) { fieldInfo10.Add(new ExportFieldInfo() { FieldName = tableInfo10[i].filedName, DisplayName = tableInfo10[i].filedExplain, DataType = DataTypeEnum.String }); } string filePath = ConfigurationManager.AppSettings["filePath"];//配置寫在E:\MyProject\1710\02_程式碼\DoMes.Web\Configs\system.config //string filePath = "F:\\exporfolder"; FileStream stream = ExcelHelper<PR_Product>.ToExcel(filePath, dictionary, fieldInfo10, Response); Response.Flush(); Response.End();//關閉響應 stream.Close();//關閉zip流,否則無法刪除zip檔案 //獲取指定路徑下所有資料夾 //string[] folderPaths = Directory.GetDirectories(filePath); //獲取指定路徑下所有檔案 var filePaths = Directory.GetFiles(filePath); foreach (string filePath_2 in filePaths) { //刪除所有檔案 System.IO.File.Delete(filePath_2); } //foreach (string folderPath in folderPaths) //{ // Directory.Delete(folderPath, true); //} //刪除最外面的資料夾 Directory.Delete(filePath, true); }

 獲取資料的方法:

     /// <summary>
        /// 根據查詢條件獲取資料,並將資料轉換為資料字典
        /// </summary>
        /// <param name="type">查詢型別(暫時不用)</param>
        /// <param name="sNum">產品總成</param>
        /// <param name="pSCode">工位</param>
        /// <param name="startTime">開始時間</param>
        /// <param name="endTime">結束時間</param>
        /// <returns></returns>
        public Dictionary<string, Dictionary<string, List<PR_Product>>> GetDictionary(string type, string sNum, string pSCode, string startTime, string endTime)
        {
            //第一層key為日期(年/月/日),value為該日所有總成的資料字典集合
            //第二層key為總成,value為該總成所有的質量資料
            Dictionary<string, Dictionary<string, List<PR_Product>>> dictionary = new Dictionary<string, Dictionary<string, List<PR_Product>>>();
            Expression<Func<PR_Product, bool>> exp = (a => 1 == 1);
            if (!string.IsNullOrEmpty(pSCode))
            {
                exp = exp.And(a => a.PSCode == pSCode);
            }
            if (!string.IsNullOrEmpty(startTime))
            {
                DateTime ctStart = Convert.ToDateTime(startTime);
                exp = exp.And(a => a.CreationTime >= ctStart);
            }
            if (!string.IsNullOrEmpty(endTime))
            {
                DateTime ctEnd = Convert.ToDateTime(endTime);
                exp = exp.And(a => a.CreationTime < ctEnd.AddDays(1));
            }
            if (!string.IsNullOrEmpty(sNum))
            {
                exp = exp.And(a => a.SNum.Contains(sNum));
            }
            //根據查詢條件獲得的產品質量資料
            List<PR_Product> product = this.DbContext.Query<PR_Product>().Where(exp).OrderBy(a => a.SNum).ThenBy(it => it.PSCode).ToList();
            //產品總成不為空則只有一個總成
            if (!string.IsNullOrEmpty(sNum))
            {
                Dictionary<string, List<PR_Product>> dictionary2 = new Dictionary<string, List<PR_Product>>();
                dictionary2.Add(sNum, product);
                dictionary.Add(startTime, dictionary2);
            }
            else//產品總成為空
            {
                Dictionary<string, List<PR_Product>> dictionary2 = new Dictionary<string, List<PR_Product>>();
                //從查詢的資料集合中查詢出所有的總成
                List<PR_Product> snumDistinct = product.Where((x, firstId) => product.FindIndex(z => z.SNum == x.SNum) == firstId).ToList();
                foreach(PR_Product item in snumDistinct)
                {
                    //從大資料集合中查詢該總成的資料集合
                    List<PR_Product> snumList = product.Where(x => x.SNum == item.SNum).ToList();
                    dictionary2.Add(item.SNum, snumList);
                }
                dictionary.Add(startTime, dictionary2);
            }
            return dictionary;
        }

Excel檔案幫助類方法:

      /// <summary>
        /// 匯出產品質量資料,每個總成一個Excel
        /// </summary>
        /// <param name="filePath">匯出檔案路徑</param>
        /// <param name="dictionary">匯出資料字典</param>
        /// <param name="fieldInfies">匯出資料表頭</param>
        /// <param name="Response">頁面響應</param>
        /// <returns></returns>
        public static FileStream ToExcel(String filePath, Dictionary<string, Dictionary<string, List<T>>> dictionary, List<ExportFieldInfo> fieldInfies, HttpResponseBase Response)
        {
            //匯出檔案路徑(這裡也可以寫成固定路徑"F:\\exporfolder")
            //String filePath = "F:\\exporfolder";
            //建立此路徑(配置檔案中的地址一定要保證磁碟存在)
            Directory.CreateDirectory(filePath);
            //匯出壓縮檔案的全路徑(zipFilePath)
            DateTime dateTimeZip = DateTime.Now;
            string zipFilePath = filePath + Path.DirectorySeparatorChar + "QM_" + dateTimeZip.ToString("yyyyMMdd") + "_" + dateTimeZip.ToString("HHmmss") + "_" + dateTimeZip.ToString("fff") + ".zip";
            //匯出Excel檔案路徑
            string fullFilePath = "";
            //儲存Excel檔名
            string fileName = "";
            //用於存放生成的Excel檔名稱集合
            List<string> fileNames = new List<string>();
            //excel檔案流
            FileStream excel = null;
            foreach (Dictionary<string, List<T>> items in dictionary.Values)
            {
                foreach (var item in items)
                {
                    DateTime dateTimeExcel = DateTime.Now;
                    //Excel檔名
                    fileName = item.Key + "_" + dateTimeExcel.ToString("yyyyMMdd") + "_" + dateTimeExcel.ToString("HHmmss") + "_" + dateTimeExcel.ToString("fff") + ".xlsx";
                    //Excel檔案路徑
                    fullFilePath = filePath + Path.DirectorySeparatorChar + fileName;
                    //存放到Excel檔名稱集合
                    fileNames.Add(fullFilePath);
                    excel = File.Create(fullFilePath);
                    HSSFWorkbook book = createColumnHSSF(item.Key, item.Value, fieldInfies);
                    // 寫檔案
                    book.Write(excel);
                    excel.Close();
                }
            }
            FileStream stream = ZipFiles(fileNames, zipFilePath, Response);
            return stream;
        }
     /// <summary>
        /// 壓縮多個檔案
        /// </summary>
        /// <param name="filesToZip">要進行壓縮的檔名集合</param>
        /// <param name="zipedFile">壓縮後生成的壓縮檔名</param>
        public static FileStream ZipFiles(List<string> filesToZip, string zipedFile, HttpResponseBase Response)
        {
            Response.AddHeader("content-disposition", "attachment;filename=" + zipedFile.Substring(zipedFile.LastIndexOf("\\", StringComparison.Ordinal) + 1) );
            //Zip檔案流
            FileStream zipFile = File.Create(zipedFile);
            //將zipStream寫到響應輸出流中
            ZipOutputStream zipStream = new ZipOutputStream(Response.OutputStream);
            //遍歷所有的Excel檔案
            foreach (string fileToZip in filesToZip)
            {
                if (string.IsNullOrEmpty(fileToZip))
                {
                    throw new ArgumentException(fileToZip);
                }
                if (string.IsNullOrEmpty(zipedFile))
                {
                    throw new ArgumentException(zipedFile);
                }
                if (!File.Exists(fileToZip))
                {
                    throw new FileNotFoundException("指定要壓縮的檔案: " + fileToZip + " 不存在!");
                }
                try
                {
                    //讀取Excel檔案到檔案流中
                    using (var fs = File.OpenRead(fileToZip))
                    {
                        var buffer = new byte[fs.Length];
                        fs.Read(buffer, 0, buffer.Length);
                        fs.Close();
                        //從Excel檔案路徑中讀取Excel檔名
                        var fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\", StringComparison.Ordinal) + 1);
                        //根據檔名建立ZipEntry
                        var zipEntry = new ZipEntry(fileName);
                        //將ZipEntry放入zipStream流中
                        zipStream.PutNextEntry(zipEntry);
                        zipStream.SetLevel(5);
                        zipStream.Write(buffer, 0, buffer.Length);
                    }            
                }
                catch (IOException ioex)
                {
                    throw new IOException(ioex.Message);
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }
            //zipStream完成後返回
            zipStream.Finish();
            return zipFile;
        }