作为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; } }
以上示例亲测通过。关于单元格格式,还可以增加一个标题格式(列名格式处理),这个处理没有问题吧。