20 votes

Ouvrir le kit de développement logiciel Open XML 2.0 pour accéder à la feuille de calcul Excel 2010 par son nom

J'ai une feuille de calcul Excel 2010 qui comporte 3 feuilles de travail nommées Feuil1, Feuil2 et Feuil3.

Je cherche à obtenir une référence à une feuille de travail par son nom.

Je utilise le code :

using (SpreadsheetDocument myWorkbook = SpreadsheetDocument.Open(FileName, true))
{
    // Accéder à la partie principale du classeur, qui contient toutes les références
    WorkbookPart workbookPart = myWorkbook.WorkbookPart;

    WorksheetPart worksheetPart = workbookPart.WorksheetParts.Last(); 

    // cela me donne Feuil1
    SheetData sheetData = worksheetPart.Worksheet.GetFirstChild();
}

J'essaie d'obtenir une référence à Feuil2, mais je ne trouve pas de moyen de le faire.

Je me rapproche, mais je n'y suis pas encore :

var x = workbookPart.Workbook.Sheets.Where(s=> s.GetAttribute("name", "").Value == "Feuil2").FirstOrDefault();

Cela me donne une référence à la feuille, mais pas aux données de la feuille

Merci

40voto

amurra Points 8822

Ce que vous voulez vraiment est le WorksheetPart qui contient les SheetData que vous recherchez. Récupérer les Sheets sous le Workbook ne vous donnera que certaines métadonnées sur les feuilles de calcul. Voici un exemple de comment récupérer ce WorksheetPart (n'hésitez pas à ajouter des vérifications d'erreur comme bon vous semble, car je suppose que le sheetName existe déjà en appelant First et non FirstOrDefault)

public WorksheetPart GetWorksheetPart(WorkbookPart workbookPart, string sheetName)
{
    string relId = workbookPart.Workbook.Descendants().First(s => sheetName.Equals(s.Name)).Id;
    return (WorksheetPart)workbookPart.GetPartById(relId);
}

Ensuite, utilisez simplement votre code ci-dessus pour récupérer la bonne référence SheetData et vous pourrez trouver les données que vous voulez à partir de là.

7voto

Jess Points 2039

Voici du code pour traiter une feuille de calcul avec un onglet ou un nom de feuille spécifique et le stocker dans quelque chose comme CSV. (J'ai choisi un tuyau au lieu d'une virgule).

J'aimerais que ce soit plus facile d'obtenir la valeur d'une cellule, mais je pense que c'est ce avec quoi nous sommes coincés. Vous pouvez voir que je fais référence aux documents MSDN où j'ai obtenu la plupart de ce code. C'est ce que Microsoft recommande.

    /// 
    /// Code obtenu sur : https://msdn.microsoft.com/en-us/library/office/gg575571.aspx
    /// 
    [Test]
    public void WriteOutExcelFile()
    {
        var fileName = "ExcelFiles\\File_With_Many_Tabs.xlsx";
        var sheetName = "Formulaire de soumission"; // Nom de l'onglet existant.
        using (var document = SpreadsheetDocument.Open(fileName, isEditable: false))
        {
            var workbookPart = document.WorkbookPart;
            var sheet = workbookPart.Workbook.Descendants().FirstOrDefault(s => s.Name == sheetName);
            var worksheetPart = (WorksheetPart)(workbookPart.GetPartById(sheet.Id));
            var sheetData = worksheetPart.Worksheet.Elements().First();

            foreach (var row in sheetData.Elements())
            {
                foreach (var cell in row.Elements())
                {
                    Console.Write("|" + GetCellValue(cell, workbookPart));
                }
                Console.Write("\n");
            }
        }
    }

    /// 
    /// Code obtenu sur : https://msdn.microsoft.com/en-us/library/office/hh298534.aspx
    /// 
    /// 
    /// 
    /// 
    private string GetCellValue(Cell cell, WorkbookPart workbookPart)
    {
        if (cell == null)
        {
            return null;
        }

        var value = cell.CellFormula != null
            ? cell.CellValue.InnerText 
            : cell.InnerText.Trim();

        // Si la cellule représente un nombre entier, vous avez terminé.
        // Pour les dates, ce code retourne la valeur sérialisée qui
        // représente la date. Le code gère les chaînes et les booléens individuellement.
        // Pour les chaînes partagées, le code
        // recherche la valeur correspondante dans la table de chaînes partagées.
        // Pour les booléens, le code convertit la valeur en
        // les mots TRUE ou FALSE.
        if (cell.DataType == null)
        {
            return value;
        }
        switch (cell.DataType.Value)
        {
            case CellValues.SharedString:

                // Pour les chaînes partagées, recherchez la valeur dans le
                // table de chaînes partagées.
                var stringTable =
                    workbookPart.GetPartsOfType()
                        .FirstOrDefault();

                // Si la table de chaînes partagées est manquante, quelque chose
                // ne va pas. Renvoie l'index qui est dans
                // la cellule. Sinon, recherchez le texte correct dans
                // la table.
                if (stringTable != null)
                {
                    value =
                        stringTable.SharedStringTable
                            .ElementAt(int.Parse(value)).InnerText;
                }
                break;

            case CellValues.Boolean:
                switch (value)
                {
                    case "0":
                        value = "FALSE";
                        break;
                    default:
                        value = "TRUE";
                        break;
                }
                break;
        }
        return value;
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X