2011-01-22 164 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" 
      ); 
    } 
相關問題