L'exportation DataTable pour Excel avec le SDK Open Xml en c#

Désolé pour mon anglais s'il vous plaît. Je suis nouveau dans open xml sdk. Mon programme ont la capacité d'exporter certaines données et DataTable pour le fichier Excel (modèle) Dans le modèle, j'insère les données de certains espaces. Il fonctionne très bien, mais je dois insérer un datable aussi... Mon exemple de code:

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);

prochaine méthode pour exporter

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

    }
}

mais ce fragment à la sortie DataTable sloooooooooooooooooooooooowwwwwww...

Comment puis-je exporter DataTable pour exceller rapidement et vraiment?

35
demandé sur John Conde 2012-08-04 22:42:59

7 réponses

j'ai écrit cet exemple rapide. Il fonctionne pour moi. Je ne l'ai testé qu'avec un ensemble de données avec une table à l'intérieur, mais je suppose que cela peut être suffisant pour vous.

prendre en considération que j'ai traité toutes les cellules comme des cordes (pas même des cordes partagées). Si vous voulez utiliser des cordes de rasoir vous pourriez avoir besoin de modifier mon échantillon un peu.

Edit: pour faire ce travail il est nécessaire d'ajouter WindowsBase et DocumentFormat.Références à OpenXml projet.

Profiter,

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

                }
            }
        }
77
répondu eburgos 2013-12-26 13:02:21

eburgos, j'ai légèrement modifié votre code parce que quand vous avez plusieurs datatables dans votre ensemble de données, c'était juste en les écrasant dans le tableur, donc il ne vous restait qu'une feuille dans le classeur. Je viens de déplacer la partie où le cahier est créé hors de la boucle. Voici le code mis à jour.

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);
            }
        }
    }
}
13
répondu msr 2012-11-16 10:20:47

j'ai aussi écrit un C# / VB.Net" Export to Excel " bibliothèque, qui utilise OpenXML et (plus important) utilise également OpenXmlWriter, donc vous ne manquerez pas de mémoire lors de l'écriture de gros fichiers.

code source Complet, ainsi qu'une démonstration, peut être téléchargé ici:

Exporter vers Excel

C'est très facile à utiliser. Passez-lui juste le nom du fichier auquel vous voulez écrire, et un DataTable, DataSet ou List<>.

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

Et si vous appelez à partir d'un ASP.Net l'application, la passer à l' HttpResponse pour écrire le fichier.

CreateExcelFile.CreateExcelDocument(myDataSet, "MyFilename.xlsx", Response);
7
répondu Mike Gledhill 2016-06-21 08:00:51

j'ai écrit mon propre export vers Excel writer parce que rien d'autre ne répondait vraiment à mes besoins. Il est rapide et permet un formatage substantiel des cellules. Vous pouvez revoir au

https://openxmlexporttoexcel.codeplex.com/

j'espère que cela aide.

1
répondu Steve 2014-04-10 17:38:39

vous pourriez essayer de jeter un oeil à cette libaire. Je l'ai utilisé pour un de mes projets et l'a trouvé très facile à utiliser, fiable et rapide (je n'ai utilisé pour l'exportation des données).

http://epplus.codeplex.com/

0
répondu KLIM8D 2012-08-04 21:47:11

Vous pouvez avoir un coup d'oeil à ma bibliothèque ici. Dans la section documentation, vous trouverez comment importer une table de données.

Il suffit d'écrire

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

j'Espère que ça aide!

0
répondu jamdagni86 2013-10-29 09:23:03

j'ai essayé réponse acceptée et j'ai reçu un message disant que le fichier excel généré est corrompu en essayant d'ouvrir. J'ai pu le corriger en faisant quelques modifications comme ajouter la fin en dessous de la ligne du code.

workbookPart.Workbook.Save();

j'ai posté le code complet@Exporter DataTable Excel Open XML en c#

0
répondu Saranga 2015-11-27 13:06:14