将DataTable复制到Excel

时间:2014-08-26 18:20:47

标签: c# datatable

我有一个大小为m x n的DataTable,并希望将所有内容(包括列标题)复制到已打开的excel文件中。我有对Excel.WorkBook的引用,并且知道将数据复制到哪个WorkSheet。

我知道最简单(最脏的方式)是:

Excel.WorkSheet outSheet; //set to desired worksheet
int rowIdx = 1;
int colIdx = 1;
//add header row
foreach (DataColumn dc in dt.Columns)
{
    outSheet.Cells[rowIdx, colIdx++] = dc.ColumnName;
}

colIdx = 1; //reset to Cell 1

//add rest of rows
foreach (DataRow dr in dt.Rows)
{
    colIdx = 0;
    foreach (DataColumn dc in dt.Columns)
    {
        outSheet.Cells[rowIdx + 1, colIdx + 1] = dr[colIdx].ToString();
        colIdx++;
    }
    rowIdx++;
}

这样可行但不幸的是,由于需要逐个单元地访问和粘贴数据,因此会产生巨大的时间成本。有没有更好的方法来实现这一目标?

1 个答案:

答案 0 :(得分:3)

我为你写了一个小例子。 tl; dr 您可以将值数组分配给Excel范围。但是这个必须满足一些规范。积分转到Eric Carter

    Stopwatch sw = new Stopwatch();
    sw.Start();
    Application xlApp = new Application();
    Workbook xlBook = xlApp.Workbooks.Open(@"E:\Temp\StackOverflow\COM_Interop_CS\bin\Debug\demo.xlsx");
    Worksheet wrkSheet = xlBook.Worksheets[1];            

    try
    {
        /// credits go to: 
        /// http://blogs.msdn.com/b/eric_carter/archive/2004/05/04/126190.aspx
        /// 
        /// [cite] when you want to set a range of values to an array, you must declare that array as a 2 
        /// dimensional array where the left-most dimension is the number of rows you are going to set and 
        /// the right-most dimension is the number of columns you are going to set.  
        /// 
        /// Even if you are just setting one column, you can’t create a 1 dimensional array and have it work[/cite]

        Excel.Range range = wrkSheet.Range["A1", "Z100000"];
        int maxRows = 100000, maxCols = 26;
        object[,] values = new object[maxRows, maxCols];

        int counter = 0;
        for (int row = 0; row < maxRows; row++)
        {
            for (int col = 0; col < maxCols; col++)
            {
                values[row, col] = counter++;
            }
        }
        range.Value2 = values;                
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
    xlApp.Visible = true;
    sw.Stop();
    Console.WriteLine("Elapsed: {0}", sw.Elapsed);

我在不到10秒的时间内添加了100.000行和26列。我希望这适合你!