2009-02-11 55 views
45

我目前正在试图从对象的数组在Excel中的一个范围内使用下面的代码,其中objData只是一个字符串数组写入数据:写入阵列到Excel范围

private object m = System.Type.Missing; 
object[] objData = getDataIWantToWrite(); 

Range rn_Temp; 
rn_Temp = (Range)XlApp.get_Range(RangeName, m); 
rn_Temp = rn_Temp.get_Resize(objData.GetUpperBound(), 1); 
rn_Temp.value2 = objData; 

这非常接近工作,问题是范围被填充,但每个单元格获得objData中第一项的值。

逆工程,即

private object m = System.Type.Missing; 
object[] objData = new object[x,y] 

Range rn_Temp; 
rn_Temp = (Range)XlApp.get_Range(RangeName, m); 
rn_Temp = rn_Temp.get_Resize(objData.GetUpperBound(), 1); 
objData = (object[])rn_Temp.value2; 

会返回一个包含所有从表中的数据的数组,所以我不知道为什么是阅读和分配工作方式不同。

有没有人曾经成功做过这件事?我目前正在按单元格编写数组,但它需要处理大量(> 50,000个)行,因此非常耗时。

+7

选定的答案并不能使它立即明显,所以如果别人永远有这个问题,总之,解决的办法是即使您的数据仅适用于一个维度,也需要分配二维数组(即“对象[,]”)。 – zneak 2012-05-17 15:19:20

+1

[非常有用](http://blogs.msdn.com/b/eric_carter/archive/2004/05/04/126190.aspx) – 2014-03-10 16:41:41

回答

77

这是我的方法摘录,它将DataTable(dt变量)转换为数组,然后将数组写入工作表(wsh var)中的Range。您还可以将topRow变量更改为您希望放置字符串数组的任何行。

 object[,] arr = new object[dt.Rows.Count, dt.Columns.Count]; 
     for (int r = 0; r < dt.Rows.Count; r++) 
     { 
      DataRow dr = dt.Rows[r]; 
      for (int c = 0; c < dt.Columns.Count; c++) 
      { 
       arr[r, c] = dr[c]; 
      } 
     } 

     Excel.Range c1 = (Excel.Range)wsh.Cells[topRow, 1]; 
     Excel.Range c2 = (Excel.Range)wsh.Cells[topRow + dt.Rows.Count - 1, dt.Columns.Count]; 
     Excel.Range range = wsh.get_Range(c1, c2); 

     range.Value = arr; 

当然你不需要像我一样使用一个中间数据表,代码摘录只是为了演示一个数组如何被写入单个调用到工作表。

4

您可以将数据放入记录集并使用Excel's CopyFromRecordset Method - 它比填充单元格要快得多。

您可以使用this code从数据集创建记录集。你将不得不做一些试验,看看使用这种方法是否比你现在正在做的更快。

+0

这可能是一个愚蠢的问题,但我在哪里可以找到一个C#中的Recordset类?或者你是否知道是否还有其他课程可以通过?非常感谢! – 2009-02-11 13:12:41

+1

添加对程序集ADODB 7.0.3300.0版的引用。使用ADODB; ADODB有类型“记录集” – 2013-09-05 10:32:57

9

感谢指针家伙 - Value vs Value2的参数让我获得了一组不同的搜索结果,帮助我意识到答案是什么。顺便提一下,Value属性是一个参数化属性,必须通过C#中的访问器访问。这些被称为get_Value和set_Value,并采取一个可选的枚举值。如果任何人有兴趣,this explains it nicely

但是,可以通过Value2属性进行赋值,这是因为互操作性文档建议不要使用get_Value和set_Value方法,因为我理解的原因,这是可取的。

该键似乎是对象数组的维数。对于调用工作,必须将数组声明为二维,即使您只分配一维数据。

我宣布我的数据数组为object[NumberofRows,1],并且调用工作正常。

0

出于某种原因,转换为2维数组不适用于我。但是,下面的方法做:

public void SetRow(Range range, string[] data) 
{ 
    range.get_Resize(1, data.Length).Value2 = data; 
} 
1

那种数组定义的似乎是关键: 对我来说,它是17项的一维数组,它必须转换为二维数组

确定指标的列: object [,] Array = new object [17,1];

定义行 object [,] Array = new object [1,17];

value2的代码在两种情况下都是相同的 Excel.Range cell = activeWorksheet.get_Range(Range); cell.Value2 = Array;

LG Georg

1

在我的情况下,程序查询返回DataGridView的数据库。然后我将它复制到一个数组中。我得到刚刚创建的数组的大小,然后将数组写入Excel电子表格。该代码在大约两秒内输出5000行数据。

//private System.Windows.Forms.DataGridView dgvResults; 
dgvResults.DataSource = DB.getReport(); 

Microsoft.Office.Interop.Excel.Application oXL; 
Microsoft.Office.Interop.Excel._Workbook oWB; 
Microsoft.Office.Interop.Excel._Worksheet oSheet; 
try 
{ 
    //Start Excel and get Application object. 
    oXL = new Microsoft.Office.Interop.Excel.Application(); 
    oXL.Visible = true; 

    oWB = (Microsoft.Office.Interop.Excel._Workbook)(oXL.Workbooks.Add("")); 
    oSheet = (Microsoft.Office.Interop.Excel._Worksheet)oWB.ActiveSheet; 

    var dgArray = new object[dgvResults.RowCount, dgvResults.ColumnCount+1]; 
    foreach (DataGridViewRow i in dgvResults.Rows) 
    { 
     if (i.IsNewRow) continue; 
     foreach (DataGridViewCell j in i.Cells) 
     { 
      dgArray[j.RowIndex, j.ColumnIndex] = j.Value.ToString(); 
     } 
    } 

    Microsoft.Office.Interop.Excel.Range chartRange; 

    int rowCount = dgArray.GetLength(0); 
    int columnCount = dgArray.GetLength(1); 
    chartRange = (Microsoft.Office.Interop.Excel.Range)oSheet.Cells[2, 1]; //I have header info on row 1, so start row 2 
    chartRange = chartRange.get_Resize(rowCount, columnCount); 
    chartRange.set_Value(Microsoft.Office.Interop.Excel.XlRangeValueDataType.xlRangeValueDefault, dgArray); 


    oXL.Visible = false; 
    oXL.UserControl = false; 
    string outputFile = "Output_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx"; 

    oWB.SaveAs("c:\\temp\\"+outputFile, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing, 
     false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, 
     Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); 

    oWB.Close(); 
} 
catch (Exception ex) 
{ 
    //... 
} 
0

当要写入的Excel工作表一维数组你必须调换它不必创建一个二维数组用1柱([N,1])作为我上面阅读!这里是一个代码示例:

wSheet.Cells(RowIndex, colIndex).Resize(RowsCount,).Value = _excel.Application.transpose(My1DArray) 

日子过好, 吉尔斯