2013年10月9日 星期三

C# 輸出 Excel

以下是使用 C# 輸出 Excel 檔的範例。
環境:Microsoft Visual Studio 2012 Express、 .Net Framework 4.5


將 Excel 物件程式庫加入參考
  1. 在「方案」底下的「參考」按右鍵,選擇「加入參考」
  2. 在「參考管理員」畫面,選左邊的「COM」,再搜尋 excel,勾選「Microsoft Excel 版本 Object Library」,版本會依安裝的 Excel 而不同,按「確定」加入參考。


將 System.Drawing 組件加入參考
如果要設定欄位背景、文字顏色,可將 System.Drawing 組件加入參考
在「參考管理員」畫面,選左邊的「組件」,再搜尋 drawing,勾選「System.Drawing」,按「確定」加入參考。



設定引用的 using
using Excel = Microsoft.Office.Interop.Excel;
using System.Drawing;


範例
static void Main(string[] args)
{
    // 設定儲存檔名,不用設定副檔名,系統自動判斷 excel 版本,產生 .xls 或 .xlsx 副檔名
    string pathFile = @"D:\test";

    Excel.Application excelApp;
    Excel._Workbook wBook;
    Excel._Worksheet wSheet;
    Excel.Range wRange;

    // 開啟一個新的應用程式
    excelApp = new Excel.Application();

    // 讓Excel文件可見
    excelApp.Visible = true;

    // 停用警告訊息
    excelApp.DisplayAlerts = false;

    // 加入新的活頁簿
    excelApp.Workbooks.Add(Type.Missing);

    // 引用第一個活頁簿
    wBook = excelApp.Workbooks[1];

    // 設定活頁簿焦點
    wBook.Activate();

    try
    {
        // 引用第一個工作表
        wSheet = (Excel._Worksheet)wBook.Worksheets[1];

        // 命名工作表的名稱
        wSheet.Name = "工作表測試";

        // 設定工作表焦點
        wSheet.Activate();

        excelApp.Cells[1, 1] = "Excel測試";

        // 設定第1列資料
        excelApp.Cells[1, 1] = "名稱";
        excelApp.Cells[1, 2] = "數量";
        // 設定第1列顏色
        wRange = wSheet.Range[wSheet.Cells[1, 1], wSheet.Cells[1, 2]];
        wRange.Select();
        wRange.Font.Color = ColorTranslator.ToOle(Color.White);
        wRange.Interior.Color = ColorTranslator.ToOle(Color.DimGray);

        // 設定第2列資料
        excelApp.Cells[2, 1] = "AA";
        excelApp.Cells[2, 2] = "10";

        // 設定第3列資料
        excelApp.Cells[3, 1] = "BB";
        excelApp.Cells[3, 2] = "20";

        // 設定第4列資料
        excelApp.Cells[4, 1] = "CC";
        excelApp.Cells[4, 2] = "30";

        // 設定第5列資料
        excelApp.Cells[5, 1] = "總計";
        // 設定總和公式 =SUM(B2:B4)
        excelApp.Cells[5, 2].Formula = string.Format("=SUM(B{0}:B{1})", 2, 4);
        // 設定第5列顏色
        wRange = wSheet.Range[wSheet.Cells[5, 1], wSheet.Cells[5, 2]];
        wRange.Select();
        wRange.Font.Color = ColorTranslator.ToOle(Color.Red);
        wRange.Interior.Color = ColorTranslator.ToOle(Color.Yellow);

        // 自動調整欄寬
        wRange = wSheet.Range[wSheet.Cells[1, 1], wSheet.Cells[5, 2]];
        wRange.Select();
        wRange.Columns.AutoFit();

        try
        {
            //另存活頁簿
            wBook.SaveAs(pathFile, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            Console.WriteLine("儲存文件於 " + Environment.NewLine + pathFile);
        }
        catch (Exception ex)
        {
            Console.WriteLine("儲存檔案出錯,檔案可能正在使用" + Environment.NewLine + ex.Message);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("產生報表時出錯!" + Environment.NewLine + ex.Message);
    }

    //關閉活頁簿
    wBook.Close(false, Type.Missing, Type.Missing);

    //關閉Excel
    excelApp.Quit();

    //釋放Excel資源
    System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);
    wBook = null;
    wSheet = null;
    wRange = null;
    excelApp = null;
    GC.Collect();

    Console.Read();
}


輸出結果:



參考資料:
HOW TO:使用 COM Interop 來建立 Excel 試算表 (C# 程式設計手冊)
HOW TO:使用 Visual C# 2010 功能存取 Office Interop 物件 (C# 程式設計手冊)
HOW TO:套用顏色至 Excel 範圍
HOW TO:以程式設計方式儲存活頁簿
How can I dispose my Excel Application
How to properly clean up Excel interop objects

9 則留言:

  1. 請問要如何讓他手動輸入的資料自動跑到下一欄,而不是又另開一個活頁簿

    回覆刪除
    回覆
    1. 請問有問題範例嗎?不懂您的意思,因文中並無手動輸入Excel的部分。

      刪除
    2. 不好意思,我上面說不太清楚
      我想讓他輸入帳號密碼,之後把帳號及密碼顯示在excel內,於是乎,我把設定第二列那邊改成了
      excelApp.Cells[2, 1] = textBox1.Text;
      excelApp.Cells[2, 2] = textBox2.Text;
      而我的程式是打在button內
      帳號、密碼都顯示在位置[2,1]及[2,2],但每次只要按一次button就會新增另一個excel檔
      而我是想讓他依序往下放[3,1][3,2]、[4,1][4,2]、[5,1][5,2].......

      刪除
    3. 請問每次按button,是否只執行
      excelApp.Cells[新位置, 新位置] = "新帳號";
      excelApp.Cells[新位置, 新位置] = "新密碼";

      刪除
    4. 您好,我測試做三個按鈕,將本文程式碼拆開整理成"開啟excel"、"寫入資料"、"關閉excel",分別放到三按鈕。
      其中"寫入資料",改成按1次只執行
      excelApp.Cells[1, 1] = "名稱";
      excelApp.Cells[1, 2] = "數量";

      按2次只執行
      excelApp.Cells[2, 1] = "AA";
      excelApp.Cells[2, 2] = "10";

      按3次只執行
      excelApp.Cells[3, 1] = "BB";
      excelApp.Cells[3, 2] = "20";

      .....


      測試結果,可正常在同一個excel、指定的位置寫入資料。

      會產生開新的excel的情況,只在另外多按"開啟excel"按鈕時。

      刪除
  2. 好的,非常感謝您抽空回覆我'^^
    其實我是想把excel當成SQL來用,把資料一筆一筆的傳進去
    可惜無法用mail溝通,如有問題,會再請教您
    再次感謝您抽空回覆我

    回覆刪除
  3. 為何用for迴圈想寫入資料
    for (int i = 0; i < READ_DATA_LENGHT; i++){excelApp.Cells[i + 1, 1] = scopeSamples[i];}
    結果程式變的不會存檔

    回覆刪除
    回覆
    1. 您好,如果能正常叫出excel填入資料,建議在存檔程式碼附近設中斷點觀察看看。

      刪除