按字母顺序对 Table 目录进行排序

Sort Table of Contents in alphabetical order

我正在使用 GemBox.Document 创建一个 Word 文档,该文档是通过组合多个文档生成的,并且我在开头插入了 TOC 元素(Table 的内容)。现在我需要按字母顺序排列该 TOC 元素。

我知道 Microsoft Word 中不存在此选项,TOC 始终按页面顺序排序,而不是按字母顺序排序,并且 TableOfEntries.Update() 方法默认情况下的行为与此类似。

不过,我希望有办法做到这一点。我确实检查了那些 TOC 开关,如果我没有遗漏什么,就没有开关,对吧?

最后,我知道索引表,但这不是我要找的。 TOC 元素更适合我想要获得的内容,但我需要按字母顺序排序。

您可以在更新 TOC 元素后“手动”对 TOC 条目进行排序,如下所示:

var document = DocumentModel.Load("input.docx");

var toc = (TableOfEntries)document.GetChildElements(true, ElementType.TableOfEntries).First();
toc.Update();

// Take current TOC entries.
var entries = toc.Entries.ToList();

// Remove them.
toc.Entries.Clear();

// Then place them back in sorted order.
entries.Sort((e1, e2) => e1.Content.ToString().CompareTo(e2.Content.ToString()));
entries.ForEach(e => toc.Entries.Add(e));

document.Save("output.docx");

但请注意,当使用 GemBox.Document 或某些 Word 应用程序再次更新 TOC 元素时,您将获得未排序的条目。

您在这里唯一可以做的就是防止其他人更新您的 TOC 元素,例如通过删除 TOC 并仅保留其条目(也就是取消链接内容的 Table):

toc.Content.Set(toc.Entries.Content);

或者您可以将 TOC 放在受保护的部分,从而防止从 Word 应用程序更新 TOC(请注意,您仍然可以使用 GemBox.Document 更新它):

// You mentioned that you're inserting the TOC element at the beginning
// which means that the "toc.Parent" should be document's first Section.
var section = document.Sections[0];

// If TOC is not the only element in a section then place it inside its own section.
if (section.Blocks.Count > 1)
{
    var tocSection = new Section(document);
    tocSection.PageSetup = section.PageSetup.Clone();
    tocSection.Blocks.Add(toc.Clone(true));

    document.Sections.Insert(0, tocSection);
    section.PageSetup.SectionStart = SectionStart.Continuous;
    toc.Content.Delete();
}

document.Protection.StartEnforcingProtection(EditingRestrictionType.FillingForms, "optional password");

// Unprotect all other Sections except the on that contains TOC element.
foreach (var otherSection in document.Sections.Skip(1))
    otherSection.ProtectedForForms = false;