简体   繁体   English

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

[英]Sort Table of Contents in alphabetical order

I'm using GemBox.Document to create a Word document that's generated from combining multiple documents and I'm inserting the TOC element (Table of Content) at the beginning.我正在使用GemBox.Document创建通过组合多个文档生成的 Word 文档,并且在开头插入 TOC 元素(目录)。 Now I need to alphabetize that TOC element.现在我需要按字母顺序排列那个 TOC 元素。

I'm aware that this option doesn't exist in Microsoft Word, the TOC is always sorted in page order, not in alphabetical order, and that the TableOfEntries.Update() method behaves like that by default.我知道 Microsoft Word 中不存在此选项,TOC 始终按页面顺序排序,而不是按字母顺序排序,并且默认情况下TableOfEntries.Update()方法的行为与此类似。

Nevertheless, I'm hoping there is a way to do that.不过,我希望有办法做到这一点。 I did check those TOC switches and if I'm not missing something, there is no switch for this, right?我确实检查了那些 TOC 开关,如果我没有遗漏什么,就没有开关,对吧?

Last, I'm aware of index tables, but that's not what I'm looking for.最后,我知道索引表,但这不是我想要的。 The TOC element is a much better fit to what I'm trying to get, but I need it sorted alphabetically. TOC 元素更适合我想要得到的东西,但我需要它按字母顺序排序。

You can "manually" sort the TOC entries after updating the TOC element, like this:您可以在更新 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");

But note that when the TOC element is updated again, either with GemBox.Document or with some Word application, you will get unsorted entries.但请注意,当再次更新 TOC 元素时,无论是使用 GemBox.Document 还是使用某些 Word 应用程序,您都会得到未排序的条目。

The only thing you can do here is to prevent others from updating your TOC element, for example by removing the TOC and keeping just its entries (aka unlinking the Table of Content):您在这里唯一可以做的就是防止其他人更新您的 TOC 元素,例如通过删除 TOC 并仅保留其条目(也就是取消链接目录):

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

Or you could place the TOC in a protected Section and thus prevent TOC update from Word applications (note that you'll still be able to update it with GemBox.Document):或者您可以将 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM