如何使用 Visual C# 2005 或 Visual C# .NET 将数据传输到 Excel 工作簿

有关本文的 Microsoft Visual Basic 6.0 版本,请 参阅247412

本分步文章介绍从 Microsoft Visual C# 2005 或 Microsoft Visual C# .NET 程序将数据传输到 Microsoft Excel 2002 的几种方法。 本文还介绍了每个方法的优缺点,以便你可以选择最适合你的情况的解决方案。

概述

最常用于将数据传输到 Excel 工作簿的技术是自动化。 通过自动化,可以调用特定于 Excel 任务的方法和属性。 自动化为你在工作簿中指定数据的位置、设置工作簿的格式以及在运行时设置各种设置提供了最大的灵活性。

借助自动化,可以使用多种技术来传输数据:

  • 按单元格传输数据单元格。
  • 将数组中的数据传输到一系列单元格。
  • 使用 CopyFromRecordset 方法将 ADO 记录集中的数据传输到单元格区域。
  • 在 Excel 工作表上创建一个 QueryTable 对象,其中包含对 ODBC 或 OLEDB 数据源的查询结果。
  • 将数据传输到剪贴板,然后将剪贴板内容粘贴到 Excel 工作表中。
    还可以使用不一定要求自动化将数据传输到 Excel 的几种方法。 如果运行的是服务器端程序,则这是一种将大量数据处理从客户端中移开的好方法。

若要在没有自动化的情况下传输数据,可以使用以下方法:

  • 将数据传输到选项卡分隔或逗号分隔的文本文件,Excel 稍后可以分析到工作表上的单元格中。
  • 使用 ADO.NET 将数据传输到工作表。
  • 将 XML 数据传输到 Excel (版本 2002 和 2003) ,以提供格式化并排列成行和列的数据。

本文提供每种技术的讨论和代码示例。 本文后面的“创建完整的示例 Visual C# 2005 或 Visual C# .NET 项目”部分演示如何创建执行每种技术的 Visual C# .NET 程序。

技术

使用自动化按单元格传输数据单元格

使用自动化,可以一次将数据传输到一个单元格的工作表:

// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));

// Add data to cells in the first worksheet in the new workbook.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objRange.Value = "Last Name";
m_objRange = m_objSheet.get_Range("B1", m_objOpt);
m_objRange.Value = "First Name";
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange.Value = "Doe";
m_objRange = m_objSheet.get_Range("B2", m_objOpt);
m_objRange.Value = "John";

// Apply bold to cells A1:B1.
m_objRange = m_objSheet.get_Range("A1", "B1");
m_objFont = m_objRange.Font;
m_objFont.Bold=true;

// Save the Workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book1.xls", m_objOpt, m_objOpt, 
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 
m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

如果数据量较小,则按单元格传输数据单元格是一种可接受的方法。 你可以灵活地将数据放入工作簿中的任意位置,并且可以在运行时有条件地设置单元格的格式。 但是,如果要将大量数据传输到 Excel 工作簿,则使用此方法不是一个好主意。 在运行时获取的每个 Range 对象都会生成一个接口请求,这意味着数据传输速度更慢。 此外,Microsoft Windows 95、Microsoft Windows 98 和 Microsoft Windows Millennium Edition (Me) 对接口请求有 64 千字节 (KB) 限制。 如果有超过 64 KB 的接口请求,自动化服务器 (Excel) 可能会停止响应,或者可能会收到指示内存不足的错误消息。

同样,仅对少量数据可接受按单元格传输数据单元格。 如果必须将大型数据集传输到 Excel,请考虑使用本文中讨论的其他方法之一来批量传输数据。

有关其他信息,以及使用 Visual C# .NET 自动执行 Excel 的示例,请单击下面的文章编号,查看 Microsoft 知识库中的文章:

302084 HOWTO:从 Microsoft Visual C# .NET 自动执行 Microsoft Excel

使用自动化将数据数组传输到工作表上的区域

可以一次将数据数组传输到多个单元格的区域:

// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));

