VC# で Excelファイル作成するアプリ作らされたでござるの巻

めちゃくちゃめんどくさかったのでメモ

まず、定義

using Excel = Microsoft.Office.Interop.Excel;

Excel.Application oXls;
oXls = new Excel.Application();
oXls.Visible = true;
oXls.DisplayAlerts = false;
Excel.Workbooks oWBooks = (Excel.Workbooks)oXls.Workbooks;
Excel.Workbook oWBook;
if (!System.IO.File.Exists(xlsName)) {
               oWBook = oWBooks.Add();
} else {

                oWBook = (Excel.Workbook)(oXls.Workbooks.Open(xlsName, Type.Missing, Type.Missing
                , Type.Missing, Type.Missing, Type.Missing, Type.Missing
                , Type.Missing, Type.Missing, Type.Missing, Type.Missing
                , Type.Missing, Type.Missing, Type.Missing, Type.Missing));

}

新規作成するか、既存のファイルを開く

Excel.Sheets oWSheets = oWBook.Worksheets;
Excel.Worksheet oWSheet = null;
int idx = -1;
for (int i = 1; i <= oWSheets.Count; i++) { 
     oWSheet = oWSheets[i] as Excel.Worksheet;
     if (oWSheet.Name == sheetName) {
         idx = i;
         break;
     }
}
if (idx == -1) {
   oWSheet = oWSheets.Add() as Excel.Worksheet;
   oWSheet.Name = sheetName;
}  

oWSheet.Activate(); 
目的のシート探して、なければ作る。あったらアクティブにする

Excel.Range rng;
rng = oWSheet.get_Range("A1", "D1");

object[,] val;
val = rng.get_Value(Type.Missing) as object[,];
val[1,1] = "日付";
val[1,2] = "OS";
val[1,3] = "所有者";
val[1,4] = "Image";
rng.set_Value(Type.Missing, val);

とりあえず、1行目設定
 

int rowidx = 2;
foreach (CData data in List) {
    string strItem;
    rng = oWSheet.get_Range("A" + rowidx.ToString(), "I" + rowidx.ToString());
    val[1, 1] = data.date.ToShortDateString();
    val[1, 2] = data.os.ToString();
    val[1, 3] = data.user.ToString();
    string imgName = data.file.ToString();
    Excel.Range rng2;
    if (System.IO.Directory.Exists(imgName) ) {
       val[1, 4] = "Image";
    } else {
       val[1, 4] = "";
    }
    rng.set_Value(Type.Missing, val);
    if ((string)val[1, 4] != "") {
       rng2 = oWSheet.get_Range("I" + rowidx.ToString());
       rng2.Hyperlinks.Add(rng2, files[0].ToString());
    }
    rowidx++;
}
rng = oWSheet.get_Range("A:D");
rng.EntireColumn.AutoFit();
rng = oWSheet.get_Range("A:A");
rng.NumberFormat = "yyyy/MM/dd";
try {
    oWBook.SaveAs(dirName);
} catch (Exception) {
     MessageBox.Show("ファイルに書き込めません");
}  
Cell使うと遅いので、レンジで一括転送。
ハイパーリンクとか書式設定とか、自動セル幅調整とか
使いそうなものも入ってまふ

おすすめ

1件の返信

  1. ks より:

    丁度最近同じように C#+Excel を仕事でやっている者です。
    適当に書くと遅くなるので、一括アクセスは大事ですよね。
    黒翼猫さんがどのバージョンを使われているか不明ですが、C#4.0 からは引数の省略が可能ですね。
    なので oXls.Workbooks.Open の後半の Type.Missing は全部省略できます。
    ReleaseComObject は RCW があればファイナライザで処理されるので不要、みたいなのですがこのあたりよくわかりません。
    ただ、最後に 2 回の GC.Collect() はやった方が良さそうです。
    https://blogs.msdn.microsoft.com/office_client_development_support_blog/2012/02/09/office-5/
    あと、アセンブリ参照でやるとバージョン依存ができてしまうので、私の場合は全部 COM を直叩きです。
    C# で書く意味がまるでない……

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です