locked
Modifier un fichier Excel OpenXML RRS feed

  • Question

  • Bonjour,

     

    je cherche à mettre à jour une feuille d'un document Excel existant.

    Voici le code que j'utilise pour sauvegarder le package :

    Package pkgOutputDoc = Package.Open(fileName, FileMode.Create, FileAccess.ReadWrite);

    Uri uri = new Uri(string.Format("/xl/worksheets/sheet{0}.xml", sheetNumber), UriKind.Relative);

    PackagePart partSheetXml = pkgOutputDoc.CreatePart(uri, "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml");

    StreamWriter streamStartPart = new StreamWriter(partSheetXml.GetStream(FileMode.Create, FileAccess.Write));

    xmlStartPart.Save(streamStartPart);

    streamStartPart.Close();

    pkgOutputDoc.Flush();

    pkgOutputDoc.CreateRelationship(uri, TargetMode.Internal,

    "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",

    "rId1");

    pkgOutputDoc.Flush();

    pkgOutputDoc.Close();

    Le problème est qu'avec ce code, tous les fichiers présents dans le package sont supprimés alors que je voudrait seulement écraser la feuille que je souhaite mettre à jour.

    Auriez-vous une idée du problème ?

     

    merci.

    samedi 7 juillet 2007 15:32

Toutes les réponses

  • Bonjour mathmax,

    cela est tout à fait logique de par ton code. Je te redirige vers les code snippets mise à disposition à cette adresse (localisé en FR) : http://www.microsoft.com/downloads/details.aspx?displaylang=fr&FamilyID=8d46c01f-e3f6-4069-869d-90b8b096b556 qui te permettront de trouver des exemples de codes comme celui que tu essayes de faire !

     

    L'approche pour retrouver la partie n'est pas exactement celle que tu devrais adopter, je m'explique, normalement on retrouve une partie à l'aide des relations du paquet ou avec la méthode GetPart(Uri). A noter que ton code crée une nouvelle partie et n'est donc pas capable de prendre une partie existante et de la modifier par la suite (normalement si la partie existe, tu devrais avoir une exception InvalidOperationException). Je rajouterais aussi que pour modifier une partie, il ne faut pas supprimer la partie et la recréer, mais simplement changer son contenu (si tu modifies une partie, ici une feuille, la relationvers celle-ci est déjà présente et n'est pas effacé donc tu n'as pas à la recréer).

     

    De plus, tu crées la relation au mauvais endroit, ou du moins pas sur la bonne partie. Les relations dépendent de la partie à laquelle elles sont associées (les relations de paquet sont une exception). En fait je ne sais pas réellement ce que tu essayes de faire  avec le code suivant :

     

    pkgOutputDoc.CreateRelationship(uri, TargetMode.Internal,

    "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",

    "rId1");

    pkgOutputDoc.Flush();

     

    Pour ma part voici un code qui pourrait t'aider (snippet remaniée) :

     

    public string ObtenirFeuille(string nomFichier, string nomFeuille)

    {

    const string typeRelationDocument = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";

    const string schemaFeuille = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";

    const string typeRelationChainePartagee = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings";

    const string schemaChainePartagee = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";

    string valeurCellule = null;

     

    using (Package paquetExcel = Package.Open(nomFichier, FileMode.Open, FileAccess.Read))

    {

    PackagePart partieDocument = null;

    Uri uriDocument = null;

    // Obtenir la partie principale du document (workbook.xml).

    foreach (System.IO.Packaging.PackageRelationship relation in paquetExcel.GetRelationshipsByType(typeRelationDocument))

    {

    // Il ne devrait y avoir qu'une seule partie document dans le paquet.

    uriDocument = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), relation.TargetUri);

    partieDocument = paquetExcel.GetPart(uriDocument);

    // Il ne devrait y avoir qu'une seule instance, et nous sortons quoi qu'il en soit:

    break;

    }

    if (partieDocument != null)

    {

    // Charge le contenu du classeur.

    XmlDocument doc = new XmlDocument();

    doc.Load(partieDocument.GetStream());

     

    NameTable nt = new NameTable();

    XmlNamespaceManager gestionnaireNS = new XmlNamespaceManager(nt);

    gestionnaireNS.AddNamespace("d", schemaFeuille);

    gestionnaireNS.AddNamespace("s", schemaChainePartagee);

    string chaineRecherche = string.Format("//dTongue Tiedheet[@name='{0}']", nomFeuille);

    XmlNode noeudFeuille = doc.SelectSingleNode(chaineRecherche, gestionnaireNS);

    if (noeudFeuille != null)

    {

    // Obtient l'attribut relId:

    XmlAttribute attributRelation = noeudFeuille.Attributes["r:id"];

    if (attributRelation != null)

    {

    string relId = attributRelation.Value;

    // PremiŠrement, obtient la relation entre le document et la feuille.

    PackageRelationship relationFeuille = partieDocument.GetRelationship(relId);

    Uri uriFeuille = PackUriHelper.ResolvePartUri(uriDocument, relationFeuille.TargetUri);

    PackagePart partieFeuille = paquetExcel.GetPart(uriFeuille);

    // Charge le contenu de la feuille dans un document XML.

    XmlDocument docFeuille = new XmlDocument(nt);

    docFeuille.Load(partieFeuille.GetStream());

     

    ==> Inclus le code que tu veux pour modifier la feuille

     

     

    }

    }

    }

    }

    }

    }

    }

    }

    }

     

    Ne pas oublier le Close ensuite sur le paquet ;-)

     

    J'espère que cela t'aidera !

    lundi 9 juillet 2007 18:15