Modification d'un document .dotx via OpenXML

Résolu
stefantastiq Messages postés 9 Date d'inscription dimanche 2 avril 2006 Statut Membre Dernière intervention 2 février 2012 - 29 mai 2008 à 18:08
billalch Messages postés 3 Date d'inscription lundi 26 décembre 2011 Statut Membre Dernière intervention 2 février 2012 - 2 févr. 2012 à 15:49
Bonjour,
Mon but est de créer un document word à partir d'un modèle word 2007 existant via OpenXML par exemple.
J'ai un petit bout de code qui m'ouvre un flux sur le document voulu et me permet normalement de le modifier.
Seulement le hic est la comment le modifier de manière à insérer un texte voulu à un endroit voulu soit en  remplaçant des balises (qui seraient representées par des mots clés) soit en utilisant les signets. un peu le mode opératoire du publipostage.

using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

using System.IO;
using System.Xml;
using System.IO.Packaging;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        string docWord = @"C:\test.docx";
      
        //overture du package en lecture/écriture
        Package officePackage = Package.Open(docWord, FileMode.Open, FileAccess.ReadWrite);

        //type de contenu pour la partie principale
        const String officeDocRelType = @"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";

        PackagePart mainPart = null;
        Uri documentUri = null;
        //on récupère la partie contenant les propriétés
        foreach (PackageRelationship relationship in officePackage.GetRelationshipsByType(officeDocRelType))
        {
            documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), relationship.TargetUri);
            mainPart = officePackage.GetPart(documentUri);
            break;
        }

        if (mainPart != null)
        {
            //chargement de la partie dans un XmlDocument
            XmlDocument doc = new XmlDocument();
            doc.Load(mainPart.GetStream());
            // string tmp2 = doc.GetElementById("idnode").InnerText;
            if (doc.DocumentElement.InnerText.Contains("[RS]"))
            {
                string tmp = doc.DocumentElement.InnerText.Replace("[RS]", "evolution_multimedia");
                doc.DocumentElement.InnerText = tmp;
            }
            doc.Save(mainPart.GetStream(FileMode.Open, FileAccess.ReadWrite));
        }
       
        //fermeture du package
        officePackage.Close();
    }
}
Merci d'avance pour votre aide .

13 réponses

stefantastiq Messages postés 9 Date d'inscription dimanche 2 avril 2006 Statut Membre Dernière intervention 2 février 2012
30 mai 2008 à 12:04
J'ai trouver ma solution! J'ai intégré des sortes de balises ou repères textuels dans mon texte via word 2007 par exemple :  [RS]
Puis j'utilise ce code :

    using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

using System.IO;
using System.Xml;
using System.IO.Packaging;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void Button1_Click(object sender, EventArgs e)
    {
       //chemin du document word
        string docWord = @"C:\test5.docx";

        //overture du package en lecture/écriture
        Package officePackage = Package.Open(docWord, FileMode.Open, FileAccess.ReadWrite);

        //type de contenu pour la partie principale
        const String officeDocRelType = @"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";

        PackagePart mainPart = null;
        Uri documentUri = null;
        //on récupère la partie contenant les propriétés
        foreach (PackageRelationship relationship in officePackage.GetRelationshipsByType(officeDocRelType))
        {
            documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), relationship.TargetUri);
            mainPart = officePackage.GetPart(documentUri);
            break;
        }

        if (mainPart != null)
        {
            //chargement de la partie dans un XmlDocument
            XmlDocument doc = new XmlDocument();
            doc.Load(mainPart.GetStream());
           
            if (doc.DocumentElement.InnerText.Contains("[RS]"))
            {
                //chaine temporaire où est stockée la nouvelle valeur
                string tmp2 = doc.InnerXml.Replace("[RS]", " Raison Sociale");
                doc.InnerXml = tmp2; // on affecte avec la nouvelle valeur !
            }
            //on sauvegarde
            doc.Save(mainPart.GetStream(FileMode.Open, FileAccess.ReadWrite));
        }
        //fermeture du package
        officePackage.Close();
    }
}

Ce code cherche si la chaien de caractère existe [RS] et si oui la remplace par  Raison Sociale.
Après reste plus qu'à l'adapter aux besoins    !!!
3
cs_olivier941 Messages postés 4 Date d'inscription mardi 3 février 2009 Statut Membre Dernière intervention 5 février 2009
3 févr. 2009 à 22:49
Salut,
juste une remarque :
si ta balise [RS] est mise en forme dans Word (gras, couleur, ...)
ca ne marchera pas .

... et j'ai pas de solution :-(

@+
Olivier
0
cs_olivier941 Messages postés 4 Date d'inscription mardi 3 février 2009 Statut Membre Dernière intervention 5 février 2009
3 févr. 2009 à 23:08
... heu si ca marche

