web-dev-qa-db-fra.com

Générer un document Word (docx) en utilisant les données d'un fichier XML / Convertir XML en un document Word basé sur un modèle

J'ai un fichier XML avec les données dont j'ai besoin pour être rempli sur un document Word.

J'ai besoin de trouver un moyen, de définir un modèle qui peut être utilisé comme ligne de base pour remplir des données à partir d'un fichier XML et créer un document de sortie.

Je pense qu'il y a deux façons de procéder.

  1. Créez un fichier XSLT qui sera le "modèle" et utilisez-le pour générer des documents Word en l'utilisant conjointement avec le fichier XML.
  2. Utilisez les contrôles de contenu dans Word pour créer un modèle de document et en quelque sorte mapper vers un fichier XML.

Je ne connais simplement pas les détails de la mise en œuvre dans les deux cas. Ou je ne sais pas s'il existe un autre moyen plus simple d'accomplir cette tâche.

Quelqu'un pourrait-il montrer un exemple de la façon dont cela peut être mis en œuvre. Un simple exemple suffirait.

Je préfère C # pour tout codage. J'utilise Word 2016 mais je veux qu'il soit compatible de Word 2007 à Word 2016 et tout le reste si possible car les utilisateurs utiliseront ces versions. Je vous remercie!

7
slayernoah

A compris comment utiliser les contrôles de contenu pour générer des documents et comment remplir les données d'un XML dans les contrôles de contenu. Je l'ai divisé en 2 parties:

  • Partie 1: Créez votre modèle de document pour la génération de documents
  • Partie 2: Utilisez du code en C # pour générer des documents basés sur un modèle

Partie 1: Créez votre modèle de document pour la génération de documents

  1. Créez un exemple XML basé sur lequel vous pouvez créer le modèle Word pour la génération de documents. Commencez de préférence avec une version moins compliquée pour vous y familiariser.

J'ai utilisé le XML suivant pour les tests. Pour les tests, je n'ai pas répété de sections, d'images, etc.

<?xml version="1.0" encoding="utf-8"?>
<mydata xmlns="http://CustomDemoXML.htm">
    <field1>This is the value in field1 from the XML file</field1>
    <field2>This is the value in field2 from the XML file</field2>
    <field3>This is the value in field3 from the XML file</field3>
</mydata>

Note 1 : Il ne s'agit que d'un exemple de XML pour créer votre Modèle Word. Les fichiers XML contenant des données réelles dans ce même format peuvent être appliqués ultérieurement lors de la génération de documents Word à partir du modèle.

Remarque 2 : l'attribut xmlns peut contenir littéralement tout ce que vous voulez et il ne doit pas nécessairement s'agir d'une URL commençant par http.

