吳吳雙(溫州職業(yè)技術(shù)學(xué)院 教務(wù)處,浙江 溫州 325035)
DataGridView控件中數(shù)據(jù)導(dǎo)出至Excel方案的優(yōu)化與實(shí)現(xiàn)
吳吳雙
(溫州職業(yè)技術(shù)學(xué)院 教務(wù)處,浙江 溫州 325035)
DataGridView控件是信息化系統(tǒng)廣泛應(yīng)用的數(shù)據(jù)顯示控件,但并未提供與Excel文檔的交互功能.針對(duì)多種交互方法進(jìn)行分析,通過使用Excel組件和設(shè)置Range對(duì)象的屬性,大大提高數(shù)據(jù)交互效率和穩(wěn)定性;采用動(dòng)態(tài)添加控制右鍵菜單方式,對(duì)交互完成后的Excel文件導(dǎo)出操作方式進(jìn)行優(yōu)化.測(cè)試結(jié)果表明,優(yōu)化后控件的便捷性、移植性、美觀度和易用性得到了很大提升.
計(jì)算機(jī);DataGridView控件;Excel;信息化
隨著計(jì)算機(jī)技術(shù)的迅猛發(fā)展,信息化系統(tǒng)已無(wú)處不在,大規(guī)模信息化系統(tǒng)的運(yùn)行大多利用DataGridView控件展示數(shù)據(jù)信息,但原生DataGridView控件并未給用戶提供將數(shù)據(jù)導(dǎo)出至Excel軟件中進(jìn)行二次處理的功能.這使得用戶無(wú)法快捷地與Excel辦公軟件進(jìn)行交互,大大影響了工作效率和用戶體驗(yàn).DataGridView控件中數(shù)據(jù)導(dǎo)出至Excel的常用方法大致有直接復(fù)制法、逐行寫入法和系統(tǒng)剪切板整體寫入法三種方法.這三種方法均存在各自缺陷.本文比較分析三種方法的優(yōu)缺點(diǎn),提出DataGridView控件中數(shù)據(jù)導(dǎo)出至Excel功能集成,動(dòng)態(tài)添加控件右鍵菜單的優(yōu)化方案,解決了與Excel文檔的交互問題,提高了工作效率,改善了用戶體驗(yàn).
雖然微軟提供的DataGridView控件可以方便地顯示大量數(shù)據(jù),但不支持與Excel文檔的交互.將Data-GridView控件中數(shù)據(jù)導(dǎo)出至Excel的常用方法有直接復(fù)制法、逐行寫入法、系統(tǒng)剪切板整體寫入法.
1.1直接復(fù)制法
選中DataGridView控件中數(shù)據(jù)按CTRL+C鍵復(fù)制至系統(tǒng)剪切板中,再人工打開Excel軟件,再按CTRL+V鍵將剪切板中數(shù)據(jù)復(fù)制至Excel.該方法雖然能將數(shù)據(jù)復(fù)制至Excel文檔,但因字符集的不同,經(jīng)常會(huì)出現(xiàn)亂碼.
1.2逐行寫入法
利用COM組件集中的Excel組件建立一個(gè)Excel對(duì)象,由系統(tǒng)自動(dòng)對(duì)DataGridView控件中所有數(shù)據(jù)進(jìn)行循環(huán),逐行逐條將數(shù)據(jù)寫入Sheet中.該方法只能逐行逐條寫入數(shù)據(jù),導(dǎo)致工作效率低下,并且只能導(dǎo)出DataGridView控件中所有數(shù)據(jù),無(wú)法按用戶要求導(dǎo)出特定區(qū)域數(shù)據(jù),無(wú)法處理特殊字符和完成隱藏列的篩選,容易造成系統(tǒng)崩潰.
1.3系統(tǒng)剪切板整體寫入法
用戶可以將選定的內(nèi)容或整體數(shù)據(jù)一次性填入Windows系統(tǒng)剪切板中,再在已創(chuàng)建的Sheet中發(fā)送一個(gè)CTRL+V鍵盤命令,將系統(tǒng)剪切板中的數(shù)據(jù)一次性粘貼至Sheet中.采用該方法,當(dāng)系統(tǒng)發(fā)送鍵盤命令時(shí),如用戶改變系統(tǒng)焦點(diǎn),可能造成導(dǎo)出失敗.該方法存在的缺陷有:系統(tǒng)不能對(duì)Excel文檔進(jìn)行格式設(shè)置導(dǎo)致格式丟失;因Excel的表格特性將字符串前的0去掉,如原始數(shù)據(jù)為001,導(dǎo)出結(jié)果為1,造成數(shù)據(jù)錯(cuò)誤.
比較以上三種方法可知,系統(tǒng)剪切板整體寫入法效率最高,出錯(cuò)率最小.針對(duì)系統(tǒng)剪切板整體寫入法存在的缺陷提出優(yōu)化方案.
2.1方案優(yōu)化
2.1.1當(dāng)在系統(tǒng)發(fā)送鍵盤命令時(shí),用戶對(duì)系統(tǒng)進(jìn)行了其他操作,如改變系統(tǒng)焦點(diǎn),這時(shí)可能造成導(dǎo)出失敗,因而不采取模擬發(fā)送鍵盤的方法,而是采用Sheet.get_ Range("A1",System.Type.Missing)方法.該方法可以在粘貼數(shù)據(jù)前鎖定數(shù)據(jù)表的第一個(gè)單元格,避免因用戶操作丟失焦點(diǎn)而造成的導(dǎo)出失敗.
2.1.2采用Sheet.get_Range()方法設(shè)置文本格式.如當(dāng)導(dǎo)出至Excel時(shí)保留"001"樣式,核心代碼為:
range=xlBook.get_Range("A1","A+"+rowNum+"");
range.MergeCells=true;
range.NumberFormatLocal="@";
該設(shè)置可以格式化系統(tǒng)剪切板中內(nèi)容的格式,因而可以解決無(wú)法復(fù)制格式的問題.
2.1.3將原始數(shù)據(jù)格式進(jìn)行預(yù)處理,解決因Excel表格特性將字符串前的0去掉的問題和特殊格式及內(nèi)容出現(xiàn)亂碼的問題.其主要核心代碼[1]為:
if(DataGrid.Columns[i].ValueType.ToString()== "System.String")
{range=xlSheet.get_Range(xlApp.Cells[1,colIndex], xlApp.Cells[rowCount+1,colIndex]); range.NumberFormat="@"; }
預(yù)處理還可以對(duì)輸出文檔進(jìn)行格式設(shè)置,如表格邊框類型、粗細(xì)及內(nèi)容的對(duì)齊方式等.
2.1.4為進(jìn)一步提高導(dǎo)出效率,采用將所有原始數(shù)據(jù)保存于二維數(shù)組中.在此基礎(chǔ)上,將二維數(shù)組一次性交于Excel對(duì)象的range變量,再采用range.Value2方法同時(shí)寫入所有數(shù)據(jù).
2.1.5將列頭、邊框、字體、排列方式等屬性進(jìn)行設(shè)置,使導(dǎo)出的Excel文檔更美觀,同時(shí)大大減少后期對(duì)格式調(diào)整的工作量.
2.1.6為進(jìn)一步提高用戶體驗(yàn),將功能集成至控件右鍵菜單將是一個(gè)很好的方法.
2.2功能實(shí)現(xiàn)
以Visual Studio為開發(fā)環(huán)境,選擇C#編寫為設(shè)計(jì)語(yǔ)言.DataGridView控件中數(shù)據(jù)導(dǎo)出至Excel方案優(yōu)化流程如圖1所示.
圖1 DataGridView控件中數(shù)據(jù)導(dǎo)出至Excel方案優(yōu)化流程
2.2.1添加系統(tǒng)引用.在VS中實(shí)現(xiàn)與Excel文檔交互功能的有.net組件和.com組件,但實(shí)際應(yīng)用中.com組件會(huì)涉及到許多問題,如權(quán)限方面的問題,因而一般引用.net組件.其添加方法如下:一是打開VS2010,在右側(cè)的已安裝模板中,選擇Visual C#,右邊會(huì)顯示出各種項(xiàng)目類型,第一項(xiàng)就是Windows窗體應(yīng)用程序.二是在默認(rèn)狀態(tài)下,系統(tǒng)會(huì)自動(dòng)創(chuàng)建一個(gè)窗體程序,即主窗體程序,在右側(cè)解決方案中點(diǎn)擊新建好的窗體程序,選擇引用點(diǎn)擊右鍵,選擇.net組件,在組件列表中選擇Excel V11.0.0.0,點(diǎn)擊添加組件[2].
2.2.2系統(tǒng)進(jìn)程清理.在實(shí)現(xiàn)與Office文檔交互功能時(shí)最容易出現(xiàn)的問題是,操作界面上已全部關(guān)閉Office文檔,卻在系統(tǒng)進(jìn)程中殘留Excel進(jìn)程,這樣將導(dǎo)致系統(tǒng)錯(cuò)誤.因此,在打開Excel之前一定要進(jìn)行一次進(jìn)程清理.C#中使用"User32.dll"實(shí)現(xiàn)清理殘留Office進(jìn)程.在調(diào)用"User32.dll"時(shí)要使用DllImport實(shí)現(xiàn)調(diào)用.DllImport的命名空間是System.Runtime.InteropServices,是該命名空間下的一個(gè)屬性類,Dll-Import提供從非托管DLL導(dǎo)出函數(shù)的必要調(diào)用信息.其添加方法[3]如下:雙擊打開窗體程序即可進(jìn)入代碼編輯模式,輸入[DllImport("User32.dll",CharSet=Char-Set.Auto)]public static extern int GetWindow-ThreadProcessId(IntPtr hwnd, out int ID).在得到Excel進(jìn)行ID時(shí)要特別注意一定要定義為靜態(tài)方法,否則無(wú)法得到進(jìn)程ID.
2.2.3對(duì)Excel 2003與Excel 2007不同版本進(jìn)行兼容性及對(duì)隱藏行、列處理.
Excel 2003的最大行是65 536行,最大列數(shù)是256列;Excel 2007的最大行是1 048 576,最大列數(shù)是16 384列.對(duì)行、列進(jìn)行處理的代碼為:
if(DataGrid.Rows.Count > 65536 || DataGrid. ColumnCount>256)
{return false;}//判斷數(shù)據(jù)表中數(shù)據(jù)量是否大于65 536行或大于256列
2.2.4創(chuàng)建Excel對(duì)象、Workbook、Sheet工作表及設(shè)置Range對(duì)象.
(1)利用引用的Excel V11.0.0.0組件創(chuàng)建Excel Application對(duì)象,表示Excel應(yīng)用程序本身.Application對(duì)象引用方法如下:Microsoft.Office.Interop.Excel.Application ExcelApplication=new Microsoft.Office.Interop.Excel.Application();
(2)創(chuàng)建Workbook、Sheet表.Workbook對(duì)象表示Excel應(yīng)用程序內(nèi)的單個(gè)工作簿,同時(shí)Excel提供一個(gè)Sheets集合作為Workbook對(duì)象的屬性.其核心代碼[4]如下:ExcelobjWorkbook=ExcelobjExcel.Application. Workbooks.Open(ExcelFileName,miss,miss,miss,miss, miss,miss,miss,miss,miss,miss,miss,miss,miss, miss).
(3)設(shè)置Range對(duì)象.Range對(duì)象表示一個(gè)單元格、一行、一列,包含一個(gè)或多個(gè)單元格塊(可以連續(xù),也可以不連續(xù))的單元格選定范圍,甚至多個(gè)Sheet表中的一組單元格.其方法如下:
Microsoft.Office.Interop.Excel.Range range;
(處理隱藏行)range.EntireRow.Hidden=true;
(設(shè)置內(nèi)容對(duì)齊方式)RowAll.HorizontalAlignment=Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
(設(shè)置文字大小)RowAll.Font.Size=8;
(設(shè)置邊框樣式)RowAll.Borders.LineStyle=Microsoft.Office.Interop.Excel.XlLineStyle.xlContinuous;
(設(shè)置為表頭加粗)range.Font.Bold=true.
2.2.5原始數(shù)據(jù)預(yù)處理.將原始數(shù)據(jù)格式進(jìn)行預(yù)處理,主要是對(duì)數(shù)據(jù)格式,隱藏列、行進(jìn)行處理,以及調(diào)整數(shù)據(jù)緩存并寫入緩存,為下一步提高整體寫入Exc el做好準(zhǔn)備.其核心代碼如下:
if(DataGrid.Columns[i].ValueType.ToString() =="System.String")
range.NumberFormat="@";
上下合并實(shí)現(xiàn),如選擇A1和A2兩個(gè)單位格,合并,設(shè)值.其實(shí)現(xiàn)代碼為:
range=wooksheet.get_Range(ExcelApp.Cells[1, 2],ExcelApp.Cells[1,3]);range.Merge(true);range. Value2="合并后需要顯示的名稱";
2.2.6寫入Excel及Excel格式設(shè)置.該步驟是對(duì)已預(yù)處理好的數(shù)據(jù)一次性寫入已創(chuàng)建的Excel表中,同時(shí)完成預(yù)設(shè)表的排版樣式.其核心代碼為:
range=xlSheet.get_Range(xlApp.Cells[1,1]//從表格第一行第一列開始,
xlApp.Cells[rowCount+1,colCount])//表格最后一行最后一列結(jié)束;
xlBook.Saved=true;xlBook.SaveCopyAs(fullFileName);ExportSuccess=true;}
(如保存成功返回ture,如有發(fā)現(xiàn)異常返回flash) catch{ExportSuccess=false;}
2.2.7Excel進(jìn)程處理及釋放資源.為提高程序的高效和簡(jiǎn)潔性,適時(shí)地進(jìn)行釋放資源是必要的,這也是優(yōu)質(zhì)程序的必備條件.采用查找P I D的方法對(duì)已使用的Excel進(jìn)程進(jìn)行清理,而不采用進(jìn)程名的方法進(jìn)行清理,這樣可以有效避免用戶誤操作其他作業(yè)進(jìn)程.其核心代碼[5]為:
xlApp.Quit();GetWindowThreadProcessId(t,out id);
System.Diagnostics.Process p=System.Diagnostics. Process.GetProcessById(id);
p.Kill();
2.2.8右鍵快捷菜單集成.采用動(dòng)態(tài)添加菜單的方式生成菜單,可以大大提升控件便捷性、移植性、美觀度,使用戶獲得更好的體驗(yàn).
(1)新建菜單方法.
private void AddContextMenu()
{//實(shí)例化右鍵菜單
this.BozhaiContextMenu=new ContextMenu-Strip();
this.輸出到Excel文件ToolStripMenuItem=new ToolStripMenuItem();
this.輸出到Excel文件ToolStripMenuItem.Name= "輸出到Excel文件ToolStripMenuItem";}
(2)綁定Click事件.
this.輸出到Excel文件ToolStripMenuItem.Click+= new EventHandler(this.OutputFileToExcel);
(3)建立輸出到Excel文件的方法.
public void SaveAsFileToExcel(object sender, System.EventArgs e)
{if(this.ColumnCount==0||this.RowCount==0) {MessageBox.Show("沒有可保存的數(shù)據(jù)!","系統(tǒng)提示", MessageBoxButtons.OK,MessageBoxIcon.Information); return;}
SaveFileDialog SF=new SaveFileDialog();
SF.Filter="Microsoft Excel電子文檔(*.xls)|*. xls";
if(SF.ShowDialog()==DialogResult.OK)
{this.Cursor=Cursors.WaitCursor;
DataGridViewOperation.OutputOperate OO=new DataGridViewOperation.OutputOperate();
OO.OutputFileToExcel(this,SF.FileName, false); GC.Collect();
this.Cursor=Cursors.Default;}}
完成右鍵菜單綁定后,就可以用鼠標(biāo)在控件上點(diǎn)擊右鍵,在彈出的菜單中選擇輸出到Excel文件.在提示中選擇要保存的路徑后點(diǎn)擊確定就能快捷地完成數(shù)據(jù)導(dǎo)出.DataGridView控件中數(shù)據(jù)導(dǎo)出至Excel優(yōu)化方案運(yùn)行界面如圖2所示.
圖2 DataGridView控件中數(shù)據(jù)導(dǎo)出至Excel優(yōu)化方案運(yùn)行界面
將DataGridView控件中數(shù)據(jù)導(dǎo)出至Excel的三種方法及其優(yōu)化方案同時(shí)用于溫州職業(yè)技術(shù)學(xué)院的人事管理系統(tǒng)、督導(dǎo)管理系統(tǒng)、資產(chǎn)管理系統(tǒng),測(cè)試模塊為在不通知情況下由全院教職工使用,經(jīng)一學(xué)期實(shí)際應(yīng)用后進(jìn)行用戶回訪,共回訪50人次.測(cè)試結(jié)果表明,導(dǎo)出至Excel的三種方法未經(jīng)優(yōu)化前好評(píng)率為10%,優(yōu)化后好評(píng)率為88%.
對(duì)DataGridView控件中數(shù)據(jù)導(dǎo)出至Excel三種方法進(jìn)行比較分析,吸取不同方法的優(yōu)點(diǎn),引入數(shù)據(jù)緩存的方法,提高了寫入效率和減少差錯(cuò)率;為進(jìn)一步提高控件的便捷性、移植性、美觀度,動(dòng)態(tài)添加控件右鍵菜單,大大提高了工作效率,改善了用戶體驗(yàn).
[1]CHRISTIAN N,EVJEN B,GLYNN J,等.C#高級(jí)編程(IX)[M].李銘,譯.北京:清華大學(xué)出版社,2014:120-123.
[2]李立功,祖曉東.SQL Server 2008項(xiàng)目開發(fā)教程(I)[M].北京:電子工業(yè)出版社,2010:42-46.
[3]c#的dllimport使用方法[EB/OL].(2008-06-31)[2016-02-15].http://www.jb51.net/article/46384.htm.
[4]丁士鋒,蔡平.ASP.NET項(xiàng)目開發(fā)指南[M].北京:清華大學(xué)出版社,2013:79-182.
[5]Microsoft.Office.Interop.Excel API應(yīng)用(二)Workbook[EB/OL].(2012-06-01)[2016-02-15]. http://blog.csdn.net/yimeng_1985/article/details/7623638.
[責(zé)任編輯:王志梅]
Optimizing and Implementing the Method of Deriving Data to Excel in DataGridView Control
WU Shuang
(Teaching Affairs Department, Wenzhou Vocational & Technical College, Wenzhou, 325035, China)
DataGridView Control is a data display control widely used in information system, but it can't interact with Excel documents. Analysis has been done on various interactive methods. By using Excel components and fixing the property of Range object, data interactive efficiency and stability are greatly improved. In addition, dynamic addition is used to control right key menu in order to optimize the Excel document deriving process after interaction comes to an end. Testing findings demonstrate that the optimized control is greatly improved in terms of its convenience, portability, presentation, and being easy to use.
Computers; DataGridView control; Excel; Informationization
TP317
A
1671-4326(2016)02-0068-04
10.13669/j.cnki.33-1276/z.2016.042
2016-02-29
溫州職業(yè)技術(shù)學(xué)院科研項(xiàng)目(WZY2015012)
吳雙(1981-),男,浙江溫州人,溫州職業(yè)技術(shù)學(xué)院教務(wù)處,助理實(shí)驗(yàn)師.
溫州職業(yè)技術(shù)學(xué)院學(xué)報(bào)2016年2期