2009-06-29 8 views
4

C#を使用すると、リストのリスト(つまりList<List<T>>)をExcel 2003に直接エクスポートできますか?C#リストをExcelにエクスポート

大きなテキストファイルを解析してExcelにエクスポートしています。一度に1つのセルを書き込むと、オーバーヘッドが大きくなりすぎます。私はList<T>を使用して、行や列の数を指定することを心配する必要がないようにしました。

現在、私はファイルの終わりまで待ってから、List<List<object>>の内容を2次元配列に入れます。次に、配列をExcel.Rangeオブジェクトの値として設定できます。それは動作しますが、行や列の数を気にせずにList of Listsを取り、A1からどこにでもワークシートにダンプするだけで済むようです。

ここで私は交換または上改善したいコードの抜粋です:これは動作します

object oOpt = System.Reflection.Missing.Value; //for optional arguments 
Excel.Application oXL = new Excel.Application(); 
Excel.Workbooks oWBs = oXL.Workbooks; 
Excel._Workbook oWB = oWBs.Add(Excel.XlWBATemplate.xlWBATWorksheet); 
Excel._Worksheet oSheet = (Excel._Worksheet)oWB.ActiveSheet; 

int numberOfRows = outputRows.Count; 
int numberOfColumns = int.MinValue; 

//outputRows is a List<List<object>> 
foreach (List<object> outputColumns in outputRows) 
{ 
     if (numberOfColumns < outputColumns.Count) 
     { numberOfColumns = outputColumns.Count; } 
} 

Excel.Range oRng = oSheet.get_Range("A1", oSheet.Cells[numberOfRows,numberOfColumns]); 

object[,] outputArray = new object[numberOfRows,numberOfColumns]; 

for (int row = 0; row < numberOfRows; row++) 
{ 
     for (int col = 0; col < outputRows[row].Count; col++) 
     { 
       outputArray[row, col] = outputRows[row][col]; 
     } 
} 

oRng.set_Value(oOpt, outputArray); 

oXL.Visible = true; 
oXL.UserControl = true; 

が、私はむしろ、アレイを作成するの中間ステップを持つよりも、Excelに直接リストを使用したいですちょうどExcelのために。何か案は?

答えて

8

戦略的に正しく実行しています。ジョーは言うように、セルを1つずつループするのではなく、1つのショットで値の配列全体を渡すことによって、セルの値の割り当てを実行するのは非常に高速です。

ExcelはCOMベースであり、.NET interopを介してExcelで動作します。 interopはジェネリックを知らないので、残念なことに、リスト<T>などを渡すことはできません。 2次元アレイは本当に唯一の方法です。

つまり、コードをきれいにして管理しやすくする方法がいくつかあります。ここではいくつかの考えがあります:

(1)あなたは、.NET 3.0を使用している場合は、よりあなたのコードを短くするためにLINQを使用することができます。

int numberOfColumns = int.MinValue; 

foreach (List<object> outputColumns in outputRows) 
{ 
     if (numberOfColumns < outputColumns.Count) 
     { numberOfColumns = outputColumns.Count; } 
} 

1ライン:

int numberOfColumns = outputRows.Max(list => list.Count); 

( 2)_Worksheetまたは_Workbookインターフェイスは使用しないでください。代わりにWorksheetまたはWorkbookを使用してください。ディスカッションについては、Excel interop: _Worksheet or Worksheet?を参照してください。

(3)Range.Resizeメソッドを使用することを検討してください。これは、C#でRange.get_Resizeとなります。私は実際にあなたの範囲のサイズを設定している方法が好きです。しかし、それは私があなたが知りたいかもしれないと思ったものです。たとえば、ここにあなたのライン:

Excel.Range oRng = oSheet.get_Range("A1", oSheet.Cells[numberOfRows,numberOfColumns]); 

に変更することでした:

Excel.Range oRng = 
    oSheet.get_Range("A1", Type.Missing) 
     .get_Resize(numberOfRows, numberOfColumns); 

(4)あなたはApplication.UserControltrueに設定する必要はありません。ユーザーにExcelを見えるようにするだけで十分です。 UserControlのプロパティは、あなたが思うようなことをしていません。 (ヘルプファイルhereを参照してください)ユーザーがExcelを制御できるかどうかを制御する場合は、ワークシート保護を利用するか、に設定してApplication.Interactive = falseに設定すると、ユーザーをロックアウトできます。 (ごくまれですが)ユーザーがExcelを使用できるようにしたい場合は、単に見えるようにするだけで十分です。このことができますこのことができます

object oOpt = System.Reflection.Missing.Value; //for optional arguments 
Excel.Application oXL = new Excel.Application(); 
Excel.Workbooks oWBs = oXL.Workbooks; 
Excel.Workbook oWB = oWBs.Add(Excel.XlWBATemplate.xlWBATWorksheet); 
Excel.Worksheet oSheet = (Excel.Worksheet)oWB.ActiveSheet; 

//outputRows is a List<List<object>> 
int numberOfRows = outputRows.Count; 
int numberOfColumns = outputRows.Max(list => list.Count); 

Excel.Range oRng = 
    oSheet.get_Range("A1", oOpt) 
     .get_Resize(numberOfRows, numberOfColumns); 

object[,] outputArray = new object[numberOfRows, numberOfColumns]; 

for (int row = 0; row < numberOfRows; row++) 
{ 
    for (int col = 0; col < outputRows[row].Count; col++) 
    { 
     outputArray[row, col] = outputRows[row][col]; 
    } 
} 

oRng.set_Value(oOpt, outputArray); 

oXL.Visible = true; 

希望...

マイク

+0

ありがとう!私たちは.NET 3.0ではありませんが、皆さんの説明を参考にしていただきたいと思います。 – reverendlarry

+0

問題ありません。うれしいことです。 :-)項目#1だけが.NET 3.0と関連していましたが、それ以外はすべての.NET Frameworkに適用されます。 LINQは3.0への移行を検討する主な理由です。それはすべてのコードに革命を起こすことはありませんが、LINQは非常に優れた機能です。 –

+1

ありがとう!これは完全に、明確なupvoteを働いた!しかし、助けになるかもしれない小さな細部。私はこのコードに 'oXL.Quit; 'という文章を追加しなければならなかった。もしそうでなければプロセスは実行し続けていて、ある時点でエラーが出始めたからだ。 – Soph

1

Excelに二次元配列を渡す方が、一度に1つずつセルを更新するよりも高速です。

リストの値からオブジェクトの2次元配列を作成し、Excelの範囲を配列の次元に変更してから、range.set_Valueを呼び出して2次元配列を渡します。

+0

これは私が現在やっていることです。配列の代わりに 'List 'を使うつもりなら、最初にすべてを中間配列にロードせずにExcelにデータを取得する方法があるかもしれません。 – reverendlarry

0
List<"classname"> getreport = cs.getcompletionreport(); 

var getreported = getreport .Select(c => new { demographic = c.rName); 

希望:

全体的には、心の中でこれらを、私はあなたのコードはこのような何かを見ることができると思います

ここで、cs.getcompletionreport()は参照クラスファイルです。 App

関連する問題