如何使用 Visual C# 2005 或 Visual C# .NET 向 Excel 工作簿传输数据
本文分步介绍了多种从 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 程序。
方法
使用“自动化”功能逐单元格传输数据
利用“自动化”功能,您可以逐单元格地向工作表传输数据:
1 // Start a new workbook in Excel. 2 m_objExcel = new Excel.Application(); 3 m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks; 4 m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt)); 5 6 // Add data to cells in the first worksheet in the new workbook. 7 m_objSheets = (Excel.Sheets)m_objBook.Worksheets; 8 m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1)); 9 m_objRange = m_objSheet.get_Range("A1", m_objOpt); 10 m_objRange.Value = "Last Name"; 11 m_objRange = m_objSheet.get_Range("B1", m_objOpt); 12 m_objRange.Value = "First Name"; 13 m_objRange = m_objSheet.get_Range("A2", m_objOpt); 14 m_objRange.Value = "Doe"; 15 m_objRange = m_objSheet.get_Range("B2", m_objOpt); 16 m_objRange.Value = "John"; 17 18 // Apply bold to cells A1:B1. 19 m_objRange = m_objSheet.get_Range("A1", "B1"); 20 m_objFont = m_objRange.Font; 21 m_objFont.Bold=true; 22 23 // Save the Workbook and quit Excel. 24 m_objBook.SaveAs(m_strSampleFolder + "Book1.xls", m_objOpt, m_objOpt, 25 m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 26 m_objOpt, m_objOpt, m_objOpt, m_objOpt); 27 m_objBook.Close(false, m_objOpt, m_objOpt); 28 m_objExcel.Quit();
如果您具有少量的数据,则逐单元格地传输数据是可以接受的方法。您可以灵活地将数据放到工作簿中的任何地方,并可以在运行时根据条件对单元格进行格式设置。不过,如果您具有大量需要传输到 Excel 工作簿的数据,则使用这种方法不是一个好主意。您在运行时获取的每一个“Range”对象都会产生一个接口请求,这意味着数据传输速度会变得较慢。此外,Microsoft Windows 95、Microsoft Windows 98 以及 Microsoft Windows Millennium Edition (Me) 都对接口请求有 64 KB 的限制。如果您具有 64 KB 以上的接口请求,则“自动化”服务器 (Excel) 可能会停止响应,或者您可能会收到指出内存不足的错误消息。 有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
需要再次强调的是,逐单元格地传输数据仅对少量数据而言才可以接受。如果您必须向 Excel
传输大型数据集,则应考虑使用本文中讨论的其他方法之一来批量地传输数据。
有关其他信息以及如何利用 Visual C#
.NET 自动运行 Excel 的示例,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
使用“自动化”功能将数据数组传输到工作表上的区域
可以将数据数组一次性地传输到由多个单元格组成的区域:
1 // Start a new workbook in Excel. 2 m_objExcel = new Excel.Application(); 3 m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks; 4 m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt)); 5 m_objSheets = (Excel.Sheets)m_objBook.Worksheets; 6 m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1)); 7 8 // Create an array for the headers and add it to cells A1:C1. 9 object[] objHeaders = {"Order ID", "Amount", "Tax"}; 10 m_objRange = m_objSheet.get_Range("A1", "C1"); 11 m_objRange.Value = objHeaders; 12 m_objFont = m_objRange.Font; 13 m_objFont.Bold=true; 14 15 // Create an array with 3 columns and 100 rows and add it to 16 // the worksheet starting at cell A2. 17 object[,] objData = new Object[100,3]; 18 Random rdm = new Random((int)DateTime.Now.Ticks); 19 double nOrderAmt, nTax; 20 for(int r=0;r<100;r++) 21 { 22 objData[r,0] = "ORD" + r.ToString("0000"); 23 nOrderAmt = rdm.Next(1000); 24 objData[r,1] = nOrderAmt.ToString("c"); 25 nTax = nOrderAmt*0.07; 26 objData[r,2] = nTax.ToString("c"); 27 } 28 m_objRange = m_objSheet.get_Range("A2", m_objOpt); 29 m_objRange = m_objRange.get_Resize(100,3); 30 m_objRange.Value = objData; 31 32 // Save the Workbook and quit Excel. 33 m_objBook.SaveAs(m_strSampleFolder + "Book2.xls", m_objOpt, m_objOpt, 34 m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 35 m_objOpt, m_objOpt, m_objOpt, m_objOpt); 36 m_objBook.Close(false, m_objOpt, m_objOpt); 37 m_objExcel.Quit();
如果您使用数组而不是逐单元格地传输数据,则在传输大量数据时,传输性能会大大地增强。请考虑前面代码中的下面几行,这些行将数据传输到工作表中的 300 个单元格:
1 objRange = objSheet.get_Range("A2", m_objOpt); 2 objRange = objRange.get_Resize(100,3); 3 objRange.Value = objData;
上面的代码代表了两个接口请求:一个请求是针对“Range”方法返回的“Range”对象,另一个请求是针对“Resize”方法返回的“Range”对象。相比之下,逐单元格地传输数据却需要对“Range”对象发出
300 个接口请求。只要有可能,您就可以从批量地传输数据以及减少所发出的接口请求的数量当中受益。
有关通过
Excel 自动化并使用数组获取和设置区域中的值的其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
使用“自动化”功能将 ADO 记录集传输到工作表区域
Excel 2000、Excel 2002 和 Excel 2003 的对象模型提供了“CopyFromRecordset”方法,用于向工作表上的区域传输 ADO 记录集。下面的代码说明了如何使用“CopyFromRecordset”方法使 Excel 自动运行,以传输 Northwind 示例数据库中的“订单”表的内容:
1 // Create a Recordset from all the records in the Orders table. 2 ADODB.Connection objConn = new ADODB.Connection(); 3 ADODB._Recordset objRS = null; 4 objConn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + 5 m_strNorthwind + ";", "", "", 0); 6 objConn.CursorLocation = ADODB.CursorLocationEnum.adUseClient; 7 object objRecAff; 8 objRS = (ADODB._Recordset)objConn.Execute("Orders", out objRecAff, 9 (int)ADODB.CommandTypeEnum.adCmdTable); 10 11 // Start a new workbook in Excel. 12 m_objExcel = new Excel.Application(); 13 m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks; 14 m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt)); 15 m_objSheets = (Excel.Sheets)m_objBook.Worksheets; 16 m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1)); 17 18 // Get the Fields collection from the recordset and determine 19 // the number of fields (or columns). 20 System.Collections.IEnumerator objFields = objRS.Fields.GetEnumerator(); 21 int nFields = objRS.Fields.Count; 22 23 // Create an array for the headers and add it to the 24 // worksheet starting at cell A1. 25 object[] objHeaders = new object[nFields]; 26 ADODB.Field objField = null; 27 for(int n=0;n<nFields;n++) 28 { 29 objFields.MoveNext(); 30 objField = (ADODB.Field)objFields.Current; 31 objHeaders[n] = objField.Name; 32 } 33 m_objRange = m_objSheet.get_Range("A1", m_objOpt); 34 m_objRange = m_objRange.get_Resize(1, nFields); 35 m_objRange.Value = objHeaders; 36 m_objFont = m_objRange.Font; 37 m_objFont.Bold=true; 38 39 // Transfer the recordset to the worksheet starting at cell A2. 40 m_objRange = m_objSheet.get_Range("A2", m_objOpt); 41 m_objRange.CopyFromRecordset(objRS, m_objOpt, m_objOpt); 42 43 // Save the Workbook and quit Excel. 44 m_objBook.SaveAs(m_strSampleFolder + "Book3.xls", m_objOpt, m_objOpt, 45 m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 46 m_objOpt, m_objOpt, m_objOpt, m_objOpt); 47 m_objBook.Close(false, m_objOpt, m_objOpt); 48 m_objExcel.Quit(); 49 50 // Close the recordset and connection. 51 objRS.Close(); 52 objConn.Close(); 53
注意:“CopyFromRecordset”只能与 ADO“Recordset”对象一起使用。使用 ADO.NET 创建的“DataSet”不能与“CopyFromRecordset”方法一起使用。以下几节中的多个示例演示了如何利用 ADO.NET 向 Excel 传输数据。
使用“自动化”功能在工作表上创建 QueryTable 对象
“QueryTable”对象代表了一个表,该表是用从外部数据源返回的数据生成的。当您自动运行 Excel 时,可以通过提供指向 OLE DB 或 ODBC 数据源的连接字符串和 SQL 字符串来创建“QueryTable”。Excel 将生成记录集并将该记录集插入到工作表中您所指定的位置。“QueryTable”对象提供了下列优于“CopyFromRecordset”方法的优点:
- Excel 处理记录集的创建并将其放置到工作表中。
- 您可以利用“QueryTable”对象保存查询,并在以后刷新它以获取更新的记录集。
- 当向工作表中添加新的“QueryTable”时,可以指定将工作表上的单元格中已经存在的数据移位,以处理新数据(有关更多信息,请查看“RefreshStyle”属性)。
下面的代码演示了如何自动运行 Excel 2000、Excel 2002 或 Excel 2003,以便使用 Northwind 示例数据库中的数据在 Excel 工作表中创建新的“QueryTable”:
1 // Start a new workbook in Excel. 2 m_objExcel = new Excel.Application(); 3 m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks; 4 m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt)); 5 6 // Create a QueryTable that starts at cell A1. 7 m_objSheets = (Excel.Sheets)m_objBook.Worksheets; 8 m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1)); 9 m_objRange = m_objSheet.get_Range("A1", m_objOpt); 10 m_objQryTables = m_objSheet.QueryTables; 11 m_objQryTable = (Excel._QueryTable)m_objQryTables.Add( 12 "OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + 13 m_strNorthwind + ";", m_objRange, "Select * From Orders"); 14 m_objQryTable.RefreshStyle = Excel.XlCellInsertionMode.xlInsertEntireRows; 15 m_objQryTable.Refresh(false); 16 17 // Save the workbook and quit Excel. 18 m_objBook.SaveAs(m_strSampleFolder + "Book4.xls", m_objOpt, m_objOpt, 19 m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt, 20 m_objOpt, m_objOpt); 21 m_objBook.Close(false, m_objOpt, m_objOpt); 22 m_objExcel.Quit();
使用 Windows 剪贴板
可以使用 Windows 剪贴板来向工作表传输数据。要将数据粘贴到工作表上的多个单元格中,可以复制具有以下格式的字符串:在该字符串中,列由制表符分隔,行由回车符分隔。下面的代码说明了 Visual C# .NET 如何使用 Windows 剪贴板来向 Excel 传输数据:
1 // Copy a string to the Windows clipboard. 2 string sData = "FirstName\tLastName\tBirthdate\r\n" + 3 "Bill\tBrown\t2/5/85\r\n" + 4 "Joe\tThomas\t1/1/91"; 5 System.Windows.Forms.Clipboard.SetDataObject(sData); 6 7 // Start a new workbook in Excel. 8 m_objExcel = new Excel.Application(); 9 m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks; 10 m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt)); 11 12 // Paste the data starting at cell A1. 13 m_objSheets = (Excel.Sheets)m_objBook.Worksheets; 14 m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1)); 15 m_objRange = m_objSheet.get_Range("A1", m_objOpt); 16 m_objSheet.Paste(m_objRange, false); 17 18 // Save the workbook and quit Excel. 19 m_objBook.SaveAs(m_strSampleFolder + "Book5.xls", m_objOpt, m_objOpt, 20 m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt, 21 m_objOpt, m_objOpt); 22 m_objBook.Close(false, m_objOpt, m_objOpt); 23 m_objExcel.Quit();
创建可由 Excel 分析为行和列的带分隔符的文本文件
Excel
可以打开由制表符或逗号分隔的文件并正确地将数据分析为单元格。当您希望向工作表传输大量数据而只使用少量(如果有的话)自动化功能时,可以使用此功能。这对于客户端-服务器程序而言可能是一个好方法,因为文本文件可以在服务器端生成。然后,可以在客户端根据需要使用“自动化”功能来打开文本文件。
下面的代码说明了如何从利用
ADO.NET 读取的数据生成制表符分隔的文本文件:
1 // Connect to the data source. 2 System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection( 3 "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strNorthwind + ";"); 4 objConn.Open(); 5 6 // Execute a command to retrieve all records from the Employees table. 7 System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand( 8 "Select * From Employees", objConn); 9 System.Data.OleDb.OleDbDataReader objReader; 10 objReader = objCmd.ExecuteReader(); 11 12 // Create the FileStream and StreamWriter object to write 13 // the recordset contents to file. 14 System.IO.FileStream fs = new System.IO.FileStream( 15 m_strSampleFolder + "Book6.txt", System.IO.FileMode.Create); 16 System.IO.StreamWriter sw = new System.IO.StreamWriter( 17 fs, System.Text.Encoding.Unicode); 18 19 // Write the field names (headers) as the first line in the text file. 20 sw.WriteLine(objReader.GetName(0) + "\t" + objReader.GetName(1) + 21 "\t" + objReader.GetName(2) + "\t" + objReader.GetName(3) + 22 "\t" + objReader.GetName(4) + "\t" + objReader.GetName(5)); 23 24 // Write the first six columns in the recordset to a text file as 25 // tab-delimited. 26 while(objReader.Read()) 27 { 28 for(int i=0;i<=5;i++) 29 { 30 if(!objReader.IsDBNull(i)) 31 { 32 string s; 33 s = objReader.GetDataTypeName(i); 34 if(objReader.GetDataTypeName(i)=="DBTYPE_I4") 35 { 36 sw.Write(objReader.GetInt32(i).ToString()); 37 } 38 else if(objReader.GetDataTypeName(i)=="DBTYPE_DATE") 39 { 40 sw.Write(objReader.GetDateTime(i).ToString("d")); 41 } 42 else if (objReader.GetDataTypeName(i)=="DBTYPE_WVARCHAR") 43 { 44 sw.Write(objReader.GetString(i)); 45 } 46 } 47 if(i<5) sw.Write("\t"); 48 } 49 sw.WriteLine(); 50 } 51 sw.Flush(); // Write the buffered data to the filestream. 52 53 // Close the FileStream. 54 fs.Close(); 55 56 // Close the reader and the connection. 57 objReader.Close(); 58 objConn.Close(); 59
上述代码没有使用“自动化”功能。不过,如果您愿意,您可以按如下方式使用“自动化”功能来打开文本文件,并以 Excel 工作簿格式保存该文件:
1 // Open the text file in Excel. 2 m_objExcel = new Excel.Application(); 3 m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks; 4 m_objBooks.OpenText(m_strSampleFolder + "Book6.txt", Excel.XlPlatform.xlWindows, 1, 5 Excel.XlTextParsingType.xlDelimited, Excel.XlTextQualifier.xlTextQualifierDoubleQuote, 6 false, true, false, false, false, false, m_objOpt, m_objOpt, 7 m_objOpt, m_objOpt, m_objOpt); 8 9 m_objBook = m_objExcel.ActiveWorkbook; 10 11 // Save the text file in the typical workbook format and quit Excel. 12 m_objBook.SaveAs(m_strSampleFolder + "Book6.xls", Excel.XlFileFormat.xlWorkbookNormal, 13 m_objOpt, m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt, 14 m_objOpt, m_objOpt); 15 m_objBook.Close(false, m_objOpt, m_objOpt); 16 m_objExcel.Quit(); 17
使用 ADO.NET 将数据传输到工作表
您可以使用 Microsoft Jet OLE DB 提供程序向现有的 Excel 工作簿中的表中添加记录。Excel
中的表只是由单元格组成的区域;该区域可能具有定义的名称。通常,区域的第一行包含标题(或字段名),该区域中所有以后的行都包含记录。
下面的代码向
Book7.xls 中的表中添加了两个新记录。在此示例中,该表是 Sheet1:
1 // Establish a connection to the data source. 2 System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection( 3 "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strSampleFolder + 4 "Book7.xls;Extended Properties=Excel 8.0;"); 5 objConn.Open(); 6 7 // Add two records to the table named ‘MyTable‘. 8 System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand(); 9 objCmd.Connection = objConn; 10 objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" + 11 " values (‘Bill‘, ‘Brown‘)"; 12 objCmd.ExecuteNonQuery(); 13 objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" + 14 " values (‘Joe‘, ‘Thomas‘)"; 15 objCmd.ExecuteNonQuery(); 16 17 // Close the connection. 18 objConn.Close();
当您按本示例所示的方法利用 ADO.NET
添加记录时,工作簿中的格式将被保持。添加到行中的每个记录都将继承它前面的行的格式。
有关使用 ADO.NET
的其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
有关如何将 Jet OLEDB 提供程序与 Excel 数据源一起使用的其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章。
传输 XML 数据(Excel 2002 和 Excel 2003)
Excel 2002 和 2003 可以打开格式完好的任何 XML 文件。您可以使用“文件”菜单上的“打开”命令直接打开 XML 文件,也可以使用“Workbooks”集合的“Open”或“OpenXML”方法以编程方式打开 XML 文件。如果您创建供在 Excel 中使用的 XML 文件,您还可以创建样式表来设置数据的格式。有关如何将 XML 与 Excel 2002 一起使用的其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
创建完整的示例 Visual C# .NET 项目
- 创建一个名为 C:\ExcelData 的新文件夹。示例程序将在此文件夹中存储 Excel 工作簿。
- 创建一个新工作簿,以供示例向其中写入数据:
- 在 Excel 中启动一个新工作簿。
- 在新工作簿的 Sheet1 上,在单元格 A1 中键入 FirstName,在单元格 B1 中键入 LastName。
- 选择 A1:B1。
- 在“插入”菜单上,指向“名称”,然后单击“定义”。键入名称 MyTable,然后单击“确定”。
- 将该工作簿另存为 C:\Exceldata\Book7.xls。
- 退出 Excel。
- 启动 Microsoft Visual Studio 2005 或 Microsoft Visual Studio .NET。在“文件”菜单上,指向“新建”,然后单击“项目”。在“Visual C# 项目”或“Visual C#”下,选择“Windows 应用程序”。默认情况下会创建 Form1。
- 添加对 Excel 对象库和 ADODB 主互操作程序集的引用。为此,请按照下列步骤操作:
- 在“项目”菜单上,单击“添加引用”。
- 在“NET”选项卡上,找到“ADODB”,然后单击“选择”。
注意:在 Visual Studio 2005 中,您不需要单击“选择”。 - 在“COM”选项卡上,找到“Microsoft Excel 10.0 对象库或 Microsoft Excel 11.0
对象库”,然后单击“选择”。
注意:在 Visual Studio 2005 中,您不需要单击“选择”。
注意:如果您正在使用 Microsoft Excel 2002,并且尚未这样做,Microsoft 建议您下载并安装 Microsoft Office XP 主互操作 程序集 (PIA)。 有关 Office XP PIA 的更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:328912 Microsoft Office XP主互操作程序集 (PIA) 可供下载 - 在“添加引用”对话框中,单击“确定”以接受您的选择。
- 向 Form1 中添加一个“Combo Box”控件和一个“Button”控件。
- 为该窗体的“Load”事件和 Button 控件的“Click”事件添加事件处理程序:
- 在 Form1.cs 的设计视图中,双击“Form1”。
此时将创建该窗体的“Load”事件的处理程序,该处理程序出现在 Form1.cs 中。 - 在“视图”菜单上,单击“设计器”以切换到设计视图。
- 双击“Button1”。
此时将创建该按钮的“Click”事件的处理程序,该处理程序出现在 Form1.cs 中。
- 在 Form1.cs 的设计视图中,双击“Form1”。
- 在 Form1.cs 中,将以下代码:
1 private void Form1_Load(object sender, System.EventArgs e) 2 { 3 4 } 5 6 private void button1_Click(object sender, System.EventArgs e) 7 { 8 9 }
替换为:
1 // Excel object references. 2 private Excel.Application m_objExcel = null; 3 private Excel.Workbooks m_objBooks = null; 4 private Excel._Workbook m_objBook = null; 5 private Excel.Sheets m_objSheets = null; 6 private Excel._Worksheet m_objSheet = null; 7 private Excel.Range m_objRange = null; 8 private Excel.Font m_objFont = null; 9 private Excel.QueryTables m_objQryTables = null; 10 private Excel._QueryTable m_objQryTable = null; 11 12 // Frequenty-used variable for optional arguments. 13 private object m_objOpt = System.Reflection.Missing.Value; 14 15 // Paths used by the sample code for accessing and storing data. 16 private object m_strSampleFolder = "C:\\ExcelData\\"; 17 private string m_strNorthwind = "C:\\Program Files\\Microsoft Office\\Office10\\Samples\\Northwind.mdb"; 18 19 private void Form1_Load(object sender, System.EventArgs e) 20 { 21 comboBox1.DropDownStyle = ComboBoxStyle.DropDownList; 22 23 comboBox1.Items.AddRange(new object[]{ 24 "Use Automation to Transfer Data Cell by Cell ", 25 "Use Automation to Transfer an Array of Data to a Range on a Worksheet ", 26 "Use Automation to Transfer an ADO Recordset to a Worksheet Range ", 27 "Use Automation to Create a QueryTable on a Worksheet", 28 "Use the Clipboard", 29 "Create a Delimited Text File that Excel Can Parse into Rows and Columns", 30 "Transfer Data to a Worksheet Using ADO.NET "}); 31 comboBox1.SelectedIndex = 0; 32 button1.Text = "Go!"; 33 } 34 35 private void button1_Click(object sender, System.EventArgs e) 36 { 37 switch (comboBox1.SelectedIndex) 38 { 39 case 0 : Automation_CellByCell(); break; 40 case 1 : Automation_UseArray(); break; 41 case 2 : Automation_ADORecordset(); break; 42 case 3 : Automation_QueryTable(); break; 43 case 4 : Use_Clipboard(); break; 44 case 5 : Create_TextFile(); break; 45 case 6 : Use_ADONET(); break; 46 } 47 48 //Clean-up 49 m_objFont = null; 50 m_objRange = null; 51 m_objSheet = null; 52 m_objSheets = null; 53 m_objBooks = null; 54 m_objBook = null; 55 m_objExcel = null; 56 GC.Collect(); 57 58 } 59 60 private void Automation_CellByCell() 61 { 62 // Start a new workbook in Excel. 63 m_objExcel = new Excel.Application(); 64 m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks; 65 m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt)); 66 67 // Add data to cells of the first worksheet in the new workbook. 68 m_objSheets = (Excel.Sheets)m_objBook.Worksheets; 69 m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1)); 70 m_objRange = m_objSheet.get_Range("A1", m_objOpt); 71 m_objRange.set_Value(m_objOpt,"Last Name"); 72 m_objRange = m_objSheet.get_Range("B1", m_objOpt); 73 m_objRange.set_Value(m_objOpt,"First Name"); 74 m_objRange = m_objSheet.get_Range("A2", m_objOpt); 75 m_objRange.set_Value(m_objOpt,"Doe"); 76 m_objRange = m_objSheet.get_Range("B2", m_objOpt); 77 m_objRange.set_Value(m_objOpt,"John"); 78 79 // Apply bold to cells A1:B1. 80 m_objRange = m_objSheet.get_Range("A1", "B1"); 81 m_objFont = m_objRange.Font; 82 m_objFont.Bold=true; 83 84 // Save the workbook and quit Excel. 85 m_objBook.SaveAs(m_strSampleFolder + "Book1.xls", m_objOpt, m_objOpt, 86 m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 87 m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt); 88 m_objBook.Close(false, m_objOpt, m_objOpt); 89 m_objExcel.Quit(); 90 91 } 92 93 private void Automation_UseArray() 94 { 95 // Start a new workbook in Excel. 96 m_objExcel = new Excel.Application(); 97 m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks; 98 m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt)); 99 m_objSheets = (Excel.Sheets)m_objBook.Worksheets; 100 m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1)); 101 102 // Create an array for the headers and add it to cells A1:C1. 103 object[] objHeaders = {"Order ID", "Amount", "Tax"}; 104 m_objRange = m_objSheet.get_Range("A1", "C1"); 105 m_objRange.set_Value(m_objOpt,objHeaders); 106 m_objFont = m_objRange.Font; 107 m_objFont.Bold=true; 108 109 // Create an array with 3 columns and 100 rows and add it to 110 // the worksheet starting at cell A2. 111 object[,] objData = new Object[100,3]; 112 Random rdm = new Random((int)DateTime.Now.Ticks); 113 double nOrderAmt, nTax; 114 for(int r=0;r<100;r++) 115 { 116 objData[r,0] = "ORD" + r.ToString("0000"); 117 nOrderAmt = rdm.Next(1000); 118 objData[r,1] = nOrderAmt.ToString("c"); 119 nTax = nOrderAmt*0.07; 120 objData[r,2] = nTax.ToString("c"); 121 } 122 m_objRange = m_objSheet.get_Range("A2", m_objOpt); 123 m_objRange = m_objRange.get_Resize(100,3); 124 m_objRange.set_Value(m_objOpt,"objData"); 125 126 // Save the workbook and quit Excel. 127 m_objBook.SaveAs(m_strSampleFolder + "Book2.xls", m_objOpt, m_objOpt, 128 m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 129 m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt); 130 m_objBook.Close(false, m_objOpt, m_objOpt); 131 m_objExcel.Quit(); 132 133 } 134 135 private void Automation_ADORecordset() 136 { 137 // Create a Recordset from all the records in the Orders table. 138 ADODB.Connection objConn = new ADODB.Connection(); 139 ADODB._Recordset objRS = null; 140 objConn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + 141 m_strNorthwind + ";", "", "", 0); 142 objConn.CursorLocation = ADODB.CursorLocationEnum.adUseClient; 143 object objRecAff; 144 objRS = (ADODB._Recordset)objConn.Execute("Orders", out objRecAff, 145 (int)ADODB.CommandTypeEnum.adCmdTable); 146 147 // Start a new workbook in Excel. 148 m_objExcel = new Excel.Application(); 149 m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks; 150 m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt)); 151 m_objSheets = (Excel.Sheets)m_objBook.Worksheets; 152 m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1)); 153 154 // Get the Fields collection from the recordset and determine 155 // the number of fields (or columns). 156 System.Collections.IEnumerator objFields = objRS.Fields.GetEnumerator(); 157 int nFields = objRS.Fields.Count; 158 159 // Create an array for the headers and add it to the 160 // worksheet starting at cell A1. 161 object[] objHeaders = new object[nFields]; 162 ADODB.Field objField = null; 163 for(int n=0;n<nFields;n++) 164 { 165 objFields.MoveNext(); 166 objField = (ADODB.Field)objFields.Current; 167 objHeaders[n] = objField.Name; 168 } 169 m_objRange = m_objSheet.get_Range("A1", m_objOpt); 170 m_objRange = m_objRange.get_Resize(1, nFields); 171 m_objRange.set_Value(m_objOpt,objHeaders); 172 m_objFont = m_objRange.Font; 173 m_objFont.Bold=true; 174 175 // Transfer the recordset to the worksheet starting at cell A2. 176 m_objRange = m_objSheet.get_Range("A2", m_objOpt); 177 m_objRange.CopyFromRecordset(objRS, m_objOpt, m_objOpt); 178 179 // Save the workbook and quit Excel. 180 m_objBook.SaveAs(m_strSampleFolder + "Book3.xls", m_objOpt, m_objOpt, 181 m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 182 m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt); 183 m_objBook.Close(false, m_objOpt, m_objOpt); 184 m_objExcel.Quit(); 185 186 //Close the recordset and connection 187 objRS.Close(); 188 objConn.Close(); 189 190 } 191 192 private void Automation_QueryTable() 193 { 194 // Start a new workbook in Excel. 195 m_objExcel = new Excel.Application(); 196 m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks; 197 m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt)); 198 199 // Create a QueryTable that starts at cell A1. 200 m_objSheets = (Excel.Sheets)m_objBook.Worksheets; 201 m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1)); 202 m_objRange = m_objSheet.get_Range("A1", m_objOpt); 203 m_objQryTables = m_objSheet.QueryTables; 204 m_objQryTable = (Excel._QueryTable)m_objQryTables.Add( 205 "OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + 206 m_strNorthwind + ";", m_objRange, "Select * From Orders"); 207 m_objQryTable.RefreshStyle = Excel.XlCellInsertionMode.xlInsertEntireRows; 208 m_objQryTable.Refresh(false); 209 210 // Save the workbook and quit Excel. 211 m_objBook.SaveAs(m_strSampleFolder + "Book4.xls", m_objOpt, m_objOpt, 212 m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt, 213 m_objOpt, m_objOpt, m_objOpt); 214 m_objBook.Close(false, m_objOpt, m_objOpt); 215 m_objExcel.Quit(); 216 217 } 218 219 private void Use_Clipboard() 220 { 221 // Copy a string to the clipboard. 222 string sData = "FirstName\tLastName\tBirthdate\r\n" + 223 "Bill\tBrown\t2/5/85\r\n" + 224 "Joe\tThomas\t1/1/91"; 225 System.Windows.Forms.Clipboard.SetDataObject(sData); 226 227 // Start a new workbook in Excel. 228 m_objExcel = new Excel.Application(); 229 m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks; 230 m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt)); 231 232 // Paste the data starting at cell A1. 233 m_objSheets = (Excel.Sheets)m_objBook.Worksheets; 234 m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1)); 235 m_objRange = m_objSheet.get_Range("A1", m_objOpt); 236 m_objSheet.Paste(m_objRange, false); 237 238 // Save the workbook and quit Excel. 239 m_objBook.SaveAs(m_strSampleFolder + "Book5.xls", m_objOpt, m_objOpt, 240 m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt, 241 m_objOpt, m_objOpt, m_objOpt); 242 m_objBook.Close(false, m_objOpt, m_objOpt); 243 m_objExcel.Quit(); 244 245 } 246 247 private void Create_TextFile() 248 { 249 // Connect to the data source. 250 System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection( 251 "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strNorthwind + ";"); 252 objConn.Open(); 253 254 // Execute a command to retrieve all records from the Employees table. 255 System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand( 256 "Select * From Employees", objConn); 257 System.Data.OleDb.OleDbDataReader objReader; 258 objReader = objCmd.ExecuteReader(); 259 260 261 // Create the FileStream and StreamWriter object to write 262 // the recordset contents to file. 263 System.IO.FileStream fs = new System.IO.FileStream( 264 m_strSampleFolder + "Book6.txt", System.IO.FileMode.Create); 265 System.IO.StreamWriter sw = new System.IO.StreamWriter( 266 fs, System.Text.Encoding.Unicode); 267 268 // Write the field names (headers) as the first line in the text file. 269 sw.WriteLine(objReader.GetName(0) + "\t" + objReader.GetName(1) + 270 "\t" + objReader.GetName(2) + "\t" + objReader.GetName(3) + 271 "\t" + objReader.GetName(4) + "\t" + objReader.GetName(5)); 272 273 // Write the first six columns in the recordset to a text file as 274 // tab-delimited. 275 while(objReader.Read()) 276 { 277 for(int i=0;i<=5;i++) 278 { 279 if(!objReader.IsDBNull(i)) 280 { 281 string s; 282 s = objReader.GetDataTypeName(i); 283 if(objReader.GetDataTypeName(i)=="DBTYPE_I4") 284 { 285 sw.Write(objReader.GetInt32(i).ToString()); 286 } 287 else if(objReader.GetDataTypeName(i)=="DBTYPE_DATE") 288 { 289 sw.Write(objReader.GetDateTime(i).ToString("d")); 290 } 291 else if (objReader.GetDataTypeName(i)=="DBTYPE_WVARCHAR") 292 { 293 sw.Write(objReader.GetString(i)); 294 } 295 } 296 if(i<5) sw.Write("\t"); 297 } 298 sw.WriteLine(); 299 } 300 sw.Flush(); // Write the buffered data to the FileStream. 301 302 // Close the FileStream. 303 fs.Close(); 304 305 // Close the reader and the connection. 306 objReader.Close(); 307 objConn.Close(); 308 309 // ================================================================== 310 // Optionally, automate Excel to open the text file and save it in the 311 // Excel workbook format. 312 313 // Open the text file in Excel. 314 m_objExcel = new Excel.Application(); 315 m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks; 316 m_objBooks.OpenText(m_strSampleFolder + "Book6.txt", Excel.XlPlatform.xlWindows, 1, 317 Excel.XlTextParsingType.xlDelimited, Excel.XlTextQualifier.xlTextQualifierDoubleQuote, 318 false, true, false, false, false, false, m_objOpt, m_objOpt, 319 m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt); 320 321 m_objBook = m_objExcel.ActiveWorkbook; 322 323 // Save the text file in the typical workbook format and quit Excel. 324 m_objBook.SaveAs(m_strSampleFolder + "Book6.xls", Excel.XlFileFormat.xlWorkbookNormal, 325 m_objOpt, m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt, 326 m_objOpt, m_objOpt, m_objOpt); 327 m_objBook.Close(false, m_objOpt, m_objOpt); 328 m_objExcel.Quit(); 329 330 } 331 332 private void Use_ADONET() 333 { 334 // Establish a connection to the data source. 335 System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection( 336 "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strSampleFolder + 337 "Book7.xls;Extended Properties=Excel 8.0;"); 338 objConn.Open(); 339 340 // Add two records to the table named ‘MyTable‘. 341 System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand(); 342 objCmd.Connection = objConn; 343 objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" + 344 " values (‘Bill‘, ‘Brown‘)"; 345 346 objCmd.ExecuteNonQuery(); 347 objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" + 348 " values (‘Joe‘, ‘Thomas‘)"; 349 objCmd.ExecuteNonQuery(); 350 351 352 // Close the connection. 353 objConn.Close(); 354 355 } 356 357 } // End Class 358 }// 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 Developer Network (MSDN) 网站:
http://msdn2.microsoft.com/zh-cn/library/ms173077.aspx
注意:如果您没有将 Office 安装到默认文件夹 (C:\Program
Files\Microsoft Office) 中,请修改代码示例中的“m_strNorthwind”常量以匹配 Northwind.mdb
的安装路径。
8.将下面的代码添加到 Form1.cs 中的“Using”指令中:
1 using System.Reflection; 2 using System.Runtime.InteropServices; 3 using Excel = Microsoft.Office.Interop.Excel;
9.按 F5 生成并运行该示例。
原文地址:http://support.microsoft.com/kb/306023/zh-cn
如何使用 Visual C# 2005 或 Visual C# .NET 向 Excel 工作簿传输数据,码迷,mamicode.com