7
votes

Comment modifiez-vous le contenu d'un contrôle de contenu dans Word 2007 avec OpenXML SDK 2.0?

sur le point de devenir fou avec ce problème. Je suis sûr que c'est si simple, je ne me manque tout simplement pas, mais je ne peux pas faire la vie de moi pour savoir comment modifier le contenu d'un contrôle de contenu dans Word 2007 avec le SDK OpenXML V2.0 en C #.

i ont créé un document Word avec un contrôle de contenu en texte brut. La balise pour ce contrôle est "Prénom". Dans le code, j'aimerais ouvrir le document Word, trouver ce contrôle de contenu et modifier le contenu sans perdre le formatage.

La solution que j'ai enfin obligée de travailler à trouver le contrôle du contenu, insérant un Exécutez après cela, puis retirez le contrôle du contenu comme tel: xxx

Cela modifie le texte, mais je perds toute la mise en forme. Est-ce que quelqu'un sait comment je peux faire cela?


0 commentaires

6 Réponses :


7
votes

J'ai trouvé une meilleure façon de faire ce qui précède à l'aide de http://wiki.threewill.com/display/enterprise/sharePoint+and+open+xml#sharepoindopenxml-utilisateurwordopenxml-utilisationword2007ContentControls comme référence. Vos résultats peuvent varier, mais je pense que cela vous permettra de commencer correctement:

using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(filePath, true)) {
    var sdtRuns = mainDocumentPart.Document.Descendants<SdtRun>()
        .Where(run => run.SdtProperties.GetFirstChild<Tag>().Val.Value == contentControlTagValue);

    foreach (SdtRun sdtRun in sdtRuns) {
        sdtRun.Descendants<Text>().First().Text = replacementText;
    }

    wordprocessingDocument.MainDocumentPart.Document.Save();
}


1 commentaires

On dirait que cette solution ne fonctionnera pas si le contrôle du contenu est le seul élément d'un paragraphe (c'est-à-dire qui n'est pas entouré d'un autre texte). En tant que travail rapide autour, je viens de mettre un espace sur un côté du contrôle du contenu. Je vais poster une meilleure solution quand j'en trouve un.



3
votes

Votre première approche pour supprimer le sdtrun et l'ajout d'un nouveau supprimera évidemment le formatage car vous n'ajoutez qu'une course, mais pas le runstyle. Pour préserver le formatage, vous devez créer des éléments d'exécution comme xxx

votre deuxième approche pour remplacer tous les Les décendants fonctionneront pour le contrôle de contenu texte brut uniquement parce qu'un texte riche Le contrôle du contenu n'a pas d'élément SDTRUN. Le contrôle de contenu de texte riche est SDTBLOCK avec des éléments SDTContent. Un contrôle de contenu texte riche peut avoir plusieurs paragraphes, plusieurs exécutions et plusieurs textes. Donc, votre code, sdtrun.descendants (). Premier (). Texte = remplacementText , sera défectueux pour un contrôle de contenu de texte riche. Il n'y a pas de code de ligne pour remplacer le texte entier d'un contrôle de contenu riche et préserver toute la mise en forme.

Je n'ai pas compris ce que vous entendez par "il ne se débarrasse pas du contrôle du contenu dans le document final "? Je pensais que votre exigence est de modifier le texte (contenu) uniquement en préservant le contrôle du contenu et le formatage.


0 commentaires

1
votes

J'ai aussi dû trouver et remplacer du texte dans les pieds de page. Vous pouvez les trouver à l'aide du code suivant:

using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(file.PhysicalFile.FullName, true)) {
    foreach (FooterPart footerPart in wordprocessingDocument.MainDocumentPart.FooterParts) {
        var footerPartSdtRuns = footerPart.Footer.Descendants<SdtRun>()
            .Where(run => run.SdtProperties.GetFirstChild<Tag>().Val.Value == contentControlTag);

        foreach (SdtRun sdtRun in footerPartSdtRuns) {
           sdtRun.Descendants<Text>().First().Text = replacementTerm;
        }
    }

    wordprocessingDocument.MainDocumentPart.Document.Save();
}


0 commentaires

3
votes

Un excellent moyen de déterminer comment atteindre le résultat souhaité consiste à utiliser l'outil de réflecteur de document fourni avec le XML Open XML SDK 2.0 ....

