2012-08-04 68 views
35

ご迷惑をかけてください。 私はopen xml sdkで新しいです。 私のプログラムは、いくつかのデータとDataTableをExcelファイル(テンプレート)にエクスポートする機能を持っています テンプレートでは、いくつかのプレースホルダにデータを挿入します。これは、作品は非常に良いことだが、私はあまりにも... 私のサンプルコードのDataTableを挿入する必要があります。Open Xml SDKを使用してDataTableをExcelにエクスポートするC#

using (Stream OutStream = new MemoryStream()) 
{ 
    // read teamplate 
    using (var fileStream = File.OpenRead(templatePath)) 
     fileStream.CopyTo(OutStream); 

    // exporting 
    Exporting(OutStream); 

    // to start 
    OutStream.Seek(0L, SeekOrigin.Begin); 

    // out 
    using (var resultFile = File.Create(resultPath)) 
     OutStream.CopyTo(resultFile); 

次の方法

private void Exporting(Stream template) 
{ 
    using (var workbook = SpreadsheetDocument.Open(template, true, new OpenSettings       { AutoSave = true })) 
    { 
     // Replace shared strings 
     SharedStringTablePart sharedStringsPart = workbook.WorkbookPart.SharedStringTablePart; 
     IEnumerable<Text> sharedStringTextElements = sharedStringsPart.SharedStringTable.Descendants<Text>(); 

     DoReplace(sharedStringTextElements); 
     // Replace inline strings 
     IEnumerable<WorksheetPart> worksheetParts = workbook.GetPartsOfType<WorksheetPart>(); 

     foreach (var worksheet in worksheetParts) 
     { 
      DoReplace(worksheet.Worksheet.Descendants<Text>()); 
     } 

     int z = 40; 
     foreach (System.Data.DataRow row in ExcelWorkXLSX.ToOut.Rows) 
     { 
      for (int i = 0; i < row.ItemArray.Count(); i++) 
      { 
       ExcelWorkXLSX.InsertText(workbook, row.ItemArray.ElementAt(i).ToString(), getColumnName(i), Convert.ToUInt32(z)); } 
       z++; 
      } 
     } 

    } 
} 

を輸出するのではなく、出力のDataTable slooooooooooooooooooooooowwwwwwwにこのフラグメント...

DataTableをExcelに高速かつ正確にエクスポートするにはどうすればよいですか?

+0

@

workbookPart.Workbook.Save();

私が投稿している完全なコードあなたはオープンXML SDKを使用する必要がありますか? – KLIM8D

+0

えええええええええええええええええええええええええええええええええええええええないではない、私のプログラムでは、xlsxファイルを読み込み、DataTableを使ってDataGridviewにデータを取得し、データを再チェックします。まず、私はinteropを使いましたが、それは優れていると非常に遅い必要があります。私の問題は輸出だけです。しかし、私はこの時点で多くのコードを書き直したくないです:) – user1576474

答えて

73

私はこの簡単な例を書きました。わたしにはできる。 1つのテーブルを持つ1つのデータセットでテストしましたが、それだけで十分でしょう。

私はすべてのセルをString(SharedStringsさえも)として扱ったことを考慮してください。 SharedStringsを使用したい場合は、私のサンプルを少し微調整する必要があります。

編集:この作業を行うには、WindowsBaseおよびDocumentFormat.OpenXmlの参照をプロジェクトに追加する必要があります。

は、

private void ExportDataSet(DataSet ds, string destination) 
     { 
      using (var workbook = SpreadsheetDocument.Create(destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook)) 
      { 
       var workbookPart = workbook.AddWorkbookPart(); 

       workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook(); 

       workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets(); 

       foreach (System.Data.DataTable table in ds.Tables) { 

        var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>(); 
        var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData(); 
        sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData); 

        DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>(); 
        string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart); 

        uint sheetId = 1; 
        if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0) 
        { 
         sheetId = 
          sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1; 
        } 

        DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName }; 
        sheets.Append(sheet); 

        DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); 

        List<String> columns = new List<string>(); 
        foreach (System.Data.DataColumn column in table.Columns) { 
         columns.Add(column.ColumnName); 

         DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); 
         cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; 
         cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName); 
         headerRow.AppendChild(cell); 
        } 


        sheetData.AppendChild(headerRow); 

        foreach (System.Data.DataRow dsrow in table.Rows) 
        { 
         DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); 
         foreach (String col in columns) 
         { 
          DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); 
          cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; 
          cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); // 
          newRow.AppendChild(cell); 
         } 

         sheetData.AppendChild(newRow); 
        } 

       } 
      } 
     } 
+4

私は 'workbook.WorkbookPart.Workbook = new ...'と 'workbook.WorkbookPart.Workbook.Sheets = new'はforeachループの外に移動するべきだと思います。それ以外の場合は、ループの各繰り返しがワークシートに置き換えられ、Excelファイルに最終的な「DataTable」のみが含まれます。 – Brian