// Create an array for the headers and add it to cells A1:C1.
object[] objHeaders = {"Order ID", "Amount", "Tax"};
m_objRange = m_objSheet.get_Range("A1", "C1");
m_objRange.Value = objHeaders;
m_objFont = m_objRange.Font;
m_objFont.Bold=true;

// Create an array with 3 columns and 100 rows and add it to
// the worksheet starting at cell A2.
object[,] objData = new Object[100,3];
Random rdm = new Random((int)DateTime.Now.Ticks);
double nOrderAmt, nTax;
for(int r=0;r<100;r++)
{
objData[r,0] = "ORD" + r.ToString("0000");
nOrderAmt = rdm.Next(1000);
objData[r,1] = nOrderAmt.ToString("c");
nTax = nOrderAmt*0.07;
objData[r,2] = nTax.ToString("c");
}
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange = m_objRange.get_Resize(100,3);
m_objRange.Value = objData;

// Save the Workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book2.xls", m_objOpt, m_objOpt, 
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 
m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

如果使用数组而不是单元格按单元格传输数据,则可以使用大量数据实现巨大的性能提升。 请考虑上述代码中的以下行,这些代码将数据传输到工作表中的 300 个单元格:

objRange = objSheet.get_Range("A2", m_objOpt);
objRange = objRange.get_Resize(100,3);
objRange.Value = objData;

此代码表示两个接口请求:一个用于 Range 方法返回的 Range 对象,另一个用于 Resize 方法返回的 Range 对象。 相比之下,按单元格传输数据单元格需要向 Range 对象请求 300 个接口。 尽可能地从批量传输数据和减少发出的接口请求数中获益。

有关使用数组获取和设置 Excel 自动化范围中的值的其他信息,请单击下面的文章编号,查看 Microsoft 知识库中的文章:

302096 HOWTO:使用 Visual C# .NET 自动执行 Excel,以使用数组在区域中填充或获取数据

使用自动化将 ADO 记录集传输到工作表范围

Excel 2000、Excel 2002 和 Excel 2003 的对象模型提供 CopyFromRecordset 方法,用于将 ADO 记录集传输到工作表上的范围。 以下代码演示如何使用 CopyFromRecordset 方法自动执行 Excel 以传输 Northwind 示例数据库中 Orders 表的内容:

// Create a Recordset from all the records in the Orders table.
ADODB.Connection objConn = new ADODB.Connection();
ADODB._Recordset objRS = null;
objConn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
m_strNorthwind + ";", "", "", 0);
objConn.CursorLocation = ADODB.CursorLocationEnum.adUseClient;
object objRecAff;
objRS = (ADODB._Recordset)objConn.Execute("Orders", out objRecAff, 
(int)ADODB.CommandTypeEnum.adCmdTable);

// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));

// Get the Fields collection from the recordset and determine
// the number of fields (or columns).
System.Collections.IEnumerator objFields = objRS.Fields.GetEnumerator();
int nFields = objRS.Fields.Count;

// Create an array for the headers and add it to the
// worksheet starting at cell A1.
object[] objHeaders = new object[nFields];
ADODB.Field objField = null;
for(int n=0;n<nFields;n++)
{
objFields.MoveNext();
objField = (ADODB.Field)objFields.Current;
objHeaders[n] = objField.Name;
}
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objRange = m_objRange.get_Resize(1, nFields);
m_objRange.Value = objHeaders;
m_objFont = m_objRange.Font;
m_objFont.Bold=true;

// Transfer the recordset to the worksheet starting at cell A2.
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange.CopyFromRecordset(objRS, m_objOpt, m_objOpt);

// Save the Workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book3.xls", m_objOpt, m_objOpt, 
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 
m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

// Close the recordset and connection.
objRS.Close();
objConn.Close();

注意

CopyFromRecordset 仅适用于 ADO Recordset 对象。 不能将 ADO.NET 与 CopyFromRecordset 方法结合使用来创建的 DataSet。 以下部分中的几个示例演示了如何使用 ADO.NET 将数据传输到 Excel。

使用自动化在工作表上创建 QueryTable 对象

