C#實現快速將數據寫入Excel單元格
性能問題
將生成或查詢到的數據,導出到 Excel 是應用中常用的一項功能。其中一些標準的寫入單元格的方法如下:
Worksheet worksheet = (Worksheet) excel.Worksheets[1]; //引用坐標對Cells集合進行寫入 worksheet.Cells[1, 1] = "test"; //還可以引用地址進行寫入 worksheet.Cells["A1",Type.Missing]="test";
請注意,office 元素大多的起始序號均從 1 開始,而不是 0,如 worksheet,cells等。
現在我們假設有二維數組 object[,] dataobj ,遍歷式的寫法如下:
int arraywidth=dataobj.GetLength(1); int arrayheight=dataobj.GetLength(0); Worksheet worksheet = (Worksheet) excel.Worksheets[1]; for(int j=0;j<arrayheight;j++) { for(int k=0;k<arraywidth;k++) { worksheet.Cells[j+1,k+1]=dataobj[j,k]; }//end columns }// end rows
此種寫法在數據較少的時候在寫入速度方面沒有明顯差異,但當大數據量的情況,多次的讀寫CELL單元格 IO 是一項非常耗時的操作,甚至會無法完成應用的預期目標。
Excel元素結構及寫入原理
元素結構如下圖:
其中Range對象,代表了Excel單元格集合的指定區(qū)域。
如圖選中的Range范圍起始的單元格是第5行第3列,結束于第17行第8列。它相當于object[13,6] 的一個二維數組,Excel的Range提供了get_Resize方法并通過Value2可以一次性的設置它們。
范例運行環(huán)境
操作系統: Windows Server 2019 DataCenter
操作系統上安裝 Office Excel 2016
.net版本: .netFramework4.7.1 或以上
開發(fā)工具:VS2019 C#
配置Office DCOM
配置方法可參照我的文章《C#實現讀取Word表格到DataSet》進行處理和配置。
實現代碼
組件庫引入
核心代碼
WriteArrayToExcel
public void WriteArrayToExcel(object[,] dataobj,ExcelApplication excel,int ActiveSheetId,int StartRowId,int StartColId),該方法參數說明見下表:
序號 | 參數 | 說明 |
1 | object[,] dataobj | 傳遞要寫入的二維對象數組 |
2 | ExcelApplication excel | 表示Excel應用程序對象 |
3 | int ActiveSheetId | 指定要寫入哪個工作ID,ID從1開始 |
4 | int StartRowId | 指定要寫入的開始行ID,ID從1開始 |
5 | int StartColId | 指定要寫入的開始列ID,ID從1開始 |
示例代碼如下:
public void WriteArrayToExcel(object[,] dataobj,ExcelApplication excel,int ActiveSheetId,int StartRowId,int StartColId) { Excel.Range _range; int arraywidth=dataobj.GetLength(1); int arrayheight=dataobj.GetLength(0); Worksheet worksheet = (Worksheet) excel.Worksheets[ActiveSheetId]; worksheet.Activate(); _range=excel.Range[excel.Cells[StartRowId,StartColId],excel.Cells[StartRowId+arrayheight-1,StartColId+arraywidth-1]]; _range.get_Resize(arrayheight,arraywidth); _range.Value2=dataobj; } //end writearraytoexcel
神奇的 911 事件
在 Excel 的早期版本(如Excel 2003)寫入的時,我們發(fā)現了一個現象,每寫入第 911個單元格的時候,且第911個單元數據為字符串類型的時候,會出現無響應的情況。當時的解決方案是將原始數組的每911元素值進行備份,并設置為空字符串,然后再對Cells單元格進行重寫,修改后的代碼如下:
public void WriteArrayToExcel(object[,] dataobj,ExcelApplication excel,int ActiveSheetId,int StartRowId,int StartColId) { Excel.Range _range; int arraywidth=dataobj.GetLength(1); int arrayheight=dataobj.GetLength(0); Worksheet worksheet = (Worksheet) excel.Worksheets[ActiveSheetId]; worksheet.Activate(); ArrayList ex_x = new ArrayList(); ArrayList ex_y = new ArrayList(); ArrayList ex_value = new ArrayList(); object _fvalue=""; int _maxlen=910; for(int j=0;j<arrayheight;j++) { for(int k=0;k<arraywidth;k++) { _fvalue=dataobj[j,k];// field value //備份每個第911個單元數據 if(_fvalue.GetType().ToString()=="System.String") { if(((string)_fvalue).Length>_maxlen) { ex_x.Add(j+StartRowId); ex_y.Add(k+StartColId); ex_value.Add(_fvalue); _fvalue=""; }// end maxlen } dataobj[j,k]=_fvalue; }//end columns }// end rows _range=excel.Range[excel.Cells[StartRowId,StartColId],excel.Cells[StartRowId+arrayheight-1,StartColId+arraywidth-1]]; _range.get_Resize(arrayheight,arraywidth); _range.Value2=dataobj; //恢復重寫對應的單元格 for(int j=0;j<ex_value.Count;j++) { excel.Cells[ex_x[j],ex_y[j]]=ex_value[j].ToString(); } } //end writearraytoexcel
小結
1、911單元格處理的方法是一種兼容性寫法,我們可以根據安裝的版本來決定是否需要這種寫法。
2、核心方法中輸入的起始行列,可以修改為更加直觀的CELL地址,如“A1”,"B5"等,有助于客戶進行應用,提升友好性。
3、我們還可以改造傳遞二維數組集合,寫入多個worksheet,滿足更多需求,提升應用程序的功能。
以上就是C#實現快速將數據寫入Excel單元格的詳細內容,更多關于C#數據寫入Excel的資料請關注腳本之家其它相關文章!
相關文章
C#使?XmlReader和XmlWriter操作XML?件
這篇文章介紹了C#使?XmlReader和XmlWriter操作XML?件的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06C#中BitConverter.ToUInt16()和BitConverter.ToString()的簡單使用
這篇文章主要介紹了C#中BitConverter.ToUInt16()和BitConverter.ToString()的簡單使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-02-02