Excel 中的透視表對於數據分析來說,非常的方便,而且很多業務人員對於Excel的操作也是非常熟悉的,因此用Excel作為分析數據的界面,不失為一種很好的選擇。那麼如何用C#從數據庫中抓取數據,並在Excel 動態生成PivotTable呢?下面結合實例來說明。
一般來說,數據庫的設計都遵循規范化的原則,從而減少數據的冗余,但是對於數據分析來說,數據冗余能夠提高數據加載的速度,因此為了演示透視表,這裡現在數據庫中建立一個視圖,將需要分析的數據整合到一個視圖中。如下圖所示:
數據源准備好後,我們先來建立一個web應用程序,然後用NuGet加載Epplus程序包,如下圖所示:
在index.aspx前台頁面中,編寫如下腳本:
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="index.aspx.cs" Inherits="ExcelPivot.Web.index" %> 2 3 <!DOCTYPE html> 4 <html xmlns="http://www.w3.org/1999/xhtml"> 5 <head runat="server"> 6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 7 <title>Excel PivotTable</title> 8 <link rel="stylesheet" type="text/css" href="css/style.css" /> 9 </head> 10 <body> 11 <form id="form1" runat="server"> 12 <div id="container"> 13 14 <div id="contents"> 15 16 <div id="post"> 17 <header> 18 <h1> Excel PivotTable </h1> 19 </header> 20 <div id="metro-array" > 21 <div > 22 23 <a class="metro-tile" > 24 25 <input type="button" runat="server" id="Button1" name="btn1" value="回款情況分析" onserverclick="btn1_ServerClick" 26 /> 27 28 </a> 29 30 <a class="metro-tile" > 31 <input type="button" runat="server" id="Button2" name="btn1" value="sampe1" onserverclick="btn1_ServerClick" 32 /> 33 </a> 34 </div> 35 36 <div > 37 38 <a class="metro-tile" > 39 <input type="button" runat="server" id="btn1" name="btn1" value="sampe1" onserverclick="btn1_ServerClick" 40 /> 41 </a> 42 43 </div> 44 45 <div > 46 47 <a class="metro-tile" > 48 <input type="button" runat="server" id="Button3" name="btn1" value="sampe1" onserverclick="btn1_ServerClick" 49 /> 50 </a> 51 52 <a class="metro-tile" > 53 <input type="button" runat="server" id="Button4" name="btn1" value="sampe1" onserverclick="btn1_ServerClick" 54 /> 55 </a> 56 57 <a class="metro-tile" > 58 <input type="button" runat="server" id="Button5" name="btn1" value="sampe1" onserverclick="btn1_ServerClick" 59 /> 60 </a> 61 </div> 62 63 </div> 64 </div> 65 66 </div> 67 </div> 68 </form> 69 </body> 70 <script src="js/tileJs.js" type="text/javascript"></script> 71 </html>
其中 TileJs是一個開源的構建類似win8 Metro風格的javascript庫。
編寫後台腳本:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using OfficeOpenXml; 8 using OfficeOpenXml.Table; 9 using OfficeOpenXml.ConditionalFormatting; 10 using OfficeOpenXml.Style; 11 using OfficeOpenXml.Utils; 12 using OfficeOpenXml.Table.PivotTable; 13 using System.IO; 14 using System.Data.SqlClient; 15 using System.Data; 16 namespace ExcelPivot.Web 17 { 18 public partial class index : System.Web.UI.Page 19 { 20 protected void Page_Load(object sender, EventArgs e) 21 { 22 23 } 24 private DataTable getDataSource() 25 { 26 //createDataTable(); 27 //return ProductInfo; 28 29 SqlConnection conn = new SqlConnection(); 30 conn.ConnectionString = "Data Source=.;Initial Catalog=olap;Persist Security Info=True;User ID=sa;Password=sa"; 31 conn.Open(); 32 33 SqlDataAdapter ada = new SqlDataAdapter("select * from v_pm_olap_test", conn); 34 DataSet ds = new DataSet(); 35 ada.Fill(ds); 36 37 return ds.Tables[0]; 38 39 40 41 } 42 43 protected void btn1_ServerClick(object sender, EventArgs e) 44 { 45 try 46 { 47 DataTable table = getDataSource(); 48 string path = "_demo_" + System.Guid.NewGuid().ToString().Replace("-", "_") + ".xls"; 49 //string path = "_demo.xls"; 50 FileInfo fileInfo = new FileInfo(path); 51 var excel = new ExcelPackage(fileInfo); 52 53 var wsPivot = excel.Workbook.Worksheets.Add("Pivot"); 54 var wsData = excel.Workbook.Worksheets.Add("Data"); 55 wsData.Cells["A1"].LoadFromDataTable(table, true, OfficeOpenXml.Table.TableStyles.Medium6); 56 if (table.Rows.Count != 0) 57 { 58 foreach (DataColumn col in table.Columns) 59 { 60 61 if (col.DataType == typeof(System.DateTime)) 62 { 63 var colNumber = col.Ordinal + 1; 64 var range = wsData.Cells[2, colNumber, table.Rows.Count + 1, colNumber]; 65 range.Style.Numberformat.Format = "yyyy-MM-dd"; 66 } 67 else 68 { 69 70 } 71 } 72 } 73 74 var dataRange = wsData.Cells[wsData.Dimension.Address.ToString()]; 75 dataRange.AutoFitColumns(); 76 var pivotTable = wsPivot.PivotTables.Add(wsPivot.Cells["A1"], dataRange, "Pivot"); 77 pivotTable.MultipleFieldFilters = true; 78 pivotTable.RowGrandTotals = true; 79 pivotTable.ColumGrandTotals = true; 80 pivotTable.Compact = true; 81 pivotTable.CompactData = true; 82 pivotTable.GridDropZones = false; 83 pivotTable.Outline = false; 84 pivotTable.OutlineData = false; 85 pivotTable.ShowError = true; 86 pivotTable.ErrorCaption = "[error]"; 87 pivotTable.ShowHeaders = true; 88 pivotTable.UseAutoFormatting = true; 89 pivotTable.ApplyWidthHeightFormats = true; 90 pivotTable.ShowDrill = true; 91 pivotTable.FirstDataCol = 3; 92 //pivotTable.RowHeaderCaption = "行"; 93 94 //row field 95 var field004 = pivotTable.Fields["銷售客戶經理"]; 96 pivotTable.RowFields.Add(field004); 97 98 var field001 = pivotTable.Fields["項目簡稱"]; 99 pivotTable.RowFields.Add(field001); 100 //field001.ShowAll = false; 101 102 //column field 103 var field002 = pivotTable.Fields["年"]; 104 pivotTable.ColumnFields.Add(field002); 105 field002.Sort = OfficeOpenXml.Table.PivotTable.eSortType.Ascending; 106 var field005 = pivotTable.Fields["月"]; 107 pivotTable.ColumnFields.Add(field005); 108 field005.Sort = OfficeOpenXml.Table.PivotTable.eSortType.Ascending; 109 110 //data field 111 var field003 = pivotTable.Fields["回款金額"]; 112 field003.Sort = OfficeOpenXml.Table.PivotTable.eSortType.Descending; 113 pivotTable.DataFields.Add(field003); 114 115 pivotTable.RowGrandTotals = false; 116 pivotTable.ColumGrandTotals = false; 117 118 //save file 119 excel.Save(); 120 //open excel file 121 string file = @"C:\Windows\explorer.exe"; 122 System.Diagnostics.Process.Start(file, path); 123 124 } 125 catch (Exception ex) 126 { 127 Response.Write(ex.Message); 128 } 129 } 130 } 131 }
編譯運行,如下圖所示:
單擊 [回款情況分析],稍等片刻,會打開Excel,並自動生成透視表,如下圖所示: