2019-02-12

【Delphi】以程式碼建立 Excel 檔


 
uses
    ..., comobj, ...;
    
...
...
procedure TForm1.button1Click(Sender: TObject);
const
    xlWorksheet = -4167;

var
    myExcel, mySheet: Variant;
    sFileName: string;
    iRow: integer;
begin
    // 若資料夾不存在, 則建立
    CreateDir('C:\TEMP');
    sFileName := 'C:\TEMP\test.xls';
    Deletefile(sFileName);    // 則已存在同名檔案, 則刪除
    
    MyExcel := CreateOleOBject('Excel.Application');    // 新建一個 Excel 檔
    MyExcel.WorkBooks.Add;    // 新增活頁簿
    MyExcel.Visible := true;    // 程式在對 Excel 寫入資料期間, 可以看得到過程
                                // 若 false, 就看不到
    // 指定 工作表顯示比例
    mExcel.ActiveWindow.Zoom := 75;    // 顯示比例為 75%

    MyExcel.WorkBooks[1].Saveas(sFileName);    // 指定給 Excel 的檔名

    Showmessage('工作表數='+IntToStr(myExcel.WorkBooks[1].WorkSheets.Count));

    // 可能使用者的 Excel 預設開新檔案時自動產生多個工作表
    // 但我們只想留一個工作表
    // 刪除工作表
    while myExcel.WorkBooks[1].WorkSheets.Count>1 do
    begin
        myExcel.WorkBooks[1].WorkSheets[1].Delete;
    end;

    
    // 重命名工作表
    myExcel.WorkBooks[1].WorkSheets[1].Name := '公司員工';


    // 新增工作表
    myWorkSheets := MyExcel.WorkBooks[1].WorkSheets;
    myWorkSheets.Add(null, null, 新增的工作表數量, xlWorksheet);    // 注意要在 const 區 或 var 區 宣告 xlWorksheet 的值
    // 第 1 個參數: 新工作表要在目前哪個工作表前
    // 第 2 個參數: 新工作表要在目前哪個工作表後
    // 第 3 個參數: 新增工作表數量, 預設值為 1
    // 第 4 個參數: xlWorksheet(工作表,-4167)、 xlChart(圖表, -4109)、 xlExcel4MacroSheet(Excel 版本 4 巨集表, 3)、 xlExcel4IntlMacroSheet(Excel 版本 4 國際巨集表, 4)
    
    iRow := 1;

    // 切換目前編輯的工作表
    myExcel.WorkSheets[1].Activate;

    // 指定工作表
    mySheet := myExcel.WorkBooks[1].WorkSheets[1];
    mySheet.Cells[iRow,1] := '文字';    // 括號內 [橫列, 直欄]
    mySheet.Cells[iRow,1].Font.Bold := True;    // 設定粗體字
    
    // 合併儲存格
    mySheet.Range['B1','E1'].Merge;
    // 另一種寫法, 好處是不用去算第 ? 欄是什麼英文字母
    mySheet.Range[mySheet.Cells[1,2],mySheet.Cells[1,5]].Merge;

    // 輸入的資料是數字, 但要 Excel 當做文字處理(例如:電話號碼)
    mySheet.Cells[iRow,1] := '''0912345678';    // 可以看到該儲存格的左上角有個綠色的三角標記
    // 另一種表示法
    mySheet.Cells[iRow,1].NumberFormatLocal := '@';    // 指定儲存格格式為文字, 但注意要在儲存格存入值前指定
                                                       // 不然數字太大, 會馬上被轉成科學記號表示法
    mySheet.Cells[iRow,1] := '0912345678';

    Inc(iRow);    // 移至下一列

    mySheet.Cells[iRow,1] := 1;    // 第一欄: A
    mySheet.Cells[iRow,2] := 2;    // 第二欄: B
    mySheet.Cells[iRow,3] := 3;    // 第三欄: C
    mySheet.Cells[iRow,4] := 4;    // 第四欄: D
    mySheet.Cells[iRow,5] := 5;    // 第五欄: E
    // 儲存格內寫公式
    mySheet.Cells[iRow,6] := '=SUM(A'+IntToStr(iRow)+':E'+IntToStr(iRow)+')';
    // 另一種表示法, 這種寫法的好處是不用去算第 ? 欄是什麼英文字母
    mySheet.Cells[iRow,6] := '=SUM(R'+IntToStr(iRow)+'C1:R'+IntToStr(iRow)+'C5)';

    // 給予某個儲存格別名
    mySheet.Cells[iRow,6].Name := 'TotalAmount';
    // 使用時機舉例
    // 列數不確定
    // 每列的第 1 欄為單品金額,
    // 第 2 欄是單品金額佔總金額的百分比, 計算公式為 第 1 欄/總金額 * 100
    // 要列完所有單品金額後的下一列才會列總金額
    // 這時還無法得知總金額在第幾列, 所以(以第 1 列為例) 公式可以寫 '=A1/TotalAmount'


    // 儲存格是數字
    // 指定儲存格的格式
    mySheet.Cells[iRow,6].NumberFormatLocal := '#,##0;[紅色]-#,##0';    // 數值(整數位 三位一撇),且負值時以紅色顯示, 
                                                    // 正, 負值表示法中間以 分號 隔開
                                                    // 而且很妙, 一定要寫中文, 若寫 [red] 程式還會掛掉
    mySheet.Cells[iRow,6].NumberFormatLocal := '0.00%';  // 百分比(小數兩位)


    // 單一儲存格畫框線
    // Borders 內的數字 5:左上右下斜線, 6:左下右上斜線, 7:左邊線, 8:上邊線, 9:下邊線, 10:右邊線, 11:垂直線, 12:水平線
    mySheet.Cells[iRow,4].Borders[6].LineStyle := 1;    // 1:實線, -4115:短虛線, 4:長短虛線, 5:長短短虛線, -4118:細虛線, -4119:雙實線
    mySheet.Cells[iRow,4].Borders[6].Weight := 1;    // 框線粗細, 數字愈大愈粗

    // 指定某一區域劃框線
    mySheet.Range['A1','I8'].Borders[7].LineStyle := 1;
    mySheet.Range['A1','I8'].Borders[8].LineStyle := 1;
    mySheet.Range['A1','I8'].Borders[9].LineStyle := 1;
    mySheet.Range['A1','I8'].Borders[10].LineStyle := 1;
    mySheet.Range['A1','I8'].Borders[11].LineStyle := 1;
    mySheet.Range['A1','I8'].Borders[12].LineStyle := 1;

    // 凍結窗格
    mySheet.Cells[2,1].Select;    // 指定要凍結的位置
    myExcel.ActiveWindow.FreezePanes := true;

    // 最適欄寬
    mySheet.Cells.EntireColumn.AutoFit;

    // 變更工作表名稱
    mySheet.Name := '自定工作表名稱';
end;