Par exemple, vous pourriez:

  1. Dans la boîte de dialogue Propriétés pour chacune des commandes de contenu de votre document, cochez la case "Supprimer le contrôle du contenu lorsque le contenu est édité".
  2. Remplissez-les et économisez-le comme neuf doc.
  3. Utilisez le réflecteur pour comparer l'original et la version enregistrée.
  4. Appuyez sur le bouton Montrer / Masquer le code et il vous montrera le code requis pour activer l'original dans la version remplie.

    Ce n'est pas parfait, mais c'est incroyablement utile. Vous pouvez également simplement regarder directement à la balise de l'un ou l'autre document et voir les modifications qui remplissent les commandes causées.

    Il s'agit d'un moyen quelque peu fragile de le faire car le type de traitement ML est peut être compliqué; Il est facile de le gâcher. Pour les commandes de texte simples, je viens d'utiliser cette méthode: xxx

    espère que cela aide d'une manière ou d'une autre. : D


1 commentaires

Vous êtes sorti cela pendant quelques jours, mais je le reviendrai bientôt et je vais regarder dans les suggestions ci-dessus. Merci



1
votes

Une autre solution serait xxx


0 commentaires

1
votes

Types de contrôle de contenu strong>

Selon le point d'insertion dans le document Word, il existe deux types de contrôles de contenu créés: p>

  • niveau supérieur (au même niveau que les paragraphes) p> li>

  • imbriqué (typiquement dans un paragraphe existant) p> li> ul>

    confortablement, dans le XML, les deux types sont étiquetés comme ... sdt> code> mais les classes open-ml sous-jacentes sont différentes. Pour un niveau supérieur, la racine est sdtblock code> et le contenu est sdtcontentblock code>. Pour imbriquée, il est sdtrun code> & sdtcontentrun code>. P>

    Pour obtenir les deux types, c'est-à-dire tous les contrôles de contenu, il est préférable de faire itérer via la base commune classe qui est sdtelement code>, puis vérifiez le type: p> xxx pré>

    pour un modèle de document, tous les contrôles de contenu doivent être traités - il est courant pour plus Puis un contenu de contenu pour avoir le même nom de balise, par exemple le nom du client, tous doivent être remplacés généralement avec le nom du client réel. P>

    Nom de la balise de contrôle de contenu strong> p>

    Le nom de la balise de contrôle du contenu ne sera jamais divisé. p>

    dans le XML, ceci est: p> xxx pré>

    parce que le Le nom du tag n'est jamais divisé, il peut toujours être trouvé avec une correspondance directe: p> xxx pré>

    évidemment, dans le code ci-dessus, il faudrait qu'un mécanisme plus élégant pour récupérer la valeur réelle correspondant à chaque nom de balise différent. P>

    Texte de contrôle du contenu fort> p>

    dans un contrôle de contenu, il est très courant pour le texte rendu à b E Split en plusieurs courses (malgré chaque exécution ayant les mêmes propriétés). P>

    Entre autres choses, cela est causé par l'orthographe / grammaire, et le nombre de tentatives d'édition. La scission de texte est plus courante lorsque les départiments sont utilisés, par exemple [Nom du client], etc. P>

    La raison pour laquelle cela est important est que sans vérifier le XML, il n'est pas possible de garantir que le texte de l'espace réservé n'a pas a été divisé afin qu'il ne puisse pas être trouvé et remplacé. p>

    une approche suggérée forte> p>

    Une approche suggérée consiste à utiliser uniquement des contrôles de contenu en texte brut. niveau et / ou imbriqué, alors: p>

    • Trouver le contenu-contrôle par balise-nom p> li>

    • Insérez un paragraphe formaté ou exécuté après la commande de contenu p> li>

    • Supprimez le contenu-contrôle p>

       List<SdtElement> sdtList = document.Descendants<SdtElement>().ToList();
      
       foreach( SdtElement sdt in sdtList )
       {
          if( sdt is SdtRun )
          {
             String tagName = sdt.SdtProperties.GetFirstChild<Tag>().Val;
      
             String newText = "new text"; // eg GetTextByTag( tagName );
      
             // should use a style or common run props
      
             RunProperties runProps = new RunProperties();
      
             runProps.Color    = new Color   () { Val   = "000000" };
             runProps.FontSize = new FontSize() { Val   = "23" };
             runProps.RunFonts = new RunFonts() { Ascii = "Calibri" };
      
             Run run = new Run();
      
             run.Append( runProps );
             run.Append( new Text( newText ) );
      
             sdt.InsertAfterSelf( run );
      
             sdt.Remove();
          }
      
          if( sdt is SdtBlock )
          {
             ; // add paragraph
          }
       }
      


0 commentaires