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

以上示例亲测通过。关于单元格格式,还可以增加一个标题格式(列名格式处理),这个处理没有问题吧。

posted @ 2020-05-14 10:25  老瓷  阅读(695)  评论(0编辑  收藏  举报