Enregistrez votre exemple de fichier XML à n'importe quel emplacement afin de pouvoir l'importer dans le modèle que vous êtes sur le point de créer.

  1. Assurez-vous que l'onglet Developer est activé sur votre copie de Word [File -> Options -> Customize Ribbon -> Sous Customize the Ribbon, assurez-vous que Developer est sélectionné -> OK]. Détails: Comment: afficher l'onglet Développeur sur le ruban

  2. Créez un nouveau document Word (ou utilisez un document Word existant) qui sera votre modèle pour la génération de documents.

  3. Dans l'onglet Developer, cliquez sur XML Mapping Pane. Cela ouvrira le XML Mapping Pane sur le côté droit du document.

  4. Dans le volet de mappage XML, sélectionnez le Custom XML Part menu déroulant -> Sélectionnez (Add new part).

  5. Sélectionnez le fichier XML que vous avez enregistré à l'étape 1 -> Open.

  6. Dans le volet de mappage XML, sélectionnez le Custom XML Part liste déroulante -> Sélectionnez l'élément avec le texte qui se trouvait sur l'attribut xmlns du fichier XML personnalisé. Si vous utilisez l'exemple de fichier ci-dessus, ce serait http://CustomDemoXML.htm.

  7. Ajoutez un texte statique à un document Word et ajoutez un Plain Text Content Control à côté (sous l'onglet Developer -> Controls. Répétez l'opération pour tous les champs que vous devez ajouter.

Pour l'exemple XML ci-dessus, j'avais le document Word suivant:

sample Word document template

  1. Cliquez sur le premier Plain Text Content Control -> Dans le volet de mappage XML, cliquez avec le bouton droit sur le champ que vous souhaitez mapper à ce contrôle de contenu -> Cliquez sur Map to Selected Content Control. Répétez l'opération pour tous les champs que vous souhaitez mapper.

Remarque: Alternativement, au lieu d'ajouter le Plain Text Content Control éléments de l'onglet développeur à l'étape 8, vous pouvez cliquer avec le bouton droit sur le champ que vous souhaitez mapper dans le volet de mappage XML -> Cliquez sur Insert Content Control -> Cliquez sur Plain Text.

De même, vous pouvez également ajouter d'autres types de contrôles tels que des cases à cocher, des sélecteurs de date et même des sections extensibles (il prend également en charge les sections extensibles imbriquées! - depuis Word 2013) et mapper les données XML à celles qui utilisent uniquement la fonctionnalité Word native et sans aucun tiers. outils!

  1. Enregistrez votre modèle de document.

Partie 2: Utilisez du code en C # pour générer des documents basés sur un modèle

Celui-ci utilise les recommandations de Microsoft OpenXML SDK pour générer des documents à l'aide d'un fichier XML contenant des données réelles.

  1. Créez votre fichier XML/ouvrez un fichier XML existant avec lequel générer un document à partir du modèle créé ci-dessus. Il doit être au même format que l'exemple de fichier XML utilisé pour créer le modèle.

  2. Utilisez le SDK OpenXML pour supprimer tous les éléments CustomXMLPart du document. Cela suppose qu'aucune autre partie XML personnalisée n'est utilisée dans le document, ce qui est le cas dans cet exemple. Pour les scénarios complexes, vous pouvez supprimer des parties XML spécifiques si nécessaire.

  3. Utilisez le SDK OpenXML pour ajouter un nouveau CustomXMLPart basé sur le fichier XML à l'étape 1 ci-dessus.

Voici l'exemple de code que je dois "rafraîchir"/"recharger" les exemples de données dans le modèle avec des données d'un fichier XML contenant des données réelles (en supposant que le fichier XML utilisé pour générer le document est déjà créé et enregistré):

using System.IO;
using DocumentFormat.OpenXml.Packaging;

namespace SampleNamespace
{
    public static class SampleClass
    {
        public static void GenerateDocument()
        {
            string rootPath = @"C:\Temp";
            string xmlDataFile = rootPath + @"\MyNewData.xml";
            string templateDocument = rootPath + @"\MyTemplate.docx";
            string outputDocument = rootPath + @"\MyGeneratedDocument.docx";

            using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(templateDocument, true))
            {
                //get the main part of the document which contains CustomXMLParts
                MainDocumentPart mainPart = wordDoc.MainDocumentPart;

                //delete all CustomXMLParts in the document. If needed only specific CustomXMLParts can be deleted using the CustomXmlParts IEnumerable
                mainPart.DeleteParts<CustomXmlPart>(mainPart.CustomXmlParts);

                //add new CustomXMLPart with data from new XML file
                CustomXmlPart myXmlPart = mainPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
                using (FileStream stream = new FileStream(xmlDataFile, FileMode.Open))
                {
                    myXmlPart.FeedData(stream);
                }
            }

        }
    }
}

C'est tout!

15
slayernoah

Ok, j'ai trouvé un guide détaillé sur l'utilisation de XSLT comme modèle pour générer le document Word ici: tilisation de XSLT et Open XML pour créer un document Word 2007 .

Il semble que même si cet article concerne Word 2007, il fonctionne parfaitement dans Word 2016.

Le seul problème avec cette méthode est que si des modifications sont nécessaires dans le modèle plus tard, il faut beaucoup d'efforts pour mettre à jour le fichier xslt et ce n'est pas convivial car il ne peut pas être mis à jour dans Word lui-même et le XML réel du document doit être manipulé.

Sur le plan positif, la génération de documents est TRÈS flexible avec toute la puissance disponible via XSL (foreach, variables, si conditions, etc.)

4
slayernoah