+0

@Brian、それを指摘してくれてありがとう。私は1つのテーブルでしかテストしなかったので、元々働いていました。私はちょうどそれを修正しました、それは今大丈夫ですか? – eburgos

+2

ええ、それはうまく見えます。それほど重要ではないので、 '.Max(s => s.SheetId.Value) 'を呼び出すことは' .Select(s => s.SheetId.Value).Max() 'を呼び出すよりもきれいです。同様に、 'DataRow'は' DataColumn'インデクサを持っているので 'List columns'は必要ありません。 2番目の 'foreach'は' table.Columns'を繰り返し処理することができます。 – Brian

0

あなたはこの図書館を見てみることができます。私は自分のプロジェクトの1つとして使ってきましたが、データをエクスポートするためにのみ使用していました。

http://epplus.codeplex.com/

+0

ありがとう!これはアイデアです!私は輸出のためだけにそれを試してみます。 – user1576474

11

eburgosをお楽しみください、あなたのデータセット内の複数のDataTableを持っているときだけで一枚で残っていたので、それだけでスプレッドシートでそれらを上書きしたため、私は少しあなたのコードを修正しましたワークブック。私は基本的に、ワークブックが作成された部分をループから外しました。ここに更新されたコードがあります。

private void ExportDSToExcel(DataSet ds, string destination) 
{ 
    using (var workbook = SpreadsheetDocument.Create(destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook)) 
    { 
     var workbookPart = workbook.AddWorkbookPart(); 
     workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook(); 
     workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets(); 

     uint sheetId = 1; 

     foreach (DataTable table in ds.Tables) 
     { 
      var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>(); 
      var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData(); 
      sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);     

      DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>(); 
      string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart); 

      if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0) 
      { 
       sheetId = 
        sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1; 
      } 

      DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName }; 
      sheets.Append(sheet); 

      DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); 

      List<String> columns = new List<string>(); 
      foreach (DataColumn column in table.Columns) 
      { 
       columns.Add(column.ColumnName); 

       DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); 
       cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; 
       cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName); 
       headerRow.AppendChild(cell); 
      } 

      sheetData.AppendChild(headerRow); 

      foreach (DataRow dsrow in table.Rows) 
      { 
       DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); 
       foreach (String col in columns) 
       { 
        DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); 
        cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; 
        cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); // 
        newRow.AppendChild(cell); 
       } 

       sheetData.AppendChild(newRow); 
      } 
     } 
    } 
} 
+0

ありがとう、ちょうどブライアンのコメントを見て、私は私の同じことをしました。 – eburgos

0

私のライブラリhereを見ることができます。ドキュメントのセクションでは、データテーブルをインポートする方法について説明します。あなただけの

using (var doc = new SpreadsheetDocument(@"C:\OpenXmlPackaging.xlsx")) { 
    Worksheet sheet1 = doc.Worksheets.Add("My Sheet"); 
    sheet1.ImportDataTable(ds.Tables[0], "A1", true); 
} 

を記述する必要が

はそれが役に立てば幸い!

1

私はExcelライターに自分の書き出しを書きましたが、私のニーズにはまったく合致していませんでした。それは速く、実質的な細胞のフォーマットを可能にする。あなたは、私はそれが役に立てば幸い

https://openxmlexporttoexcel.codeplex.com/

でそれを確認することができます。

7

また、OpenXMLを使用してOpenXMLWriterも使用するC#/ VB.Net「Excelにエクスポート」ライブラリを作成しました。大きなファイルを書き込むときにメモリが不足することはありません。

完全なソースコード、およびデモは、こちらからダウンロードすることができます。

Export to Excel

それは使用して死んだのは簡単です。 書き込み先のファイル名と、DataTableDataSetまたはList<>を渡してください。

CreateExcelFile.CreateExcelDocument(myDataSet, "MyFilename.xlsx"); 

そして、あなたはASP.Netアプリケーションからそれを呼び出している場合、HttpResponseはにアウトファイルを書き込むためにそれを渡します。

CreateExcelFile.CreateExcelDocument(myDataSet, "MyFilename.xlsx", Response); 
+0

リンクが死んでいます... – Arwin

+1

申し訳ありません...!それは今生きているし、今再び蹴ります。 –

+0

@MikeGledhillどのような回避策を非同期で実行していますか?私は巨大なファイルに書き込もうとするとメモリの例外が出るので、関連するすべての記事を読んだことは、利用可能なメモリに限られているようですね。 – afr0

0

私は受け入れ答えを試してみましたが、開こうとしたときに生成されたExcelファイルが破損しているというメッセージを得ました。コードの行末を追加するなどの変更を加えることで修正できました。 Export DataTable to Excel with Open XML in c#

関連する問題