0

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

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

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

最后,我知道索引表,但这不是我想要的。TOC 元素更适合我想要得到的东西,但我需要它按字母顺序排序。

4

1 回答 1

1

您可以在更新 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");

但请注意,当再次更新 TOC 元素时,无论是使用 GemBox.Document 还是使用某些 Word 应用程序,您都会得到未排序的条目。

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

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;
于 2021-12-18T15:28:31.643 回答