2011-01-22 199 views
9

我有一些表格数据,我想转换成Excel表格。用C#创建Excel表最简单的方法是什么?

软件可供选择:

  • .NET 4(C#)
  • Excel 2010中(使用Excel API是OK)
  • 我宁愿不使用任何第三方库

关于这些数据的信息:

  • 几百万ro WS
  • 5列,
  • 在我的剧本我目前使用嵌套表的数据结构,但我可以改变
  • 性能脚本并不重要的所有字符串(非常简单和普通表结构)

在线搜索提供了许多结果,我很困惑我是否应该使用OleDb,ADO RecordSets或其他。其中一些技术似乎对我的情况有点矫枉过正,有些似乎可能已经过时。

这样做最简单的方法是什么?

编辑:这是一个一次性脚本,我打算从我出席的桌面上运行。

+0

最简单的方法涉及一个像样的第三方库:-)寻找“Excel自动化”。 MSDN上应该有一些知识库文章等。请注意,使用Excel COM Interop比*大多数/所有第三方工具显着更慢*,并期望在非服务环境中运行等。处理“几百万行”也可能存在问题(从不尝试靠近这些限制的任),甚至不包括额外的资源/时间开销 - 不是批评性的,并不排除“今天某个时候”:) – 2011-01-22 04:41:48

+1

此外,对于这样一个简单的转储,考虑CSV-> Excel(手动或通过自动化)而不是添加所有一次一行(几百万是几百万!)。另一种选择是通过流式编写器等直接转储到XSLX(XML,只需抓住“模板”)。当然,这些步骤仅存在于第三方库中。 – 2011-01-22 04:51:06

+0

您在我的Excel 2010工作表中看到的1,048,576行适合“几百万行”的方法是什么?我与泰勒达成协议,将钱花在Aspose.Cells for .NET(开发者企业订购899美元)等第三方库上。 – tawman 2011-01-22 05:01:16

回答

5

为了避免使用第三方工具和使用COM对象,请遵守你的请求,这里是我该怎么做的。

  1. 添加对项目的引用:Com对象 Microsoft Excel 11.0。
  2. 顶部模块添加的:

    using Microsoft.Office.Interop.Excel; 
    
  3. 添加事件的逻辑是这样的:

    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(); 
    
    } 
    
8

避免不惜一切代价使用COM互操作。使用第三方API。真。事实上,如果你在做这个服务器端,你实际上必须这样做。有很多免费的选择。我强烈建议使用EPPlus,但也有可用的企业级解决方案。我已经使用了EPPlus,数量很大,而且效果很好。与interop不同,它允许您生成Excel文件,而不需要在计算机上安装Excel,这意味着您也不必担心COM对象作为后台进程存在。即使有适当的对象处置,Excel过程并不总是结束。

http://epplus.codeplex.com/releases/view/42439

我知道你说你想避免第三方库,但他们真的是要走的路。 Microsoft不建议自动化Office。无论如何,这并不意味着自动化。

http://support.microsoft.com/kb/257757

但是,您可能要重新考虑将“几百万行”变成了一个电子表格。

1

我同意,第三方DLL会比COM更清洁,但如果你去的互操作路线...

相传的最佳方式来填充一个Excel工作表是,首先将数据放入一个2维字符串数组,然后得到一个具有相同维度的excel范围对象并设置它(range.set_value2(oarray)我认为)。使用任何其他方法是非常缓慢。

另外,请确保您在finally块中使用了相应的清理代码。

2

为您考虑有些事情......

如果这是一个客户端使用Interop没有任何问题。 如果这是服务器端解决方案,请勿使用Interops。如果您不想要第三方解决方案,则可以选择使用Microsoft的OpenXML SDK。免费。我相信最新的一个有类似于Excel的对象模型。在生成工作簿的过程中,要比使用可能导致服务器无法工作的interop方式快得多。

3

我曾经读过创建Excel表格最简单的方法是写一个HTML表格,包括它的结构和数据,并简单地命名文件.xls

Excel将能够转换它,但会显示一条警告,指出内容与扩展名不符。

1

我实现了与MS-访问OLE-DB驱动程序 “导出到Excel”,它可以读取和写入Excel文件的follwoing方式:

准备(做一次)

  • 创建包含所有(标题,格式化,公式,图表)用作为模板将被填充
  • 给数据区(包括标题)的名称(即,“迈德特”)的空数据区的Excel文件

实现出口

  • 复制模板文件到目标文件夹
  • 打开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(...)" 

我用这个连接字符串

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" 
      ); 
    } 
相关问题