Wordテンプレートからdocxファイルを作成しましたが、コピーしたdocxファイルにアクセスしていて、特定のテキストを他のデータに置き換えたいと考えています。
文書のメイン部分からテキストにアクセスする方法についてのヒントを得ることができませんか?
どんな助けでもありがたいです。
以下は今までの私のコードです。
private void CreateSampleWordDocument()
{
//string sourceFile = Path.Combine("D:\\GeneralLetter.dot");
//string destinationFile = Path.Combine("D:\\New.doc");
string sourceFile = Path.Combine("D:\\GeneralWelcomeLetter.docx");
string destinationFile = Path.Combine("D:\\New.docx");
try
{
// Create a copy of the template file and open the copy
File.Copy(sourceFile, destinationFile, true);
using (WordprocessingDocument document = WordprocessingDocument.Open(destinationFile, true))
{
// Change the document type to Document
document.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
//Get the Main Part of the document
MainDocumentPart mainPart = document.MainDocumentPart;
mainPart.Document.Save();
}
}
catch
{
}
}
次に、特定のテキストを見つけてそれを置き換える方法は?リンクを経由して取得することができないので、いくつかのコードヒントがかなりあります。
それを行う方法のアイデアをあなたに与えるために、試してみてください:
using ( WordprocessingDocument doc =
WordprocessingDocument.Open(@"yourpath\testdocument.docx", true))
{
var body = doc.MainDocumentPart.Document.Body;
var paras = body.Elements<Paragraph>();
foreach (var para in paras)
{
foreach (var run in para.Elements<Run>())
{
foreach (var text in run.Elements<Text>())
{
if (text.Text.Contains("text-to-replace"))
{
text.Text = text.Text.Replace("text-to-replace", "replaced-text");
}
}
}
}
}
}
テキストは大文字と小文字が区別されることに注意してください。置換後、テキストの書式は変更されません。これがお役に立てば幸いです。
Flowerking
の答えに加えて:
Wordファイルにテキストボックスが含まれている場合、彼のソリューションは機能しません。テキストボックスにはTextBoxContent要素があるため、Run
sのforeachループには表示されません。
しかし、書くとき
using ( WordprocessingDocument doc =
WordprocessingDocument.Open(@"yourpath\testdocument.docx", true))
{
var document = doc.MainDocumentPart.Document
foreach (var text in document.Descendants<Text>()) // <<< Here
{
if (text.Text.Contains("text-to-replace"))
{
text.Text = text.Text.Replace("text-to-replace", "replaced-text");
}
}
}
(テキストボックスにあるかどうかにかかわらず)ドキュメント内のすべてのテキストをループするので、テキストを置き換えます。
テキストがランまたはテキストボックスに分割されている場合、これも機能しないことに注意してください。これらのケースには、より良いソリューションが必要です。
多分この解決策はより簡単です:
1。 a StreamReader
はすべてのテキストを読み取り、
2。 Regex
を使用すると、古いtexの代わりに大文字と小文字を区別せずに新しいテキストを置き換えます
3。 StreamWriter
は、変更されたテキストをドキュメントに再度書き込みます。
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
docText = sr.ReadToEnd();
foreach (var t in findesReplaces)
docText = new Regex(findText, RegexOptions.IgnoreCase).Replace(docText, replaceText);
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
sw.Write(docText);
}
テキストラン(テキストボックスを含む)全体で開いているxml(Word)ドキュメント内のタグを検索および置換できるソリューションは次のとおりです
namespace Demo
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
public class WordDocumentHelper
{
class DocumentTag
{
public DocumentTag()
{
ReplacementText = "";
}
public string Tag { get; set; }
public string Table { get; set; }
public string Column { get; set; }
public string ReplacementText { get; set; }
public override string ToString()
{
return ReplacementText ?? (Tag ?? "");
}
}
private const string TAG_PATTERN = @"\[(.*?)[\.|\:](.*?)\]";
private const string TAG_START = @"[";
private const string TAG_END = @"]";
/// <summary>
/// Clones a document template into the temp folder and returns the newly created clone temp filename and path.
/// </summary>
/// <param name="templatePath"></param>
/// <returns></returns>
public string CloneTemplateForEditing(string templatePath)
{
var tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()) + Path.GetExtension(templatePath);
File.Copy(templatePath, tempFile);
return tempFile;
}
/// <summary>
/// Opens a given filename, replaces tags, and saves.
/// </summary>
/// <param name="filename"></param>
/// <returns>Number of tags found</returns>
public int FindAndReplaceTags(string filename)
{
var allTags = new List<DocumentTag>();
using (WordprocessingDocument doc = WordprocessingDocument.Open(path: filename, isEditable: true))
{
var document = doc.MainDocumentPart.Document;
// text may be split across multiple text runs so keep a collection of text objects
List<Text> tagParts = new List<Text>();
foreach (var text in document.Descendants<Text>())
{
// search for any fully formed tags in this text run
var fullTags = GetTags(text.Text);
// replace values for fully formed tags
fullTags.ForEach(t => {
t = GetTagReplacementValue(t);
text.Text = text.Text.Replace(t.Tag, t.ReplacementText);
allTags.Add(t);
});
// continue working on current partial tag
if (tagParts.Count > 0)
{
// working on a tag
var joinText = string.Join("", tagParts.Select(x => x.Text)) + text.Text;
// see if tag ends with this block
if (joinText.Contains(TAG_END))
{
var joinTag = GetTags(joinText).FirstOrDefault(); // should be just one tag (or none)
if (joinTag == null)
{
throw new Exception($"Misformed document tag in block '{string.Join("", tagParts.Select(x => x.Text)) + text.Text}' ");
}
joinTag = GetTagReplacementValue(joinTag);
allTags.Add(joinTag);
// replace first text run in the tagParts set with the replacement value.
// (This means the formatting used on the first character of the tag will be used)
var firstRun = tagParts.First();
firstRun.Text = firstRun.Text.Substring(0, firstRun.Text.LastIndexOf(TAG_START));
firstRun.Text += joinTag.ReplacementText;
// replace trailing text runs with empty strings
tagParts.Skip(1).ToList().ForEach(x => x.Text = "");
// replace all text up to and including the first index of TAG_END
text.Text = text.Text.Substring(text.Text.IndexOf(TAG_END) + 1);
// empty the tagParts list so we can start on a new tag
tagParts.Clear();
}
else
{
// no tag end so keep getting text runs
tagParts.Add(text);
}
}
// search for new partial tags
if (text.Text.Contains("["))
{
if (tagParts.Any())
{
throw new Exception($"Misformed document tag in block '{string.Join("", tagParts.Select(x => x.Text)) + text.Text}' ");
}
tagParts.Add(text);
continue;
}
}
// save the temp doc before closing
doc.Save();
}
return allTags.Count;
}
/// <summary>
/// Gets a unique set of document tags found in the passed fileText using Regex
/// </summary>
/// <param name="fileText"></param>
/// <returns></returns>
private List<DocumentTag> GetTags(string fileText)
{
List<DocumentTag> tags = new List<DocumentTag>();
if (string.IsNullOrWhiteSpace(fileText))
{
return tags;
}
// TODO: custom regex for tag matching
// this example looks for tags in the formation "[table.column]" or "[table:column]" and captures the full tag, "table", and "column" into match Groups
MatchCollection matches = Regex.Matches(fileText, TAG_PATTERN);
foreach (Match match in matches)
{
try
{
if (match.Groups.Count < 3
|| string.IsNullOrWhiteSpace(match.Groups[0].Value)
|| string.IsNullOrWhiteSpace(match.Groups[1].Value)
|| string.IsNullOrWhiteSpace(match.Groups[2].Value))
{
continue;
}
tags.Add(new DocumentTag
{
Tag = match.Groups[0].Value,
Table = match.Groups[1].Value,
Column = match.Groups[2].Value
});
}
catch
{
}
}
return tags;
}
/// <summary>
/// Set the Tag replacement value of the pasted tag
/// </summary>
/// <returns></returns>
private DocumentTag GetTagReplacementValue(DocumentTag tag)
{
// TODO: custom routine to update tag Replacement Value
tag.ReplacementText = "foobar";
return tag;
}
}
}
Dim doc As WordprocessingDocument = WordprocessingDocument.Open("Chemin", True, New OpenSettings With {.AutoSave = True})
Dim d As Document = doc.MainDocumentPart.Document
Dim txt As Text = d.Descendants(Of Text).Where(Function(t) t.Text = "txtNom").FirstOrDefault
If txt IsNot Nothing Then
txt.Text = txt.Text.Replace("txtNom", "YASSINE OULARBI")
End If
doc.Close()
探しているテキストが角かっこで囲まれていて、Wordがテキストを複数回に分割する場合...;
テキストを検索(ienumerable(of text))
for (int i = 0; i <= SearchIn.Count - 1; i++) {
if (!(i + 2 > SearchIn.Count - 1)) {
Text TXT = SearchIn(i);
Text TXT1 = SearchIn(i + 1);
Text TXT2 = SearchIn(i + 2);
if (Strings.Trim(TXT.Text) == "[" & Strings.Trim(TXT2.Text) == "]") {
TXT1.Text = TXT.Text + TXT1.Text + TXT2.Text;
TXT.Text = "";
TXT2.Text = "";
}
}
}