QueryTable 对象表示从外部数据源返回的数据生成的表。 自动执行 Excel 时,可以通过向 OLE DB 或 ODBC 数据源和 SQL 字符串提供连接字符串来创建 QueryTable。 Excel 生成记录集,并将记录集插入到指定位置的工作表中。 QueryTable 对象比 CopyFromRecordset 方法具有以下优势:

  • Excel 处理记录集的创建及其在工作表上的位置。
  • 可以使用 QueryTable 对象保存查询,并在稍后刷新该查询以获取更新的记录集。
  • 将新的 QueryTable 添加到工作表中时,可以指定将工作表中已存在的数据移至处理新数据 (以获取详细信息,请参阅 RefreshStyle 属性) 。

以下代码演示如何使用 Northwind 示例数据库中的数据自动执行 Excel 2000、Excel 2002 或 Excel 2003,以便在 Excel 工作表中创建新的 QueryTable:

// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));

// Create a QueryTable that starts at cell A1.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objQryTables = m_objSheet.QueryTables;
m_objQryTable = (Excel._QueryTable)m_objQryTables.Add(
"OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
m_strNorthwind + ";", m_objRange, "Select * From Orders");
m_objQryTable.RefreshStyle = Excel.XlCellInsertionMode.xlInsertEntireRows;
m_objQryTable.Refresh(false);

// Save the workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book4.xls", m_objOpt, m_objOpt, 
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

使用 Windows 剪贴板

可以使用 Windows 剪贴板将数据传输到工作表。 若要将数据粘贴到工作表上的多个单元格中,可以复制一个字符串,其中列由 TAB 字符分隔,行按回车符分隔。 以下代码演示了 Visual C# .NET 如何使用 Windows 剪贴板将数据传输到 Excel:

// Copy a string to the Windows clipboard.
string sData = "FirstName\tLastName\tBirthdate\r\n"  +
"Bill\tBrown\t2/5/85\r\n"  +
"Joe\tThomas\t1/1/91";
System.Windows.Forms.Clipboard.SetDataObject(sData);

// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));

// Paste the data starting at cell A1.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objSheet.Paste(m_objRange, false);

// Save the workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book5.xls", m_objOpt, m_objOpt, 
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

创建 Excel 可以分析为行和列的带分隔符的文本文件

Excel 可以打开以制表符或逗号分隔的文件,并将数据正确分析到单元格中。 如果想要将大量数据传输到工作表,同时很少(如果有)自动化,则可以使用此功能。 对于客户端服务器程序来说,这可能是一种不错的方法,因为文本文件可以生成服务器端。 然后,可以在客户端打开文本文件,并在适当时使用自动化。

以下代码演示如何从使用 ADO.NET 读取的数据生成以选项卡分隔的文本文件:

// Connect to the data source.
System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection( 
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strNorthwind + ";");
objConn.Open();

// Execute a command to retrieve all records from the Employees table.
System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand( 
"Select * From Employees", objConn);
System.Data.OleDb.OleDbDataReader objReader;
objReader = objCmd.ExecuteReader();

// Create the FileStream and StreamWriter object to write 
// the recordset contents to file.
System.IO.FileStream fs = new System.IO.FileStream(
m_strSampleFolder + "Book6.txt", System.IO.FileMode.Create);
System.IO.StreamWriter sw = new System.IO.StreamWriter(
fs, System.Text.Encoding.Unicode);

// Write the field names (headers) as the first line in the text file.
sw.WriteLine(objReader.GetName(0) +  "\t" + objReader.GetName(1) +
"\t" + objReader.GetName(2) + "\t" + objReader.GetName(3) +
"\t" + objReader.GetName(4) + "\t" + objReader.GetName(5));

// Write the first six columns in the recordset to a text file as
// tab-delimited.
while(objReader.Read()) 
{
for(int i=0;i<=5;i++)
{
if(!objReader.IsDBNull(i))
{
string s;
s = objReader.GetDataTypeName(i);
if(objReader.GetDataTypeName(i)=="DBTYPE_I4")
{
sw.Write(objReader.GetInt32(i).ToString());
}
else if(objReader.GetDataTypeName(i)=="DBTYPE_DATE")
{
sw.Write(objReader.GetDateTime(i).ToString("d"));
}
else if (objReader.GetDataTypeName(i)=="DBTYPE_WVARCHAR")
{
sw.Write(objReader.GetString(i));
}
}
if(i<5) sw.Write("\t");
}
sw.WriteLine(); 
}
sw.Flush();// Write the buffered data to the filestream.

