早在.NET 3.5的時代,大約是2008年左右,微軟就提供了一個Microsoft Chart Control for .NET 3.5的元件,相信有使用過的人都曾體驗過它的威力,使用它在 Web Form 上面製作圖表幾乎是所向無敵。
早在.NET 3.5的時代,大約是2008年左右,微軟就提供了一個Microsoft Chart Control for .NET 3.5的元件,相信有使用過的人都曾體驗過它的威力,使用它在 Web Form 上面製作圖表幾乎是所向無敵。後來此元件已含括在 .NET Framework 4.0 中了。如下圖,當時使用 Visual Studio 2008 使用 Microsoft Chart Control for .NET 3.5 的畫面:
當時我們要產生類似上圖的圖表可以寫如下程式來產生:
1: Series series = new Series("Spline");
2: series.ChartType = SeriesChartType.Spline;
3: series.BorderWidth = 3;
4: series.ShadowOffset = 2;
5:
6: // 建立 series 欄位
7: series.Points.AddY(67);
8: series.Points.AddY(57);
9: series.Points.AddY(83);
10: series.Points.AddY(23);
11: series.Points.AddY(70);
12: series.Points.AddY(60);
13: series.Points.AddY(90);
14: series.Points.AddY(20);
15:
16: // 將 Series 加入到 Chart 的集合物件中
17: Chart1.Series.Add(series);
程式可以得到如下結果:
而今天,由於在 .NET Framework 4.0 早已內建了 Microsoft Chart Control ,因此要在 ASP.NET Razor 中使用 Chart 變的更容易了。在ASP.NET Razor 使用Chart產生類似上圖的圖表,我們可以這樣寫:
1: <!DOCTYPE html>
2:
3: <html lang="en">
4: <head>
5: <meta charset="utf-8" />
6: <title></title>
7: </head>
8: <body>
9: @{
10: var myChart = new Chart(width: 600, height: 400)
11: .AddTitle("1998 第(1/2)季銷售圖表測試")
12: .AddSeries(
13: name: "員工姓名: Davolio",
14: xValue: new[] { "一月", "二月", "三月", "四月", "五月", "六月" },
15: yValues: new[] { "2", "6", "4", "5", "3", "8" })
16: .Write();
17: }
18: </body>
19: </html>
如上Razor 程式的執行結果如下,簡單的程式及可以產出這樣的圖表。
如上,相信對於圖表的產出是不是躍躍欲試呢?還沒完呢!這只是產生單一的圖形輸出到用戶端IE而已,然而通常老闆提的需求不會這麼簡單的!今天我想要產出一份業務的 1-6月,也就是 (第一季~第二季) 的銷售報表,必須有圖形的。當然同樣的 Solution 當中也有 Reporting Service 的 Local Report 也可以做到,不過當然,如果是 Local Report 是不需要 Reporting Service 的執行個體服務的,但是我又不想搞得太複雜,因為這個報表只會在會議中用幾次而已,那個CSHTML檔案的Razor可能就是快速產出這個報表的解決方案了。
(一)、第一步,設計報表樣式
首先,我們必須思索一下報表產出的格式,由於老闆希望在左邊秀出該員工的基本資料,因此加以編排後使用Expression Web 4 拉出大致的頁面長相,圖形我先隨便找一張圖代替,如下:(註:您不一定要使用Expression Web 4拉畫面,那只是筆者的習慣,您也可以用 Visual Studio)
(二)、建立 ChartReport.cshtml ,並將上方的HTML原始碼複製出來
在ChartReport.cshtml 改以嵌入方法來使用。當然在該嵌入方法中我們還要寫一些程式碼將該員工(業務)的基本資料撈出來。程式碼如下:
1: @helper MyEmployeeDetail(string LastName) {
2: var db = Database.Open("NorthwindDB");
3: string SQL = @"select * from Employees E where E.LastName='"+LastName+@"'";
4: var query = db.Query(SQL);
5: string EmployeeID = "";
6: string FirstName = "";
7: string LastName2 = "";
8: string Title = "";
9: string HomePhone = "";
10: string PostalCode = "";
11: string Country = "";
12: foreach(var cc in query){
13: EmployeeID = cc.EmployeeID.ToString();
14: FirstName = cc.FirstName;
15: LastName2 = cc.LastName;
16: Title = cc.Title;
17: HomePhone = cc.HomePhone;
18: PostalCode = cc.PostalCode;
19: Country = cc.Country;
20: }
21: <table style="width: 100%">
22: <tr>
23: <td>Employees ID :</td>
24: <td>@EmployeeID</td>
25: <td rowspan="6">
26: <img src="ChartPage.cshtml" />
27: </td>
28: </tr>
29: <tr>
30: <td>FirstName :</td>
31: <td>@FirstName</td>
32: </tr>
33: <tr>
34: <td>LastName :</td>
35: <td>@LastName</td>
36: </tr>
37: <tr>
38: <td>Title :</td>
39: <td>@Title</td>
40: </tr>
41: <tr>
42: <td>Home Phone :</td>
43: <td>@HomePhone</td>
44: </tr>
45: <tr>
46: <td>PostalCode :</td>
47: <td>@PostalCode</td>
48: </tr>
49: <tr>
50: <td>Country</td>
51: <td>@Country</td>
52: <td> </td>
53: </tr>
54: <tr>
55: <td>Region :</td>
56: <td> </td>
57: <td> </td>
58: </tr>
59: </table>
60: }
61:
62: <!DOCTYPE html>
63:
64: <html lang="en">
65: <head>
66: <meta charset="utf-8" />
67: <title></title>
68: <style type="text/css">
69: .auto-style1 {
70: text-align: center;
71: font-size: xx-large;
72: color: #0000FF;
73: }
74: </style>
75: </head>
76: <body>
77: <p class="auto-style1"><strong>XX公司業務銷售報表 (第1-2季)</strong></p>
78: <hr />
79: @MyEmployeeDetail("Davolio")
80: <p> </p>
81: <hr />
82: <p>列印日期:@DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")</p>
83: </body>
84: </html>
(三)、撰寫圖表程式
眼尖的讀者應該有發現,由於我們是直接呼叫 Chart().Write() 方法,它會直接寫入 Response 的資料流中,因此我們直接把它當作如同泛型處理常式來使用。而成式中由於只是個 Demo,暫時寫死 [年份] [月份] 等參數,與暫不考慮 SQL Injection 等問題。
而程式碼的設計部分,筆者使用一個 Razor的 functions ,該方法用已傳回當月的銷售實績,因此整個 ChartPage.cshtml 程式碼筆者撰寫完畢後會像這樣:
1: @functions{
2: public string GetOrdersByYearMonth(string Year, string Month, string LastName)
3: {
4: var db = Database.Open("NorthwindDB");
5: string SQL = @"select COUNT(*) AS MY_ORDERS from Employees E join Orders O
6: on E.EmployeeID=O.EmployeeID
7: where E.LastName='"+LastName+@"'
8: AND YEAR(O.OrderDate)="+Year+@" AND MONTH(O.OrderDate)="+Month;
9: var query = db.Query(SQL);
10: string result = "AAA";
11: try{
12: foreach(var re in query){
13: result = re.MY_ORDERS.ToString();
14: }
15: }
16: finally
17: {
18: db.Close();
19: }
20: return result;
21: }
22: }
23:
24: @{
25: string January = GetOrdersByYearMonth("1998", "1", "Davolio");
26: string February = GetOrdersByYearMonth("1998", "2", "Davolio");
27: string March = GetOrdersByYearMonth("1998", "3", "Davolio");
28: string April = GetOrdersByYearMonth("1998", "4", "Davolio");
29: string May = GetOrdersByYearMonth("1998", "5", "Davolio");
30: string June = GetOrdersByYearMonth("1998", "6", "Davolio");
31: }
32:
33: @{
34: var myChart = new Chart(width: 600, height: 400)
35: .AddTitle("1998 第(1/2)季銷售圖表測試")
36: .AddSeries(
37: name: "員工姓名: Davolio",
38: xValue: new[] { "一月", "二月", "三月", "四月", "五月", "六月" },
39: yValues: new[] { January, February, March, April, May, June })
40: .Write();
41: }
42:
中間的部分會呼叫 6 次,以取得 1998 年 (1-6月) 的銷售數字。
(四)、最後將 ChartPage.cshtml 做為 ChartReport.cshtml 的內嵌方法的 <img> 的src來源。
(五)、測試與執行
該程式的執行結果應該會式如下:
如上!是不是又有一些成就感了!
下次筆者再介紹其他開發上的應用,謝謝各位!
簽名:
學習是一趟奇妙的旅程
這當中,有辛苦、有心酸、也有成果。有時也會有瓶頸。要能夠繼續勇往直前就必須保有一顆最熱誠的心。
軟體開發之路(FB 社團):https://www.facebook.com/groups/361804473860062/
Gelis 程式設計訓練營(粉絲團):https://www.facebook.com/gelis.dev.learning/
如果文章對您有用,幫我點一下讚,或是點一下『我要推薦』,這會讓我更有動力的為各位讀者撰寫下一篇文章。
非常謝謝各位的支持與愛護,小弟在此位各位說聲謝謝!!! ^_^