désolé !
0
stefantastiq Messages postés 9 Date d'inscription dimanche 2 avril 2006 Statut Membre Dernière intervention 2 février 2012
4 févr. 2009 à 09:24
Bonjour, alors en fait le post datant un peu j'ai finis par trouver une autre solution beaucoup plus propre en passsant par les objets appelés signets. Si tu as besoin de plus d'explication post ici ou contacte moi.mais  merci quand même !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_olivier941 Messages postés 4 Date d'inscription mardi 3 février 2009 Statut Membre Dernière intervention 5 février 2009
4 févr. 2009 à 09:27
Salut,

oui je suis super interesé
est-ce que t'as un exemple comme le tiens ?

merci à toi
0
stefantastiq Messages postés 9 Date d'inscription dimanche 2 avril 2006 Statut Membre Dernière intervention 2 février 2012
5 févr. 2009 à 11:15
Re, donc j'ai recherché mon vieux projet et je te met quelques brides commentées qui pourrant te servir.
Au préalable, tu dois disposr, d'un fichier word dans lequel tu aura insérer des signets que tu aura nommé comme tu le souhaite.
sinon je reste par la si plus de question.

_Application myWord;              // declaration word
private object myWhat = WdGoToItem.wdGoToBookmark;
private object mySignet;   // variable contenant le signet

#region configuration WORD
myWord = new ApplicationClass();
myWord.DisplayAlerts = WdAlertLevel.wdAlertsNone;
myWord.Visible = false;
#endregion

#region ouverture du Modele word
myDotPath = "c:\\Lettre_fact.dot";  // Renseigne le chemin du fichier word
myWord.Documents.Add(ref myDotPath, ref nullObj, ref nullObj, ref nullObj);   // on met le doc dans notre objet word

#region remplacement numero de facture
mySignet = "NumFacture";      //on affecte notre objet signet avec son nom
myWord.Selection.GoTo(ref myWhat, ref nullObj, ref nullObj, ref mySignet);      //on deplace le curseur jusqu'au signet précédent
myWord.Selection.TypeText("mon texte");      // on ecrit le texte
#endregion

En éspérant avoir pu t'aider
0
cs_olivier941 Messages postés 4 Date d'inscription mardi 3 février 2009 Statut Membre Dernière intervention 5 février 2009
5 févr. 2009 à 11:36
merci

par contre, chaque signet doit avoir un nom unique dans le document word ?

si tu voulais placer a deux endroit la meme valeur tu dois donc utiliser deux signets différents ?
"NumFacture1" et "NumFacture2"

 
0
stefantastiq Messages postés 9 Date d'inscription dimanche 2 avril 2006 Statut Membre Dernière intervention 2 février 2012
5 févr. 2009 à 11:58
oui exact un nom unique pour chaque signet.A moins que comme ça a été mon cas, tu ais à ecrire tes factures à la suite par exmple : "Voici les factures suivantes n° 12541, 145857" la tu peux concaténer tes chaines et mettre la résultant dans ton signet.
0
billalch Messages postés 3 Date d'inscription lundi 26 décembre 2011 Statut Membre Dernière intervention 2 février 2012
2 févr. 2012 à 08:46
bonjour stefantastiq et merci pour votre codes qui ma aider énormement je voudrais just dire que j'ai pas arrivé a faire ecxecuter le deuxieme code de signet priére de m'expliquer un peut car je suis débutant en c# asp merci
0
stefantastiq Messages postés 9 Date d'inscription dimanche 2 avril 2006 Statut Membre Dernière intervention 2 février 2012
2 févr. 2012 à 09:21
Bonjour! Oulala que c'est vieux tout ça ! billalch. Je peux vous apporter une légère aide parce que ça date mais il me faudrait plus de précision sur ce qui vous pose problème exactement, on voit ça en MP?
0
billalch Messages postés 3 Date d'inscription lundi 26 décembre 2011 Statut Membre Dernière intervention 2 février 2012
2 févr. 2012 à 13:35
OK et désolé pour le dérengment just je voudrais le code complet de la partie signet car jai testé l'ancien code et sa marche pas je ne c pas koi faire
0
stefantastiq Messages postés 9 Date d'inscription dimanche 2 avril 2006 Statut Membre Dernière intervention 2 février 2012
2 févr. 2012 à 14:11
Je vous ai envoyé une message privé sur le site et je vais essayer d'ici ce week end de mettre un exemple complet, si je le retrouve je vous tiens au courant.
0
billalch Messages postés 3 Date d'inscription lundi 26 décembre 2011 Statut Membre Dernière intervention 2 février 2012
2 févr. 2012 à 15:49
merci bien mon ami
0
Rejoignez-nous