IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

C#, SQL et Word


Sujet :

Windows Forms

  1. #1
    Membre à l'essai
    Femme Profil pro
    Vice-présente, centre sportif
    Inscrit en
    Juillet 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations professionnelles :
    Activité : Vice-présente, centre sportif
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juillet 2013
    Messages : 8
    Points : 10
    Points
    10
    Par défaut C#, SQL et Word
    Bonjour à tous,

    tout d'abord, ENFIN UN forum en français !
    Merci d'exister.
    J'ai trouvé une foule d'informations sur ce forums et je remercie tout le monde de votre aide, volontaire ou non !

    Mise en situation :

    J'ai entre les mains, un petit logiciel de gestion de la clientèle et de service de vente. C'est fait maison, par moi et j'y ai travaillé de nombreuses heures. En gros, il prend les infos des clients, leurs achats, leur présences (oui oui, on a une école de karaté) et le logiciel transfère les infos à mon logiciel comptable pour les fins d'années fiscales.

    Mon problème:

    J'ai déjà un fichier .docx qui contient des zones de texte à remplir et je cherche une solution afin de pouvoir remplir ces champs avec les données de ma BD, mais à partir de mon code C#.

    En fait, en inscrivant un nouveau client, je voudrais appuyer sur un bouton pour confirmer son inscription, imprimer son contrat et sa facture en même temps. Sans avoir à ouvrir une instance visible de Word.

    J'espère que j'ai bien pu expliquer ma situation. Je suis ouverte aux suggestions et suis prête à faire pas mal de lecture ou à apprendre quelque chose de nouveau pour y arriver.

    **P.S. en cherchant sur des forums, j'ai vu un peu de XLM ou de OPEN XML mais je suis très confuse. Est-ce que ça pourrait donner le résultat que je recherche?

  2. #2
    Membre éclairé Avatar de chamamo
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    588
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 588
    Points : 735
    Points
    735
    Par défaut
    Il y a l'Open Xml SDK que tu peux utiliser pour ton besoin.

    Les docx sont un ensemble de fichier xml (tu peux faire le test en changement l'extension docx en zip), donc tu vas pouvoir utiliser Linq To Xml pour lire et modifier tes fichiers docx.

    Tu n'es pas obligé d'utiliser Word, libre office permet aussi de les lire et de les modifier.

    Voici un article du site pour commencer.

    Bon dév.

  3. #3
    Membre régulier
    Inscrit en
    Avril 2010
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 200
    Points : 111
    Points
    111
    Par défaut
    Tes champs à remplir dans ton word, ce sont quoi exactement ?
    J'ai déjà du travailler avec des documents docx par le passé en faisant un remplacement de texte comme toi.

    Tu as raison chamamo, sur le fait que les documents sont un ensemble de fichiers xml, seulement les balises xml changent en fonction des modifications du document, si je ne m'abuse. Donc retrouver en utilisant LINQ, je ne suis pas sûr que ce soit adapté dans ce cas-là, j'avais réellement eu des problèmes à l'époque.

    Dans un premier temps je pensais pouvoir utiliser ce qu'on appelle des quickparts mais au final je n'avais jamais réussi à récupérer ceux-ci en c# me semble-t-il, j'avais du utiliser à la place des "champs fusion" si mes souvenirs sont bon.
    Google t'indiquera comment créer ces champs dans word, et comment les remplacer en c#.

    Si j'ai un bout de code quelque part, je te le posterai si tu le souhaites (et si je retrouve...)

  4. #4
    Membre éclairé Avatar de chamamo
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    588
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 588
    Points : 735
    Points
    735
    Par défaut
    Ce que j'avais utilisé c'était du text tout simplement, quelques chose comme:
    Bonjour Monsieur <Utilisateur.Nom>.... (ou utilisateur représente l'entité et Nom la propriété que l'on veut insérer.)

    C'est une syntaxe à moi qui me permet d'avoir mes propres champs de fusion, d'où l'utilisation de LINQ pour faire des recherches dans le document.

  5. #5
    Membre régulier
    Inscrit en
    Avril 2010
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 200
    Points : 111
    Points
    111
    Par défaut
    @chamamo ok, j'avais pas vu ça comme ça c'est une possibilité, effectivement

    En ce qui concerne le code que j'avais promis de chercher, le voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    /// <summary>
            /// Remplace le contenu texte de tous les champs fusion d'un document Word
            /// </summary>
            /// <param name="document">Object 'WordprocessingDocument' représentant le document</param>
            /// <param name="replaceOperations">Un dictionnaire clés/valeurs (clés : nom du champ fusion à remplacer, valeur : valeur par laquelle remplacer)</param>
            public static void ReplaceAllQuickPartText(WordprocessingDocument document,
                                                       Dictionary<string, string> replaceOperations)
            {
                Document currentDocument = document.MainDocumentPart.Document;
                Body currentBody = currentDocument.Body;
     
                IEnumerable<SimpleField> simpleFields = currentBody.Descendants<SimpleField>();
                if (simpleFields.Count() > 0)
                {
                    // w:fldSimple (MergeField par défaut, au premier enregistrement du template)
                    foreach (SimpleField field in simpleFields)
                    {
                        string[] instruction = GetCurrentInstruction(field);
                        ReplaceMergeField(instruction, field.Descendants<Text>(), replaceOperations);
                    }
                }
                else
                {
                    IEnumerable<FieldCode> fieldCodes = currentBody.Descendants<FieldCode>();
                    // w:instrText (MergeField après une modification du template)
                    foreach (FieldCode field in fieldCodes)
                    {
                        string[] instruction = GetCurrentInstruction(field);
                        ReplaceMergeField(instruction, field.Parent.Parent.Descendants<Text>(), replaceOperations);
                    }
                }
     
                currentDocument.Save();
            }
     
    /// <summary>
            /// Remplace le texte des champs fusion d'un document
            /// </summary>
            /// <param name="instruction">tableau contenant les instructions du champ MergeField</param>
            /// <param name="descendants">Les éléments OpenXml enfants suivant si le remplacement est fait dans un champ w:fldSimple ou w:instrText</param>
            /// <param name="replaceOperations">Un dictionnaire clés/valeurs (clés : nom du champ fusion à remplacer, valeur : valeur par laquelle remplacer)</param>
            private static void ReplaceMergeField(string[] instruction,
                                                  IEnumerable<Text> descendants,
                                                  Dictionary<string, string> replaceOperations)
            {
                // Vérifie si c'est un champ de type de MergeField (champ fusion).
                if (instruction[0].ToLower().Equals("mergefield"))
                {
                    string fieldname = instruction[1];
     
                    // Récupère le texte à l'intérieur du champ fusion
                    foreach (Text fieldText in descendants)
                    {
                        string value = replaceOperations.ContainsKey(fieldname) ? replaceOperations[fieldname] : null;
     
                        // Est-ce un champ à remplacer ?
                        if (value != null)
                        {
                            fieldText.Text = value;
                        }
     
                        // Il ne devrait y avoir qu'un seul champ texte...
                        break;
                    }
                }
            }
    C'est du vieux code ! Ca fait bizarre de retomber dessus mais ça fonctionnait dans mes souvenirs ! XD Si ça peut aider.

    Ca parraît compliqer la vie par rapport à ce que tu proposes Chamamo, mais ça aidera bien quelqu'un un jour, peut-être... Sait-on jamais !

    EDIT : Il y a très probablement des améliorations à apporter. De plus l'époque où je mettais encore la xml-doc en français... Que de souvenirs de jeunesses !

  6. #6
    Membre éclairé Avatar de chamamo
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    588
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 588
    Points : 735
    Points
    735
    Par défaut
    Ça semble pas mal, moi je ne voulais pas passer par ces champs, je voulais donner la possibilité à l'utilisateur de créer ses propre champs, il va ouvrir word depuis l'application, commencer à rédiger son document et s'il a besoin d'insérer un champs, un formulaire est affiché à droite qui contient la structure des données (exemple: table: Personne, champs (Nom, Prénom, tél...), l'utilisateur avec un glisser déposer glisse son champs désiré à l'emplacement voulu, et à la fin ça crée un modèle du genre: Bonjour Monsieur <Personne.Nom>...

    Une fois le modèle créé, il peut générer ses document depuis ce modèle, en lui passant le jeux de données correspondant, j'ai fait aussi des relations parent-> enfant, pour générer un tableau par exemple il suffit dans le modèle de créer une seule ligne (d'un tableau avec les champs de fusion) et je génère autant de ligne que de données que je passe.

    Cette solution permet à l'utilisateur de créer ses propres modèle et sans faire appel aux champs de fusion de word qui nécessite une certaine maîtrise.

  7. #7
    Membre régulier
    Inscrit en
    Avril 2010
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 200
    Points : 111
    Points
    111
    Par défaut
    pour générer un tableau par exemple il suffit dans le modèle de créer une seule ligne (d'un tableau avec les champs de fusion) et je génère autant de ligne que de données que je passe.
    Je m'étais créé des méthodes permettant de remplacer un champ fusion par une image, un tableau, du texte, je ne sais quoi d'autres encore. Oui tout est possible

    sans faire appel aux champs de fusion de word qui nécessite une certaine maîtrise.
    Dans mes souvenirs ce n'est pas si compliqué que ça, une petite recherche sur google, on trouve en 5 min comment faire, ensuite c'est un jeu d'enfant, je crois même qu'on pouvait faire des copier/coller des champs, mais je me souviens plus vraiment je m'avance peut-être.

    En tout cas ta solution est bonne aussi, je n'ai rien contre au contraire.
    Deux solutions sont proposées, maintenant c'est à Luthecia de choisir

  8. #8
    Membre à l'essai
    Femme Profil pro
    Vice-présente, centre sportif
    Inscrit en
    Juillet 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations professionnelles :
    Activité : Vice-présente, centre sportif
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juillet 2013
    Messages : 8
    Points : 10
    Points
    10
    Par défaut
    Vaut mieux tard que jamais. Désolée pour le délai de réponse.

    Je continue de plancher là-dessus. Jusqu'à maintenant, j'ai encore un peu de difficulté à implémenter tout ça.

    En fait, c'est au niveau de la création du "template" que j'ai de la difficulté. Je ne sais pas quel type de champs utiliser pour l'instertion des données.

    Les zones de textes ne peuvent pas être indentifiées par un nom unique (enfin je pense).
    J'avais pensé utiliser un signet pour les trouver dans le xml, mais je n'y arrive pas.

    Le lien donné plus haut est fantastique pour comprendre le côté C#, mais pour le côté Word, c'est difficile pour moi encore.

    Merci de votre aide

  9. #9
    Candidat au Club
    Femme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 59
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mai 2014
    Messages : 2
    Points : 3
    Points
    3
    Par défaut Help !!!
    Citation Envoyé par chamamo Voir le message
    Il y a l'Open Xml SDK que tu peux utiliser pour ton besoin.

    Les docx sont un ensemble de fichier xml (tu peux faire le test en changement l'extension docx en zip), donc tu vas pouvoir utiliser Linq To Xml pour lire et modifier tes fichiers docx.

    Tu n'es pas obligé d'utiliser Word, libre office permet aussi de les lire et de les modifier.

    Voici un article du site pour commencer.

    Bon dév.
    Bonjour Mourad

    Je dois développer une appli de "mailing"....Les "supers" utilisateurs pourraient écrire les courriers qui seraient ensuite utilisés via des pages asp
    J'ai essayé de voir Open XML avec libre office mais j'ai un peu de mal...qt à ta solution de déconnecter complément le docx des champs de fusion me plait beaucoup

    Aurait il une possibilité pour avoir des bout de codes et des fichiers docx en exemple, contre une caisse de champagne ?!!!!!

    Merci d'avance

    Anne

  10. #10
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Points : 2 201
    Points
    2 201
    Par défaut
    Les documents word (.docx), qui sont en réalité des fichiers zip avec des dossier et des fichiers XML, peuvent aussi contenir un fichier XML de "donnée" libre additionnel. Il est ensuite possible de lier des attributs de ce fichier XML a des contrôles graphique dans le document word.

    Comme le fichier XML de données est (normalement) beaucoup moins complexe que le bordel définissant le document il est plus facile de travailler sur ce dernier pour charger des données ou récupérer une saisie / modification effectué à l'aide de Word sur les champs.

    Sauf erreur ce lien présente une solution. Bien que cette dernière utilise un fichier XML externe pour stocker les données, il y a un survol rapide concernant l'intégration de ce fichier directement dans le docx.

    http://msdn.microsoft.com/en-us/libr...ffice.12).aspx

    Par contre la mise en œuvre de ce genre de solution est quand même assez "lourde/complexe" donc c'est à réserver à des cas d'utilisation spécifique où l'on désire utiliser Word pour effectuer de la saisie ou faire des traitements manuel post-processing. Si il s'agit simplement de cracher des données sur une imprimante, l'utilisation de rapport (fichier .rdlc et l'objet reportviewer par exemple) est à mon avis plus appropriée. A la limite du publipostage word avec un fichier d'export pour faire l'interface avec ton application.

  11. #11
    Candidat au Club
    Femme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 59
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mai 2014
    Messages : 2
    Points : 3
    Points
    3
    Par défaut Merci, mais
    Bonjour,

    J'ai déjà développé une appli "mailing" en v6 et tx control.
    Je connais aussi la difficulté à développer ce genre d'appli sur un intranet.
    Mais je n'ai pas le choix, 1 super utilisateur doit pouvoir créer les fichiers modèle et les utilisateurs doivent pouvoir s'en servir.
    Il est impératif que cela fonctionne avec n'importe quel logiciel (MS word, OO, LO), du coup je fais mes tests en LO car je pourrais éventuellement l'imposer (normalement, nous n'achetons plus de licence MS WOrd sauf cas particuliers)...
    La solution de Mourad me paraissait intéressante....
    Pour le moment, je décortique les fichiers LO avec open xml...pour trouver les chamlps et les remplacer, mais sans résultat....

    Bonne journée

    Anne

  12. #12
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    La solution qui me semble de loin la plus facile à implémenter consiste à créer un (ou plusieurs) doc Word de publipostage lié(s) statiquement à un fichier de données de type .csv qui ne contiendra qu'un seul enregistrement avec les données du client.

    Le doc Word est fixe.
    Le fichier de données (.csv) est recréé chaque fois qu'on veut faire une(des) impressions pour un client.

    Pour lancer l'impression du fichier Word lié au fichier de données, voici un petit bout code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
        internal static bool PrintDocument(string FileName,string PrinterName)
        { // PrinterName = ""(Default) / "?" (select printer dialog) / xxxx
          // Get PrinterName
          bool Result=false ;
          if (PrinterName!="") PrinterName=SelectPrinterDialog(PrinterName) ;
          if (PrinterName!=null)
          {
            if (!System.IO.File.Exists(FileName)) MessageBox.Show("File to be printed was not found : "+FileName) ;
            else 
            {
              System.Diagnostics.Process TheProcess = new System.Diagnostics.Process() ;
              try
                { 
                TheProcess.StartInfo.FileName = FileName ;
                TheProcess.StartInfo.Verb     = PrinterName==""?"Print":"Printto" ;
                TheProcess.StartInfo.Arguments= '"'+PrinterName+'"' ;
                TheProcess.StartInfo.CreateNoWindow = true ;
                TheProcess.Start() ;
                Result=true ;
                }
              catch (Exception Ex) { MessageBox.Show("File print error on "+FileName+Environment.NewLine+Ex.Message.ToString()) ; }
            }
          }
          return Result ;
        }
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  13. #13
    Membre éclairé Avatar de chamamo
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    588
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 588
    Points : 735
    Points
    735
    Par défaut
    Bon, vous m'avez convaincu de retrouver mon code et de le poster
    Je ferais ça dès que j'ai le temps, c'est à dire ce weekend

  14. #14
    Membre éclairé Avatar de chamamo
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    588
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 588
    Points : 735
    Points
    735
    Par défaut
    Voici le code source du projet https://github.com/chamamo/Cham.DocxReport
    Pour l'instant il n'y a pas de documentation.

    J'attends vos retours

    Mourad

Discussions similaires

  1. fusion sql server word
    Par debutantasp dans le forum ASP
    Réponses: 4
    Dernier message: 07/02/2008, 20h47
  2. importer des données d'une base SQL vers word?
    Par Jayceblaster dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 26/10/2007, 09h43
  3. SQL sous Word 2003
    Par Stef.web dans le forum Langage SQL
    Réponses: 3
    Dernier message: 01/12/2005, 13h54
  4. Afficher sous Word des données SQL qui contient des retours
    Par samoht dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 30/09/2005, 16h12
  5. Fusions word d'Access à SQL Server
    Par Robert999 dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 12/08/2004, 13h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo