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. P>
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: p> Cela modifie le texte, mais je perds toute la mise en forme. Est-ce que quelqu'un sait comment je peux faire cela? P> p>
6 Réponses :
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(); }
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.
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 votre deuxième approche pour remplacer tous les 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. P> P> Les décendants
sdtrun.descendants
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(); }
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: P>
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. P>
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: p> espère que cela aide d'une manière ou d'une autre. : D p> p>
Vous êtes sorti cela pendant quelques jours, mais je le reviendrai bientôt et je vais regarder dans les suggestions ci-dessus. Merci
Une autre solution serait
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 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 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> parce que le Le nom du tag n'est jamais divisé, il peut toujours être trouvé avec une correspondance directe: p> é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>
sdtblock code> et le contenu est
sdtcontentblock code>. Pour imbriquée, il est
sdtrun code> &
sdtcontentrun code>. P>
sdtelement code>, puis vérifiez le type: 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
}
}