需求背景: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; }