用C#创buildExcel表最简单的方法是什么?
我有一些表格数据,我想变成一个Excel表格。
软件可用:
- .NET 4(C#)
- Excel 2010(使用Excel API是好的)
- 我更喜欢不使用任何第三方库
关于数据的信息:
- 几百万行
- 5列,所有string(非常简单和规则的表结构)
- 在我的脚本中,我正在使用嵌套列表数据结构,但我可以改变这一点
- 脚本的性能并不重要
在线search给出了许多结果,我很困惑我是否应该使用OleDb,ADO RecordSets或其他。 其中一些技术似乎对我的情况有些过火,有些似乎可能已经过时。
什么是最简单的方法来做到这一点?
编辑 :这是一个一次性的脚本,我打算从我出席的桌面运行。
为了避免使用第三方工具和使用COM对象,请遵循你的请求,这里是我要做的。
- 添加对项目的引用:Com对象Microsoft Excel 11.0。
-
模块顶部添加:
using Microsoft.Office.Interop.Excel;
-
像这样添加事件逻辑:
private void DoThatExcelThing() { ApplicationClass myExcel; try { myExcel = GetObject(,"Excel.Application") } catch (Exception ex) { myExcel = New ApplicationClass() } myExcel.Visible = true; Workbook wb1 = myExcel.Workbooks.Add(""); Worksheet ws1 = (Worksheet)wb1.Worksheets[1]; //Read the connection string from App.Config string strConn = System.Configuration.ConfigurationManager.ConnectionStrings["NewConnString"].ConnectionString; //Open a connection to the database SqlConnection myConn = new SqlConnection(); myConn.ConnectionString = strConn; myConn.Open(); //Establish the query SqlCommand myCmd = new SqlCommand("select * from employees", myConn); SqlDataReader myRdr = myCmd.ExecuteReader(); //Read the data and put into the spreadsheet. int j = 3; while (myRdr.Read()) { for (int i=0 ; i < myRdr.FieldCount; i++) { ws1.Cells[j, i+1] = myRdr[i].ToString(); } j++; } //Populate the column names for (int i = 0; i < myRdr.FieldCount ; i++) { ws1.Cells[2, i+1] = myRdr.GetName(i); } myRdr.Close(); myConn.Close(); //Add some formatting Range rng1 = ws1.get_Range("A1", "H1"); rng1.Font.Bold = true; rng1.Font.ColorIndex = 3; rng1.HorizontalAlignment = XlHAlign.xlHAlignCenter; Range rng2 = ws1.get_Range("A2", "H50"); rng2.WrapText = false; rng2.EntireColumn.AutoFit(); //Add a header row ws1.get_Range("A1", "H1").EntireRow.Insert(XlInsertShiftDirection.xlShiftDown, Missing.Value); ws1.Cells[1, 1] = "Employee Contact List"; Range rng3 = ws1.get_Range("A1", "H1"); rng3.Merge(Missing.Value); rng3.Font.Size = 16; rng3.Font.ColorIndex = 3; rng3.Font.Underline = true; rng3.Font.Bold = true; rng3.VerticalAlignment = XlVAlign.xlVAlignCenter; //Save and close string strFileName = String.Format("Employees{0}.xlsx", DateTime.Now.ToString("HHmmss")); System.IO.File.Delete(strFileName); wb1.SaveAs(strFileName, XlFileFormat.xlWorkbookDefault, Missing.Value, Missing.Value, Missing.Value, Missing.Value, XlSaveAsAccessMode.xlExclusive, Missing.Value, false, Missing.Value, Missing.Value, Missing.Value); myExcel.Quit(); }
不惜一切代价避免使用COM互操作。 使用第三方API。 真。 事实上,如果你正在做这个服务器端,你几乎不得不。 有很多免费的select。 我强烈build议使用EPPlus,但也有企业级的解决scheme。 我已经使用EPPlus相当数量,它工作的很好。 与interop不同,它允许您生成Excel文件,而不需要在计算机上安装Excel,这意味着您也不必担心COM对象作为后台进程存在。 即使有适当的对象处理,Excel过程并不总是结束。
http://epplus.codeplex.com/releases/view/42439
我知道你说过要避免使用第三方库,但他们确实是要走的路。 Microsoft不build议自动执行Office。 无论如何,这并不意味着自动化。
http://support.microsoft.com/kb/257757
但是,您可能需要重新考虑将“几百万行”插入到单个电子表格中。
我曾经读过,创buildExcel表格的最简单方法是实际编写一个HTML表格,包括其结构和数据,并简单地命名文件.xls
。
Excel将能够转换它,但会显示一条警告,说明内容与扩展名不符。
有些事情可供您考虑…
如果这是客户端解决scheme,那么使用Interops没有任何问题。 如果这是服务器端解决scheme,请勿使用Interops。 如果您不想要第三方解决scheme,则可以使用Microsoft的OpenXML SDK。 免费。 我相信最新的有一个类似于Excel的对象模型。 在生成工作簿的过程中,要比使用interop方式生成工作簿的速度要快得多,这可能导致服务器崩溃。
我同意,第三方的DLL将比COM更干净,但如果你去互操作路线…
首先将数据放入一个二维string数组中,然后得到一个具有相同维数的excel范围对象并设置它(range.set_value2(oarray),我认为)。 使用任何其他方法是非常缓慢的。
还要确保你在finally块中使用了相应的清理代码。
我用ms-access-ole-db-driver实现了“export to Excel”,也可以通过以下方式读写excel文件:
准备(完成一次)
- 创build一个包含所有(头,格式,公式,图表)的空白数据区域的Excel文件作为模板来填充
- 给数据区(包括标题)一个名字(即“MyData”)
实施出口
- 将模板文件复制到目标文件夹
- 打开目标文件的oledb数据库连接
- 使用sql来插入数据
例
Excel table with Named area "MyData" Name, FamilyName, Birthday open System.Data.OleDb.OleDbConnection execute sql "Insert into MyData(Name, FamilyName, Birthday) values(...)"
我用这个连接string
private const string FORMAT_EXCEL_CONNECT = // @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=""Excel 8.0;HDR={1}"""; @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0;HDR={1}"""; private static string GetExcelConnectionString(string excelFilePath, bool header) { return string.Format(FORMAT_EXCEL_CONNECT, excelFilePath, (header) ? "Yes" : "No" ); }