// Close the FileStream.
fs.Close();

// Close the reader and the connection.
objReader.Close();
objConn.Close(); 

上述代码不使用自动化。 但是,如果需要,可以使用自动化打开文本文件并将文件保存为 Excel 工作簿格式,如下所示:

// Open the text file in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBooks.OpenText(m_strSampleFolder + "Book6.txt", Excel.XlPlatform.xlWindows, 1, 
Excel.XlTextParsingType.xlDelimited, Excel.XlTextQualifier.xlTextQualifierDoubleQuote,
false, true, false, false, false, false, m_objOpt, m_objOpt, 
m_objOpt, m_objOpt, m_objOpt);

m_objBook = m_objExcel.ActiveWorkbook;

// Save the text file in the typical workbook format and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book6.xls", Excel.XlFileFormat.xlWorkbookNormal, 
m_objOpt, m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

使用 ADO.NET 将数据传输到工作表

可以使用 Microsoft Jet OLE DB 提供程序将记录添加到现有 Excel 工作簿中的表。 Excel 中的表只是一系列单元格;该区域可能具有定义的名称。 通常,区域的第一行包含) (或字段名称的标头,并且该区域中的所有后续行都包含记录。

以下代码将两条新记录添加到Book7.xls中的表中。 本例中的表为 Sheet1:

// Establish a connection to the data source.
System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strSampleFolder +
"Book7.xls;Extended Properties=Excel 8.0;");
objConn.Open();

// Add two records to the table named 'MyTable'.
System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand();
objCmd.Connection = objConn;
objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" +
" values ('Bill', 'Brown')";
objCmd.ExecuteNonQuery();
objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" +
" values ('Joe', 'Thomas')";
objCmd.ExecuteNonQuery();

// Close the connection.
objConn.Close();

添加包含 ADO.NET 的记录时,将保留工作簿中的格式。 添加到行中的每个记录都从行之前的行中借用格式。

有关使用 ADO.NET 的其他信息,请单击以下文章编号,查看 Microsoft 知识库中的文章:

306636 如何:使用 ADO.NET 和 Visual C# .NET 连接到数据库并运行命令

314145 如何:使用 Visual C# .NET 从数据库填充 DataSet 对象

307587 如何:使用 Visual C# .NET 从 DataSet 对象更新数据库

有关将 Jet OLEDB 提供程序与 Excel 数据源配合使用的其他信息,请单击以下文章编号,查看 Microsoft 知识库中的文章:

278973 示例:ExcelADO 演示如何使用 ADO 在 Excel 工作簿中读取和写入数据

257819 HOWTO:将 ADO 与 Visual Basic 或 VBA 中的 Excel 数据配合使用

传输 XML 数据 (Excel 2002 和 Excel 2003)

Excel 2002 和 2003 可以打开任何格式正确的 XML 文件。 可以通过在“文件”菜单上使用 Open 命令直接打开 XML 文件,也可以使用工作簿集合的 Open 或 OpenXML 方法以编程方式打开 XML 文件。 如果创建要在 Excel 中使用的 XML 文件,还可以创建样式表来设置数据的格式。

