【发布时间】:2013-09-13 09:07:13
【问题描述】:
我找不到任何用于替换书签内容的有效代码示例。代码应该能够处理替换空书签和用预先存在的内容替换书签的情况。
例如:如果我在 Word 文档中有此文本:
“在下一个周期之间是 Bookmark1.. 在下一个周期之间是 Bookmark2..”
我想在第一个句点之间插入文本“BM1”,在下一个句点之间插入“BM2”。
第一次替换运行后,替换已正确插入。
但在下一次替换运行后,Bookmark1 之后的行上的所有文本都被删除,然后插入 Bookmark2 的替换。
这是我的 C# 代码:
var doc = WordprocessingDocument.Open(@"file.docx", true);
public static Dictionary<string, wd.BookmarkStart> FindAllBookmarksInWordFile(WordprocessingDocument file)
{
var bookmarkMap = new Dictionary<String, wd.BookmarkStart>();
foreach (var headerPart in file.MainDocumentPart.HeaderParts)
{
foreach (var bookmarkStart in headerPart.RootElement.Descendants<wd.BookmarkStart>())
{
if (!bookmarkStart.Name.ToString().StartsWith("_"))
bookmarkMap[bookmarkStart.Name] = bookmarkStart;
}
}
foreach (var bookmarkStart in file.MainDocumentPart.RootElement.Descendants<wd.BookmarkStart>())
{
if (!bookmarkStart.Name.ToString().StartsWith("_"))
bookmarkMap[bookmarkStart.Name] = bookmarkStart;
}
return bookmarkMap;
}
/*extension methods*/
public static bool IsEndBookmark(this OpenXmlElement element, BookmarkStart startBookmark)
{
return IsEndBookmark(element as BookmarkEnd, startBookmark);
}
public static bool IsEndBookmark(this BookmarkEnd endBookmark, BookmarkStart startBookmark)
{
if (endBookmark == null)
return false;
return endBookmark.Id.Value == startBookmark.Id.Value;
}
/* end of extension methods */
public static void SetText(BookmarkStart bookmark, string value)
{
RemoveAllTexts(bookmark);
bookmark.Parent.InsertAfter(new Run(new Text(value)), bookmark);
}
private static void RemoveAllTexts(BookmarkStart bookmark)
{
if (bookmark.ColumnFirst != null) return;
var nextSibling = bookmark.NextSibling();
while (nextSibling != null)
{
if (nextSibling.IsEndBookmark(bookmark) || nextSibling.GetType() == typeof(BookmarkStart))
break;
foreach (var item in nextSibling.Descendants<Text>())
{
item.Remove();
}
nextSibling = nextSibling.NextSibling();
}
}
我已经寻找了很长时间的通用解决方案。 任何帮助表示赞赏! -维克多
【问题讨论】: