C#開源組件NPOI處理Excel導入DataTable數據至Sheet

作爲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;
    }
}

以上示例親測通過。關於單元格格式,還可以增加一個標題格式(列名格式處理),這個處理沒有問題吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章