【问题标题】:Sort Table of Contents in alphabetical order按字母顺序对目录进行排序
【发布时间】:2022-01-18 09:41:38
【问题描述】:

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

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

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

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

【问题讨论】:

  • Word 不会按字母顺序排列目录。索引可以。除非 Gembox 文档中有不同的内容,否则这是不可能的。这是一个编程论坛,而不是 Word 论坛。您的问题可能在此处离题,并且可能会在没有答案的情况下关闭。混乱是可以理解的。 stackoverflow.com/help/on-topic 这将是 Microsoft 社区 answers.microsoft.com/en-us/msoffice/forum/msoffice_word 或其他论坛上的适当问题。如果您确实在那里发布了一些内容,您应该在此处的问题中添加一个链接到那里的新问题以帮助其他人。
  • @CharlesKenyon 这不是题外话,GemBox.Document 是 C# 语言的编程库。无论如何,谢谢您的建议,如果我在这里没有得到答案,我也会尝试在那里询问。
  • 感谢您对我的教育。

标签: c# ms-word tableofcontents gembox-document


【解决方案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;

【讨论】:

  • 谢谢马里奥。保护 TOC 不被更新是一个绝妙的技巧!
猜你喜欢
  • 1970-01-01
  • 2011-08-29
  • 1970-01-01
  • 2022-01-13
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多