用c#中的Open Xml SDK导出DataTable到Excel#

问题描述:

对不起,我的英语请。 我是新的打开xml sdk。 我的程序能够将一些数据和DataTable导出到Excel文件(模板) 在模板中,我将数据插入一些占位符。它的作品非常好,但我需要插入一个DataTable太... 我的示例代码:用c#中的Open Xml SDK导出DataTable到Excel#

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++; 
      } 
     } 

    } 
} 

但这个片段输出数据表slooooooooooooooooooooooowwwwwww ...

如何快速,真实地将DataTable导出到Excel?

+0

你需要使用开放XML SDK? – KLIM8D 2012-08-04 21:22:51

+0

嗯...不,但打开xml sdk快速读取/写入excel文件。在我的程序中,我读取xlsx文件,将数据抓取到datagridview(使用DataTable),重新检查数据。首先,我使用互操作,但它需要优秀且非常缓慢。我的问题只是出口。但是,此刻我不想重写很多代码:) – user1576474 2012-08-04 21:37:25

我写了这个简单的例子。这个对我有用。我只用一个数据集对其中的一个表进行了测试,但我想这对您而言可能已足够。

考虑到我将所有单元格视为字符串(甚至不是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 2013-03-13 18:16:13

+0

@布莱恩,谢谢你指出。它最初的工作原因是我只用一个表进行测试。我只是修好了,现在看起来好吗? – eburgos 2013-03-13 21:05:37

+2

是的,它看起来很好。作为一个不重要的地方,调用'.Max(s => s.SheetId.Value)'比调用'.Select(s => s.SheetId.Value).Max()'更清洁。同样,由于'DataRow'具有'DataColumn'索引器,因此不需要'列表列';第二个'foreach'也可以遍历'table.Columns'。 – Brian 2013-03-13 21:25:32

你可以试试看看这个库。我已经将它用于我的一个项目,并且发现使用起来非常简单,可靠且快速(我只用它来导出数据)。

http://epplus.codeplex.com/

+0

谢谢!这是一个主意!我会尝试只出口。 – user1576474 2012-08-04 22:00:38

eburgos,我已经修改了你的代码稍微因为当你在你的数据集的数据表的多个它只是覆盖它们在电子表格中,所以你只用在一张纸上留下工作簿。我基本上只是将创建工作簿的部分移出循环。这是更新的代码。

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

谢谢,刚刚看到Brian的评论,我也对我做了同样的评论。 – eburgos 2013-03-13 21:06:28

你可以看看我的图书馆here。在文档部分下,您将找到如何导入数据表。

你只需要编写

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

希望它能帮助!

我写了我自己的出口到Excel作家,因为没有别的完全满足我的需求。它速度很快,并允许大量格式的单元格。您可以在

https://openxmlexporttoexcel.codeplex.com/

审查,我希望它能帮助。

我还写了一个C#/ VB.Net“导出到Excel”库,使用OpenXML和(更重要的是)也使用OpenXmlWriter,因此在写入大文件时不会耗尽内存。

完整的源代码和演示,可以在这里下载:

Export to Excel

它的死很容易使用。 只需将它传递给您要写入的文件名即可,并且可以使用DataTable,DataSetList<>

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

而且如果你从一个ASP.Net应用程序中调用它,它传递的HttpResponse到文件写出来。

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

链接已经死了... – Arwin 2016-06-21 07:31:21

+1

对不起...!它现在还活着,踢起来。 – 2016-06-21 08:01:07

+0

@MikeGledhill任何解决方法异步执行它?当我尝试写入一个巨大的文件时,出现内存异常,我读过所有相关的帖子,看起来似乎只限于可用内存? – afr0 2018-01-10 01:24:43

我试着接受答案,并得到消息说生成的excel文件在试图打开时被破坏。我可以通过做一些修改来修复它,比如在代码的下面添加代码。

workbookPart.Workbook.Save();

我已经发布完整的代码@Export DataTable to Excel with Open XML in c#