作爲C#處理Excel的強大的開源組件,NPOI具有Office Excel的絕大部分功能,與收費的Spire比雖有不足,但對於一般性的處理來說還是基本夠用,這也是NPOI至今仍作爲衆多C#堆碼人員的選擇的原因。
收費軟件能夠提供更多的功能給用戶,這也是它的賣點。Spire的DataTable數據導入,就是NPOI所不具備的,而導入DataTable數據,對於C#來說是經常遇到的,所以NPOI用起來雖然也能夠想辦法處理,卻沒有那麼方便。
下面的代碼,仿照Spire的DataTable數據導入,提供大家一個參照。
/// <summary> /// NPOI把DataTable的數據寫入到指定的Sheet中 /// </summary> /// <param name="sourceData">要寫入的數據表</param> /// <param name="sheet">當前要寫入的Sheet</param> /// <param name="rowStart">當前要寫入的Sheet的起始行號(行計數從1起)</param> /// <param name="colStart">當前要寫入的Sheet的起始列號(列計數從1起)</param> /// <param name="IsWriteColumnName">DataTable的列名稱是否寫入Sheet</param> /// <param name="cellStyle">單元格格式</param> /// <returns>返回標題行數和寫入的錶行數的合計</returns> private int DataTableToSheet_NPOI(DataTable sourceData, ISheet sheet, int rowStart, int colStart, bool IsWriteColumnName, ICellStyle cellStyle = null) { //Sheet的總行數 int WriteRowCount = rowStart - 1; //已有行數,同時爲新行號(NPOI計數從0起) ICell cell; //是否寫入列名,則寫入DataTable的列名,已有行後的下一行寫入列名 if (IsWriteColumnName) { //sheet表創建新的一行,即已有行後的第一行 IRow ColumnNameRow = sheet.CreateRow(WriteRowCount); //進行寫入DataTable的列名 for (int colunmNameIndex = 0; colunmNameIndex < sourceData.Columns.Count; colunmNameIndex++) { cell = ColumnNameRow.CreateCell(colStart - 1 + colunmNameIndex); cell.SetCellValue(sourceData.Columns[colunmNameIndex].ColumnName.ToString()); SetValue(cell, sourceData.Columns[colunmNameIndex].ColumnName); if (cellStyle != null) cell.CellStyle = cellStyle; } WriteRowCount++; } //寫入數據 for (int row = 0; row < sourceData.Rows.Count; row++) { //sheet表創建新的一行 IRow newRow = sheet.CreateRow(WriteRowCount); for (int column = 0; column < sourceData.Columns.Count; column++) { cell = newRow.CreateCell(colStart - 1 + column); SetValue(cell, sourceData.Rows[row][column]); if (cellStyle != null) cell.CellStyle = cellStyle; } WriteRowCount++; //下一行號 } return WriteRowCount; }
private void SetValue(ICell cell,object value) { Type type = value.GetType(); switch (type.Name) { case "Boolean": cell.SetCellValue((bool)value); break; case "String": cell.SetCellValue(value.ToString()); break; case "DateTime": cell.SetCellValue((DateTime)value); break; case "Int32": cell.SetCellValue((int)value); break; case "Single": cell.SetCellValue((double)value); break; case "Double": cell.SetCellValue((double)value); break; default: cell.SetCellValue(value.ToString()); break; } }
以上示例親測通過。關於單元格格式,還可以增加一個標題格式(列名格式處理),這個處理沒有問題吧。