导出Excel实现 (ASP.NET C# 代码部分)
背景: 实现导出Excel功能.
技术: ASP.NET , 采用`Aspose.Cells`第三方组件, C# 实现通用部分.
根据前台Ext Grid完成导入Excel中文列与实际存储列的对应关系. 组织完 Workbook 组织, 保存到Server临时目录, 返回地址下载, 每次都为新故文件名 采用了 随机数:
//_reportName :Excel名称 //_reportName: 报表名称 //_headerStruct: 包含数据库列与Excel中文列的对应关系. (此处取Ext表头) public string ExportServerExcelFile(Aspose.Cells.Workbook w, string fileName) { if (!Directory.Exists(Server.MapPath("~/ExportFile/"))) Directory.CreateDirectory(Server.MapPath("~/ExportFile/")); w.Save(Server.MapPath("~/ExportFile/") + fileName); return "http://" + Request.Url.Host + ":" + Request.Url.Port + "/ExportFile/" + fileName; } public string ExportExcelAll(string queryP, string _reportName, string _headerStruct) { DataTable dt = ....; //取查到库中数据 string jsonData = Ext.Net.JSON.Serialize(dt); Workbook w = this.CreateWorkbook(jsonData, _reportName, _headerStruct); string fileName = _reportName.Split('(')[0] + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx"; return this.ExportServerExcelFile(w, fileName); } public Workbook CreateWorkbook(string jsonData, string _reportName, string _headerStruct) { var w = new Workbook(); Worksheet ws = (Worksheet)w.Worksheets[0]; if (!string.IsNullOrEmpty(_headerStruct)) SerHeader1(JSON.Deserialize<dynamic[]>(_headerStruct), ws); RangeHeader(ws); //设置标题 ws.Cells[0, 0].PutValue(_reportName); Range titleRange = ws.Cells.CreateRange(0, 0, 1, lastColIndex); #region ===样式 var style = new Style { HorizontalAlignment = TextAlignmentType.Center, Font = { Size = 25, IsBold = true } }; style.Borders.SetStyle(Aspose.Cells.CellBorderType.Thin); style.Borders.DiagonalStyle = Aspose.Cells.CellBorderType.None; var styleFlag = new StyleFlag { HorizontalAlignment = true, VerticalAlignment = true, Font = true, FontSize = true, FontBold = true, Borders = true }; titleRange.ApplyStyle(style, styleFlag); titleRange.RowHeight = 26; titleRange.Merge(); var cellStyle1 = new Style(); cellStyle1.Borders.SetStyle(Aspose.Cells.CellBorderType.Thin); cellStyle1.Borders.DiagonalStyle = Aspose.Cells.CellBorderType.None; cellStyle1.IsTextWrapped = true; var cellStyleNumber = new Style(); cellStyleNumber.Borders.SetStyle(Aspose.Cells.CellBorderType.Thin); cellStyleNumber.Borders.DiagonalStyle = Aspose.Cells.CellBorderType.None; cellStyleNumber.Number = 2; #endregion //列集合 JavaScriptSerializer serializer = new JavaScriptSerializer(); serializer.MaxJsonLength = int.MaxValue; List<grid> _Test = serializer.Deserialize<List<grid>>(_headerStruct); var companies = JSON.Deserialize<Dictionary<string, string>[]>(jsonData); for (int i = 0; i < companies.Length; i++) { int tmpColIndex = 0; foreach (var item in companies[i]) { if (headerNames.IndexOf(item.Key) > -1) { var list = _Test.Where(p => p.DataIndex == item.Key).ToList(); //获取列名称 var cColumn = list[0]; //初始样式 ws.Cells[lastLevel + 1 + i, headerNames.IndexOf(item.Key)].SetStyle(cellStyle1, true); if (cColumn.DataType == "float" || cColumn.DataType == "decimal") //1. 数字类型 { if (IsDecimal(item.Value)) { ws.Cells[lastLevel + 1 + i, headerNames.IndexOf(item.Key)].PutValue(ToDouble(item.Value));//金额保留2位数 //ws.Cells[lastLevel + 1 + i, headerNames.IndexOf(item.Key)].SetStyle(cellStyleNumber); } } else if (cColumn.DataType == "date") //2. 日期类型 { ws.Cells[lastLevel + 1 + i, headerNames.IndexOf(item.Key)].PutValue( (string.IsNullOrWhiteSpace(item.Value) ? "" : Convert.ToDateTime(item.Value).ToString("yyyy-MM-dd hh:mm:ss")) ); } else //3. 字符串和集合类型auto { ws.Cells[lastLevel + 1 + i, headerNames.IndexOf(item.Key)].PutValue(item.Value); } //★获得要隐藏的列 if (cColumn.Hiden == true)//列需要隐藏: 字典类型 { var index = headerNames.IndexOf(item.Key);//列索引 ws.Cells.HideColumn(index); } } tmpColIndex++; } } return w; } private void RangeHeader(Worksheet ws) { for (int row = 1; row <= lastLevel; row++) { for (int col = 0; col < lastColIndex; col++) { var style = new Style { HorizontalAlignment = TextAlignmentType.Center, VerticalAlignment = TextAlignmentType.Center }; style.Borders.SetStyle(Aspose.Cells.CellBorderType.Thin); style.Borders.DiagonalStyle = Aspose.Cells.CellBorderType.None; var styleFlag = new StyleFlag { HorizontalAlignment = true, VerticalAlignment = true, Font = true, FontSize = true, FontBold = true, Borders = true }; ws.Cells[row, col].SetStyle(style); if (ws.Cells[row, col].Value != null) { RangeCell(ws, row, col); } } } foreach (Range item in rc.Where(m => m != null)) { var style = new Style { HorizontalAlignment = TextAlignmentType.Center, VerticalAlignment = TextAlignmentType.Center }; style.Borders.SetStyle(Aspose.Cells.CellBorderType.Thin); style.Borders.DiagonalStyle = Aspose.Cells.CellBorderType.None; var styleFlag = new StyleFlag { HorizontalAlignment = true, VerticalAlignment = true, Font = true, FontSize = true, FontBold = true, Borders = true }; item.ApplyStyle(style, styleFlag); try { item.Merge(); } catch (Exception) { } } } /// <summary> /// grid表头 /// </summary> [Serializable] public class grid { public string Text { get; set; } public string DataIndex { get; set; } public string Width { get; set; } public List<grid> Cols { get; set; } public bool Hiden { get; set; } public string xtype { get; set; } public string DataType { get; set; }//列类型 }
其中, 传入
_headerStruct
参数格式截图所示, 包括grid 类用于反序列化, 类似于, 关键用到了Text, DataType, DataIndex 关键, 特殊处理了Ext的多表头, 例如Cols 非末级就忽略了(函数
RangeHeader的作用
):
在未知中徜徉,
求心之荡漾。