创建完整的示例 Visual C# .NET 项目

  1. 创建名为 C:\ExcelData 的新文件夹。 示例程序将 Excel 工作簿存储在此文件夹中。

  2. 为要写入到的示例创建新工作簿:

    1. 在 Excel 中启动新工作簿。
    2. 在新工作簿的 Sheet1 上,在单元格 A1 中键入 FirstName,在单元格 B1 中键入 LastName。
    3. 选择 A1:B1。
    4. 在“插入”菜单上,指向“名称”,然后单击“定义”。 键入名称 MyTable,然后单击“确定”。
    5. 将工作簿另存为C:\Exceldata\Book7.xls。
    6. 退出 Excel。
  3. 启动 Microsoft Visual Studio 2005 或 Microsoft Visual Studio .NET。 在"文件"菜单上,指向"新建",然后单击"项目"。 在 Visual C# 项目或 Visual C# 下,选择 Windows 应用程序。 默认情况下,将创建 Form1。

  4. 添加对 Excel 对象库和 ADODB 主互操作程序集的引用。 为此,请按照下列步骤操作:

    1. 在"项目"菜单上单击"添加引用"。
    2. 在“NET”选项卡上,找到 ADODB,然后单击“选择”。

    请注意,在 Visual Studio 2005 中,无需单击“ 选择”。
    3. 在 COM 选项卡上,找到 Microsoft Excel 10.0 对象库或 Microsoft Excel 11.0 对象库,然后单击“选择”。

    请注意,在 Visual Studio 2005 中,无需单击“ 选择”。

    请注意,如果使用的是 Microsoft Excel 2002,但尚未这样做,Microsoft 建议下载并安装 Microsoft Office XP 主互操作程序集 (PIA) 。

  5. 在“添加引用”对话框中,单击“确定”以接受所选内容。

  6. 将组合框控件和按钮控件添加到 Form1。

  7. 为窗体加载事件和按钮控件的 Click 事件添加事件处理程序:

    1. 在 Form1.cs 的设计视图中,双击 Form1。

    窗体加载事件的处理程序已创建并显示在 Form1.cs 中。
    2.在“视图”菜单上,单击“设计器”切换到设计视图。
    3. 双击 Button1。

    将创建按钮的 Click 事件的处理程序,并显示在 Form1.cs 中。

  8. 在 Form1.cs 中,替换以下代码:

    private void Form1_Load(object sender, System.EventArgs e)
    {
    
    }
    
    private void button1_Click(object sender, System.EventArgs e)
    {
    
    }
    
    

    与:

            // Excel object references.
            private Excel.Application m_objExcel =  null;
            private Excel.Workbooks m_objBooks = null;
            private Excel._Workbook m_objBook = null;
            private Excel.Sheets m_objSheets = null;
            private Excel._Worksheet m_objSheet = null;
            private Excel.Range m_objRange =  null;
            private Excel.Font m_objFont = null;
            private Excel.QueryTables m_objQryTables = null;
            private Excel._QueryTable m_objQryTable = null;
    
    // Frequenty-used variable for optional arguments.
            private object m_objOpt = System.Reflection.Missing.Value;
    
    // Paths used by the sample code for accessing and storing data.
            private object m_strSampleFolder = "C:\\ExcelData\\";
            private string m_strNorthwind = "C:\\Program Files\\Microsoft Office\\Office10\\Samples\\Northwind.mdb";
    
    private void Form1_Load(object sender, System.EventArgs e)
            {
                comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
    
    comboBox1.Items.AddRange(new object[]{
                                                         "Use Automation to Transfer Data Cell by Cell ", 
                                                         "Use Automation to Transfer an Array of Data to a Range on a Worksheet ", 
                                                         "Use Automation to Transfer an ADO Recordset to a Worksheet Range ", 
                                                         "Use Automation to Create a QueryTable on a Worksheet", 
                                                         "Use the Clipboard", 
                                                         "Create a Delimited Text File that Excel Can Parse into Rows and Columns", 
                                                         "Transfer Data to a Worksheet Using ADO.NET "});
                comboBox1.SelectedIndex = 0;
                button1.Text = "Go!";
            }
    
    private void button1_Click(object sender, System.EventArgs e)
            {
                switch (comboBox1.SelectedIndex)
                {
                    case 0 : Automation_CellByCell(); break;
                    case 1 : Automation_UseArray(); break;
                    case 2 : Automation_ADORecordset(); break;
                    case 3 : Automation_QueryTable(); break;
                    case 4 : Use_Clipboard(); break;
                    case 5 : Create_TextFile(); break;
                    case 6 : Use_ADONET(); break;
                }
    
    //Clean-up
                m_objFont = null;
                m_objRange = null;
                m_objSheet = null;
                m_objSheets = null;
                m_objBooks = null;
                m_objBook = null;
                m_objExcel = null;
                GC.Collect();
    
    }
    
    private void Automation_CellByCell()
            {
                // Start a new workbook in Excel.
                m_objExcel = new Excel.Application();
                m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
                m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
    
    // Add data to cells of the first worksheet in the new workbook.
                m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
                m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
                m_objRange = m_objSheet.get_Range("A1", m_objOpt);
                m_objRange.set_Value(m_objOpt,"Last Name");
                m_objRange = m_objSheet.get_Range("B1", m_objOpt);
                m_objRange.set_Value(m_objOpt,"First Name");
                m_objRange = m_objSheet.get_Range("A2", m_objOpt);
                m_objRange.set_Value(m_objOpt,"Doe");
                m_objRange = m_objSheet.get_Range("B2", m_objOpt);
                m_objRange.set_Value(m_objOpt,"John");
    
    // Apply bold to cells A1:B1.
                m_objRange = m_objSheet.get_Range("A1", "B1");
                m_objFont = m_objRange.Font;
                m_objFont.Bold=true;
    
    // Save the workbook and quit Excel.
                m_objBook.SaveAs(m_strSampleFolder + "Book1.xls", m_objOpt, m_objOpt, 
                    m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 
                    m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
                m_objBook.Close(false, m_objOpt, m_objOpt);
                m_objExcel.Quit();
    
    }
    
    private void Automation_UseArray()
            {
                // Start a new workbook in Excel.
                m_objExcel = new Excel.Application();
                m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
                m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
                m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
                m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
    
    // Create an array for the headers and add it to cells A1:C1.
                object[] objHeaders = {"Order ID", "Amount", "Tax"};
                m_objRange = m_objSheet.get_Range("A1", "C1");
                m_objRange.set_Value(m_objOpt,objHeaders);
                m_objFont = m_objRange.Font;
                m_objFont.Bold=true;
    
    // Create an array with 3 columns and 100 rows and add it to
                // the worksheet starting at cell A2.
                object[,] objData = new Object[100,3];
                Random rdm = new Random((int)DateTime.Now.Ticks);
                double nOrderAmt, nTax;
                for(int r=0;r<100;r++)
                {
                    objData[r,0] = "ORD" + r.ToString("0000");
                    nOrderAmt = rdm.Next(1000);
                    objData[r,1] = nOrderAmt.ToString("c");
                    nTax = nOrderAmt*0.07;
                    objData[r,2] = nTax.ToString("c");
                }
                m_objRange = m_objSheet.get_Range("A2", m_objOpt);
                m_objRange = m_objRange.get_Resize(100,3);
                m_objRange.set_Value(m_objOpt,"objData");
    
    // Save the workbook and quit Excel.
                m_objBook.SaveAs(m_strSampleFolder + "Book2.xls", m_objOpt, m_objOpt, 
                    m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 
                    m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
                m_objBook.Close(false, m_objOpt, m_objOpt);
                m_objExcel.Quit();
    
    }
    
    private void Automation_ADORecordset()
            {
                // Create a Recordset from all the records in the Orders table.
                ADODB.Connection objConn = new ADODB.Connection();
                ADODB._Recordset objRS = null;
                objConn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
                    m_strNorthwind + ";", "", "", 0);
                objConn.CursorLocation = ADODB.CursorLocationEnum.adUseClient;
                object objRecAff;
                objRS = (ADODB._Recordset)objConn.Execute("Orders", out objRecAff, 
                    (int)ADODB.CommandTypeEnum.adCmdTable);
    
    // Start a new workbook in Excel.
                m_objExcel = new Excel.Application();
                m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
                m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
                m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
                m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
    
    // Get the Fields collection from the recordset and determine
                // the number of fields (or columns).
                System.Collections.IEnumerator objFields = objRS.Fields.GetEnumerator();
                int nFields = objRS.Fields.Count;
    
    // Create an array for the headers and add it to the
                // worksheet starting at cell A1.
                object[] objHeaders = new object[nFields];
                ADODB.Field objField = null;
                for(int n=0;n<nFields;n++)
                {
                    objFields.MoveNext();
                    objField = (ADODB.Field)objFields.Current;
                    objHeaders[n] = objField.Name;
                }
                m_objRange = m_objSheet.get_Range("A1", m_objOpt);
                m_objRange = m_objRange.get_Resize(1, nFields);
                m_objRange.set_Value(m_objOpt,objHeaders);
                m_objFont = m_objRange.Font;
                m_objFont.Bold=true;
    
    // Transfer the recordset to the worksheet starting at cell A2.
                m_objRange = m_objSheet.get_Range("A2", m_objOpt);
                m_objRange.CopyFromRecordset(objRS, m_objOpt, m_objOpt);
    
    // Save the workbook and quit Excel.
                m_objBook.SaveAs(m_strSampleFolder + "Book3.xls", m_objOpt, m_objOpt, 
                    m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 
                    m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
                m_objBook.Close(false, m_objOpt, m_objOpt);
                m_objExcel.Quit();
    
    //Close the recordset and connection
                objRS.Close();
                objConn.Close();
    
    }
    
    private void Automation_QueryTable()
            {
                // Start a new workbook in Excel.
                m_objExcel = new Excel.Application();
                m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
                m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
    
    // Create a QueryTable that starts at cell A1.
                m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
                m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
                m_objRange = m_objSheet.get_Range("A1", m_objOpt);
                m_objQryTables = m_objSheet.QueryTables;
                m_objQryTable = (Excel._QueryTable)m_objQryTables.Add(
                    "OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
                    m_strNorthwind + ";", m_objRange, "Select * From Orders");
                m_objQryTable.RefreshStyle = Excel.XlCellInsertionMode.xlInsertEntireRows;
                m_objQryTable.Refresh(false);
    
    // Save the workbook and quit Excel.
                m_objBook.SaveAs(m_strSampleFolder + "Book4.xls", m_objOpt, m_objOpt, 
                    m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
                    m_objOpt, m_objOpt, m_objOpt);
                m_objBook.Close(false, m_objOpt, m_objOpt);
                m_objExcel.Quit();
    
    }
    
    private void Use_Clipboard()
            {
                // Copy a string to the clipboard.
                string sData = "FirstName\tLastName\tBirthdate\r\n"  +
                    "Bill\tBrown\t2/5/85\r\n"  +
                    "Joe\tThomas\t1/1/91";
                System.Windows.Forms.Clipboard.SetDataObject(sData);
    
    // Start a new workbook in Excel.
                m_objExcel = new Excel.Application();
                m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
                m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
    
    // Paste the data starting at cell A1.
                m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
                m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
                m_objRange = m_objSheet.get_Range("A1", m_objOpt);
                m_objSheet.Paste(m_objRange, false);
    
    // Save the workbook and quit Excel.
                m_objBook.SaveAs(m_strSampleFolder + "Book5.xls", m_objOpt, m_objOpt, 
                    m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
                    m_objOpt, m_objOpt, m_objOpt);
                m_objBook.Close(false, m_objOpt, m_objOpt);
                m_objExcel.Quit();
    
    }
    
    private void Create_TextFile()
            {
                // Connect to the data source.
                System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection( 
                    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strNorthwind + ";");
                objConn.Open();
    
    // Execute a command to retrieve all records from the Employees  table.
                System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand( 
                    "Select * From Employees", objConn);
                System.Data.OleDb.OleDbDataReader objReader;
                objReader = objCmd.ExecuteReader();
    
    // Create the FileStream and StreamWriter object to write 
                // the recordset contents to file.
                System.IO.FileStream fs = new System.IO.FileStream(
                    m_strSampleFolder + "Book6.txt", System.IO.FileMode.Create);
                System.IO.StreamWriter sw = new System.IO.StreamWriter(
                    fs, System.Text.Encoding.Unicode);
    
    // Write the field names (headers) as the first line in the text file.
                sw.WriteLine(objReader.GetName(0) +  "\t" + objReader.GetName(1) +
                    "\t" + objReader.GetName(2) + "\t" + objReader.GetName(3) +
                    "\t" + objReader.GetName(4) + "\t" + objReader.GetName(5));
    
    // Write the first six columns in the recordset to a text file as
                // tab-delimited.
                while(objReader.Read()) 
                {
                    for(int i=0;i<=5;i++)
                    {
                        if(!objReader.IsDBNull(i))
                        {
                            string s;
                            s = objReader.GetDataTypeName(i);
                            if(objReader.GetDataTypeName(i)=="DBTYPE_I4")
                            {
                                sw.Write(objReader.GetInt32(i).ToString());
                            }
                            else if(objReader.GetDataTypeName(i)=="DBTYPE_DATE")
                            {
                                sw.Write(objReader.GetDateTime(i).ToString("d"));
                            }
                            else if (objReader.GetDataTypeName(i)=="DBTYPE_WVARCHAR")
                            {
                                sw.Write(objReader.GetString(i));
                            }
                        }
                        if(i<5) sw.Write("\t");
                    }
                    sw.WriteLine(); 
                }
                sw.Flush();// Write the buffered data to the FileStream.
    
    // Close the FileStream.
                fs.Close();
    
    // Close the reader and the connection.
                objReader.Close();
                objConn.Close(); 
    
    // ==================================================================
                // Optionally, automate Excel to open the text file and save it in the
                // Excel workbook format.
    
    // Open the text file in Excel.
                m_objExcel = new Excel.Application();
                m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
                m_objBooks.OpenText(m_strSampleFolder + "Book6.txt", Excel.XlPlatform.xlWindows, 1, 
                    Excel.XlTextParsingType.xlDelimited, Excel.XlTextQualifier.xlTextQualifierDoubleQuote,
                    false, true, false, false, false, false, m_objOpt, m_objOpt, 
                    m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
    
    m_objBook = m_objExcel.ActiveWorkbook;
    
    // Save the text file in the typical workbook format and quit Excel.
                m_objBook.SaveAs(m_strSampleFolder + "Book6.xls", Excel.XlFileFormat.xlWorkbookNormal, 
                    m_objOpt, m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
                    m_objOpt, m_objOpt, m_objOpt);
                m_objBook.Close(false, m_objOpt, m_objOpt);
                m_objExcel.Quit();
    
    }
    
    private void Use_ADONET()
            {
                // Establish a connection to the data source.
                System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection(
                    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strSampleFolder +
                    "Book7.xls;Extended Properties=Excel 8.0;");
                objConn.Open();
    
    // Add two records to the table named 'MyTable'.
                System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand();
                objCmd.Connection = objConn;
                objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" +
                    " values ('Bill', 'Brown')";
    
    objCmd.ExecuteNonQuery();
                objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" +
                    " values ('Joe', 'Thomas')";
                objCmd.ExecuteNonQuery();
    
    // Close the connection.
                objConn.Close(); 
    
    } 
    
    }  // End Class
    }// End namespace
    
    

    请注意,必须在 Visual Studio 2005 中更改代码。 默认情况下,在创建Windows 窗体项目时,Visual C# 会向项目添加一个窗体。 该窗体名为 Form1。 表示窗体的两个文件名为 Form1.cs 和 Form1.designer.cs。 在 Form1.cs 中编写代码。 Form1.designer.cs 文件是Windows 窗体设计器写入代码的位置,该代码通过拖放工具箱中的控件来实现执行的所有操作。

    有关 Visual C# 2005 中Windows 窗体设计器的详细信息,请访问以下 Microsoft 开发人员网络 (MSDN) 网站:

    创建项目 (Visual C#) 请注意,如果未将 Office 安装到默认文件夹 (C:\Program Files\Microsoft Office) ,请修改代码示例中的m_strNorthwind常量,以匹配 Northwind.mdb 的安装路径。

  9. 将以下内容添加到 Form1.cs 中的 Using 指令:

    using System.Reflection;
    using System.Runtime.InteropServices;
    using Excel = Microsoft.Office.Interop.Excel;
    
  10. 按 F5 生成和运行此示例。

参考

有关更多信息,请访问以下 Microsoft 网站:

使用 Visual Studio 进行 Microsoft Office 开发