記得2010年之前,公司的項目基本上都要用到報表,以前我們常用的方法就是針對客戶的需求來定製化開發(基本上是死寫代碼)來實現,經常導致項目經常性的延期,因為客戶的需求經常會變化,隨著用戶的使用認知度的提高,對報表的要求越來越高,導致程式員不停的修改代碼來實現,效率不高、結束遙遙無期。。。非常的痛苦; ...
記得2010年之前,公司的項目基本上都要用到報表,以前我們常用的方法就是針對客戶的需求來定製化開發(基本上是死寫代碼)來實現,經常導致項目經常性的延期,因為客戶的需求經常會變化,隨著用戶的使用認知度的提高,對報表的要求越來越高,導致程式員不停的修改代碼來實現,效率不高、結束遙遙無期。。。非常的痛苦;當然市面上有很多報表開發工具可以實現,但是針對小公司來說採購一套這樣的系統的成本也非常的高,所以我們決定自己來開發一套像目前的潤乾、FineReport 這樣的報表設計器,來實現快速的報表設計製作。
當初為了開發這樣的系統,花費的了很長的時間學習查閱各種資料,其痛苦只有程式員才能體會,因為沒有任何現成的實例代碼可供參考,只有看別人的思路來一步步的摸索,本文將我們當初設計製作的報表設計器的功能分享出來,讓有需要的或想開發報表設計的朋友們提供一個參考,儘量少走很動彎路,設計端可以直接使用,但是計算引擎和網頁的計算的源碼就不能分享出來了(請不要介意,因為涉及到公司的保密原因)
記得當初為了製作報表設計器,在網上查找有沒有相關的實例資料,找了很久,也是沒有找到合適的,後來發現 SourceGrid 可以實現單元格的合併拆分功能,所以決定修改實現winform端的報表設計。下麵我將製作的E_Report 報表控制項抽取出來建立一個簡易的Winform的可運行的實例提供給大伙下載,希望能給你的開發提供一點幫助和借鑒;當然你可以直接使用也可以,裡面的設計功能基本全部能。
抽取出來的源碼包含:E_Report 報表設計自定義控制項DLL源碼; EReportDemo 建立的簡易Winform 端設計器使用DLL的實例源碼;
一、運行效果
實例中,只做了一個簡單的效果,工具欄的按鈕在單元格右擊屬性中都有,只是放了幾個常用的在工具導航欄中(右擊單元格屬性可以看到設計導航)
可以進行單元格的合併、拆分、字體、顏色、背景、邊框等的設置,朋友們可以自己編寫保存發佈等功能,實現報表的真實功能;
例如單元格屬性(其他還有很多的屬性,自己下載源碼後運行起來就能看到了)
對錶格的斜線、斜線文字有很好的支持;可以設置表頭、表位、標題等 實際效果圖如下
二、使用介紹
1、頁面初始化的時候,通過 ReportDoc 類 初始報表的行列及單元格屬性
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.Drawing; 5 using System.Windows.Forms; 6 using System.Drawing.Drawing2D; 7 using System.Xml; 8 using System.Collections; 9 using E_Report; 10 11 namespace EReportDemo 12 { 13 /// <summary> 14 /// 報表表格對象 15 /// </summary> 16 public class ReportDoc 17 { 18 #region 變數參數定義 19 20 /// <summary> 21 /// 表格對象 22 /// </summary> 23 private EReport _nowReport; 24 25 /// <summary> 26 /// 報表配置編碼 27 /// </summary> 28 private string _reportCode = ""; 29 30 /// <summary> 31 /// 表報設計狀態 32 /// </summary> 33 private string _reportState = ""; 34 35 #endregion 36 37 #region 函數構造方法 38 39 /// <summary> 40 /// 構造函數 41 /// </summary> 42 public ReportDoc() 43 { 44 this._nowReport = null; 45 this._reportCode = ""; 46 this._reportState = ""; 47 48 } 49 50 51 /// <summary> 52 /// 獲取--設置--表格對象 53 /// </summary> 54 public EReport NowReport 55 { 56 get { return this._nowReport; } 57 set { this._nowReport = value; } 58 } 59 60 /// <summary> 61 /// 報表配置編碼 62 /// </summary> 63 public string ReportCode 64 { 65 get { return this._reportCode; } 66 set { this._reportCode = value; } 67 } 68 69 /// <summary> 70 /// 報表設計狀態 71 /// 新增、修改 兩種狀態 72 /// </summary> 73 public string ReportState 74 { 75 get { return this._reportState; } 76 set { this._reportState = value; } 77 } 78 79 /// <summary> 80 /// 資源釋放 81 /// </summary> 82 ~ReportDoc() 83 { 84 this._nowReport = null; 85 this._reportState = ""; 86 87 } 88 89 #endregion 90 91 #region 載入報表表格 92 93 /// <summary> 94 /// 初始化--報表表格 95 /// </summary> 96 public void InitReport() 97 { 98 99 int rCount = 41; // 41行 100 int cCount = 20; // 20列 101 102 _nowReport.Redim(rCount, cCount); 103 _nowReport.FixedRows = 1; 104 _nowReport.FixedColumns = 1; 105 106 InitCells(); 107 108 } 109 110 /// <summary> 111 /// 初始化--單元格 112 /// </summary> 113 public void InitCells() 114 { 115 // 第一行 第一列 116 _nowReport.Rows[0].Height = 23; 117 _nowReport.Columns[0].Width = 50; 118 119 // 設置00格 120 _nowReport[0, 0] = new E_Report.Cells.HeaderColumn(""); 121 122 // 設置行 123 for (int rr = 1; rr < _nowReport.RowsCount; rr++) 124 { 125 string tmRowT = rr.ToString(); 126 _nowReport[rr, 0] = new E_Report.Cells.HeaderRow(tmRowT); 127 } 128 129 // 設置列 130 for (int cc = 1; cc < _nowReport.ColumnsCount; cc++) 131 { 132 _nowReport[0, cc] = new E_Report.Cells.HeaderColumn(_nowReport.GetColumnHeadTileChar(cc)); 133 } 134 135 // 設置單元格 136 for (int iRow = 1; iRow < _nowReport.RowsCount; iRow++) 137 { 138 for (int iCol = 1; iCol < _nowReport.ColumnsCount; iCol++) 139 { 140 _nowReport[iRow, iCol] = new E_Report.Cells.Cell("", typeof(string)); 141 } 142 } 143 144 } 145 146 147 #endregion 148 149 } 150 }View Code
2、工具導航欄 設置單元格相關屬性
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Text; 7 using System.Windows.Forms; 8 using System.Collections; 9 using E_Report; 10 11 namespace EReportDemo 12 { 13 /// <summary> 14 /// 本程式只是Winform端的報表設計功能 15 /// 至於其他的功能,本實例沒有提供 16 /// 報表設計的設計效果:可以查看 www.sdpsoft.com SDP軟體快速開發平臺 報表設計篇 17 /// </summary> 18 19 public partial class EReportMain : Form 20 { 21 private ReportDoc report; 22 private E_Report.Cells.Controllers.PopupMenu myPopupMenu; 23 24 public EReportMain() 25 { 26 InitializeComponent(); 27 } 28 29 private void EReportMain_Load(object sender, EventArgs e) 30 { 31 Cursor.Current = Cursors.WaitCursor; 32 gridMain.Rows.Clear(); 33 myPopupMenu = new E_Report.Cells.Controllers.PopupMenu(gridMain); 34 35 report = new ReportDoc(); 36 report.NowReport = gridMain; 37 report.InitReport(); 38 Cursor.Current = Cursors.Default; 39 } 40 41 private void gridMain_MouseMove(object sender, MouseEventArgs e) 42 { 43 this.lbl_X.Text = e.X.ToString(); 44 this.lbl_Y.Text = e.Y.ToString(); 45 } 46 47 /// <summary> 48 /// 工具欄報表單元格事件 49 /// </summary> 50 /// <param name="sender"></param> 51 /// <param name="e"></param> 52 private void btn_GridTools_Click(object sender, EventArgs e) 53 { 54 string sType = ((Button)sender).Tag.ToString().Trim().ToLower(); 55 switch (sType) 56 { 57 58 case "cellproperty": // 單元格屬性設置 59 myPopupMenu.CellProperty_Click(sender, e); 60 break; 61 case "fontset": // 單元格字體設置 62 myPopupMenu.CellFont_Click(sender, e); 63 break; 64 case "fontcolor": // 文本字體顏色 65 myPopupMenu.CellForColor_Click(sender, e); 66 break; 67 case "backcolor": // 單元格背景色 68 myPopupMenu.CellBackColor_Click(sender, e); 69 break; 70 case "cellborder": // 單元格邊框設置 71 myPopupMenu.CellBorder_Click(sender, e); 72 break; 73 case "lock": // 設置表格只讀 74 myPopupMenu.LockReport_Click(sender, e); 75 break; 76 case "unlock": // 設置表格編輯 77 myPopupMenu.UnLockReport_Click(sender, e); 78 break; 79 case "alignleft": // 水平居左對齊 80 myPopupMenu.AlignLeft_Click(sender, e); 81 break; 82 case "aligncenter": // 水平居中對齊 83 myPopupMenu.AlignCenter_Click(sender, e); 84 break; 85 case "alignright": // 水平居右對齊 86 myPopupMenu.AlignRight_Click(sender, e); 87 break; 88 case "aligntop": // 垂直居上對齊 89 myPopupMenu.AlignTop_Click(sender, e); 90 break; 91 case "alignmiddle": // 垂直居中對齊 92 myPopupMenu.AlignMiddle_Click(sender, e); 93 break; 94 case "alignbottom": // 垂直居下對齊 95 myPopupMenu.AlignBottom_Click(sender, e); 96 break; 97 case "addindent": // 增加文本縮進 98 myPopupMenu.AddIndent_Click(sender, e); 99 break; 100 case "delindent": // 清除文本縮進 101 myPopupMenu.RemoveIndent_Click(sender, e); 102 break; 103 case "insertrow": // 插入後一行 104 myPopupMenu.InsertRow_Click(sender, e); 105 break; 106 case "appendrow": // 表格追加行 107 myPopupMenu.AddRow_Click(sender, e); 108 break; 109 case "delrow": // 刪除選中行 110 myPopupMenu.DeleteRows_Click(sender, e); 111 break; 112 case "hiderow": // 隱藏選中行 113 myPopupMenu.HideSelectRows_Click(sender, e); 114 break; 115 case "showrow": // 顯示選中行 116 myPopupMenu.ShowSelectRows_Click(sender, e); 117 break; 118 case "showallrow": // 顯示所有行 119 myPopupMenu.ShowAllRows_Click(sender, e); 120 break; 121 case "insertcol": // 插入左側列 122 myPopupMenu.InsertColumn_Click(sender, e); 123 break; 124 case "addcol": // 插入右側列 125 myPopupMenu.AddColumn_Click(sender, e); 126 break; 127 case "delcol": // 刪除選中列 128 myPopupMenu.DeleteColumns_Click(sender, e); 129 break; 130 case "hidecol": // 隱藏選中列 131 myPopupMenu.HideSelectColumns_Click(sender, e); 132 break; 133 case "showcol": // 顯示選中列 134 myPopupMenu.ShowSelectColumns_Click(sender, e); 135 break; 136 case "showallcol": // 顯示所有列 137 myPopupMenu.ShowAllColumns_Click(sender, e); 138 break; 139 case "mergecell": // 合併單元格 140 myPopupMenu.MergeCell_Click(sender, e); 141 break; 142 case "splitcell": // 拆分單元格 143 myPopupMenu.SplitCell_Click(sender, e); 144 break; 145 } 146 } 147 } 148 }View Code
3、報表控制項DLL類庫部分
裡面有我們自定義的 條碼控制項、圖片控制項、圖表控制項
表格內自定義圖表控制項(曲線、柱狀、餅狀)源碼
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.Drawing; 5 using System.Drawing.Drawing2D; 6 using System.Drawing.Text; 7 8 namespace E_Report 9 { 10 /// <summary> 11 /// 圖表屬性 12 /// </summary> 13 /// <summary> 14 /// 報表圖表類庫 15 /// </summary> 16 public class EChart 17 { 18 #region 屬性方法 19 20 #region 臨時變數 21 22 /// <summary> 23 /// 臨時變數--關聯單元格行號 24 /// </summary> 25 private int _row = 0; 26 27 /// <summary> 28 /// 獲取--設置--關聯單元格行號 29 /// </summary> 30 public int Row 31 { 32 get { return _row; } 33 set { _row = value; } 34 } 35 36 /// <summary> 37 /// 臨時變數--關聯單元格列號 38 /// </summary> 39 private int _col = 0; 40 41 /// <summary> 42 /// 獲取--設置--關聯單元格列號 43 /// </summary> 44 public int Col 45 { 46 get { return _col; } 47 set { _col = value; } 48 } 49 50 /// <summary> 51 /// 數據來源 52 /// </summary> 53 private string _t_DataFrom = "數據源"; 54 55 /// <summary> 56 /// 獲取--設置--數據來源 57 /// </summary> 58 public string T_DataFrom 59 { 60 get { return _t_DataFrom; } 61 set { _t_DataFrom = value; } 62 } 63 64 /// <summary> 65 /// 數據源名稱 66 /// </summary> 67 private string _t_DsName = ""; 68 69 /// <summary> 70 /// 獲取--設置--數據源名稱 71 /// </summary> 72 public string T_DsName 73 { 74 get { return _t_DsName; } 75 set { _t_DsName = value; } 76 } 77 78 /// <summary> 79 /// 項目名稱 80 /// </summary> 81 private string _t_ItemName = ""; 82 83 /// <summary> 84 /// 獲取--設置--項目名稱 85 /// </summary> 86 public string T_ItemName 87 { 88 get { return _t_ItemName; } 89 set { _t_ItemName = value; } 90 } 91 92 /// <summary> 93 /// 項目數值 94 /// </summary> 95 private string _t_ItemValue = ""; 96 97 /// <summary> 98 /// 獲取--設置--項目數值 99 /// </summary> 100 public string T_ItemValue 101 { 102 get { return _t_ItemValue; } 103 set { _t_ItemValue = value; } 104 } 105 106 /// <summary> 107 /// X軸刻度 108 /// </summary> 109 private string _t_XScale = ""; 110 111 /// <summary> 112 /// 獲取--設置--X軸刻度 113