使用Office Interop将单元格写入Excel的最快方法?

时间:2010-06-22 18:38:04

标签: vb.net performance excel com office-interop

我正在编写一个函数,使用VB .NET中的Office Interop将数据导出到Excel。我目前正在使用Excel工作表的Cells()方法直接编写单元格:

worksheet.Cells(rowIndex, colIndex) = data(rowIndex)(colIndex)

这需要很长时间才能处理大量数据。是否有更快的方法可以立即将大量数据写入Excel?用范围做某事会更快吗?

6 个答案:

答案 0 :(得分:29)

如果可以的话,你应该避免逐个单元地读写。使用数组并一次读取或写入整个块更快。我在reading from worksheets using C#上写了一篇帖子;基本上,相同的代码以相反的方式工作(见下文),并且运行得更快,尤其是对于更大的数据块。

  var sheet = (Worksheet)Application.ActiveSheet;
  var range = sheet.get_Range("A1", "B2");
  var data = new string[3,3];
  data[0, 0] = "A1";
  data[0, 1] = "B1";
  data[1, 0] = "A2";
  data[1, 1] = "B2";
  range.Value2 = data;

答案 1 :(得分:10)

如果您还没有,请确保在开始输出数据之前设置Application.ScreenUpdating = false。这将使事情变得更快。完成输出数据后,将其设置为True。必须在每个单元格上重绘屏幕需要花费很多时间,绕过这可以节省时间。

至于使用范围,您仍然需要将1(一)个特定单元格作为值,因此我认为这里没有任何好处。我不知道这样做比你在实际输出数据方面做得更快。

答案 2 :(得分:5)

只是为了补充Tommy的答案。

  • 您可能还希望在开始编写之前将计算设置为手动。
  

Application.Calculation =   xlCalculationManual

当你完成写作后,将其设置为自动。 (如果原始模式可能不是自动模式,则必须在将其设置为手动之前存储该值)

  

Application.Calculation =   xlCalculationAutomatic

  • 您还可以使用Range对象的CopyFromRecordset方法。

http://msdn.microsoft.com/de-de/library/microsoft.office.interop.excel.range.copyfromrecordset(office.11).aspx

答案 3 :(得分:3)

从excel范围写入和读取值的最快方法是Range.get_ValueRange.set_Value

方法如下:

Range filledRange = Worksheet.get_Range("A1:Z678",Missing);
object[,] rngval = (object[,]) filledRange.get_Value (XlRangeValueDataType.xlRangeValueDefault);

Range Destination = Worksheet2.get_Range("A1:Z678",Missing);
destination.set_Value(Missing,rngval);

是的,不需要迭代。表现真是太棒了!!

希望它有所帮助!!

答案 4 :(得分:2)

老实说,编写它的最快方法是使用逗号分隔符。使用Join(“,”)。ToString方法编写一行字段更容易,而不是尝试迭代单元格。然后将文件另存为“.csv”。使用interop,将文件作为csv打开,它将在打开时自动为您更新单元格。

答案 5 :(得分:0)

如果有其他人像我这样使用@Mathias提供的方法(这似乎是加载到Excel中最快的方法)来寻找一个完整的解决方案,请参阅@ IMil对阵列的建议。
你走了:

'dt (DataTable) is the already populated DataTable
'myExcelWorksheet (Worksheet) is the worksheet we are populating
'rowNum (Integer) is the row we want to start from (usually 1)
Dim misValue As Object = System.Reflection.Missing.Value
Dim arr As Object = DataTableToArray(dt)
'Char 65 is the letter "A"
Dim RangeTopLeft As String = Convert.ToChar(65 + 0).ToString() + rowNum.ToString()
Dim RangeBottomRight As String = Convert.ToChar(65 + dt.Columns.Count - 1).ToString() + (rowNum + dt.Rows.Count - 1).ToString()
Dim Range As String = RangeTopLeft + ":" + RangeBottomRight
myExcelWorksheet.Range(Range, misValue).NumberFormat = "@" 'Include this line to format all cells as type "Text" (optional step)
'Assign to the worksheet
myExcelWorksheet.Range(Range, misValue).Value2 = arr

然后

Function DataTableToArray(dt As DataTable) As Object
    Dim arr As Object = Array.CreateInstance(GetType(Object), New Integer() {dt.Rows.Count, dt.Columns.Count})
    For nRow As Integer = 0 To dt.Rows.Count - 1
        For nCol As Integer = 0 To dt.Columns.Count - 1
            arr(nRow, nCol) = dt.Rows(nRow).Item(nCol).ToString()
        Next
    Next
    Return arr
End Function

限制包括仅允许26列才需要更好的代码来提供范围值字母。