【问题标题】:C#: Insert and indent bullet points at bookmark in word document using Office Interop librariesC#:使用 Office 互操作库在 word 文档中的书签处插入和缩进项目符号点
【发布时间】:2023-03-09 00:33:01
【问题描述】:

这是我的困境。我的任务是根据来自 Web 前端的用户输入生成现有 Word 文档的特定部分。系统的后端是用 C# 编写的,其中部分是使用 Microsoft.Office.Interop.Word 命名空间编辑 word 文档。

基本上,他们会从可用指令列表中进行选择,每个指令的类型为string,然后将用于生成文档的指令部分,每个单独的指令是列表中的另一个项目符号。这部分工作正常。我的问题是,说明可以包含字符\,需要用缩进替换,或者如果您用word打开文档,则相当于在项目符号中按TAB。到目前为止,我能够让它很好地将项目符号插入列表的中间,它会继续按预期对它们进行适当的编号。关键是我无法根据需要缩进它们。

我已经尝试了几乎所有可以在此处和其他一些网站上找到的示例以使其正常工作,但没有成功。最新的迭代在下面的代码中,它只是尽可能地缩进整个列表。

var bookmark = "bookMarkName";
var docPath = @"c:\temp\Template.docx";
var app = new Application();
var doc = app.Documents.Open(docPath);
var range = doc.Bookmarks[bookmark].Range;
var listTemplate = range.ListFormat.ListTemplate;

range.ListFormat.ApplyListTemplate(listTemplate);

string[] bulletList = new string[] {
    @"Point A",
    @"\Point B",
    @"\Point C",
    @"\\Point D",
    @"Point E"
}

var count = bulletList.Length;

for (var i = 0; i < count; i++)
{
    var listLevel = 0;
    var currentItem = bulletList[i];
    var item = currentItem.Replace(@"\", "");

    if (i < count - 1)
        item = item + "\n";

    listLevel += currentItem.ToList().Where(x => x == '\\').Select(x => x).Count();

    for (var x = 0; x < listLevel; x++)
    {
        range.ListFormat.ListIndent();
    }

    range.InsertAfter(item);
}

doc.SaveAs(@"c:\temp\" + DateTime.Now.Ticks + ".docx");
doc.Close();

所以我的代码的输出应该是:

  • 1 点 A
    • 1.1 B点
    • 1.2 C 点
      • 1.2.1 D点
  • 2 点 E

这是我第一次真正不得不使用 Office 互操作库,所以我很肯定这里缺少一些东西。任何帮助将不胜感激。

【问题讨论】:

  • 嗯,你不应该等到确定反斜杠的数量(该项目属于哪个级别)之后再替换反斜杠吗?
  • 我想。我什至不知道如何在插入它们时缩进它们。事后我不知道从哪里开始追踪可能的几十个列表项。
  • 如果没有 Word 如何处理此问题的背景知识,您的问题就“过于宽泛”了——尽管我表示同情。 Word 的这一部分很困难,即使在 UI 中也是如此。但是,如果我试图按现状回答这个问题,我们将一事无成,我担心......
  • 我建议您首先以用户身份打开 Word 并研究如何创建这样的列表。您需要 Home 选项卡、Paragrph 组、Multilevel List 按钮。画廊中的任何内容都不会符合您的要求,因此请从菜单中选择“定义新的多级列表”。您将看到九个级别 - 选择一个级别以更改其外观。现在,转到此级别的数字样式并查找项目符号条目。为您要支持的每个级别选择一个项目符号。尝试使用缩进和其他东西,直到你得到一个你希望它的外观和理解你正在处理的内容的列表。
  • @DanS。由于项目符号缩进量由每条指令中的反斜杠数量控制,为什么不为所需的每个级别创建样式,然后根据每条指令中的反斜杠计数将样式应用于文本范围?

标签: c# ms-word office-interop


【解决方案1】:

我的计算机上没有 Office Interop,但您可以尝试使用 DocX 构建列表,将其写入文件,然后从所述文件将该列表插入到您的文档中。

类似这样的:

using System.Collections.Specialized;
...
...

DocX doc = DocX.Create("bullet-text.docx");

var firstItem = bulletList[0];
var firstItemLevel = firstItem.ToList().Count(c => c == '\\');
// Using full Namespace to avoid ambiguous reference error.
Xceed.Words.NET.List list = doc.AddList(firstItem.Replace("\\", ""), firstItemLevel, ListItemType.Numbered);

for (var i = 1; i < count; i++)
{
    var currentItem = bulletList[i];
    var item = currentItem.Replace(@"\", "");
    int listLevel = currentItem.ToList().Count(c => c == '\\')

    doc.AddListItem(list, item, listLevel, ListItemType.Numbered);

}

doc.InsertList(list);

doc.Save();

// Collapse the range to the end, as to not overwrite it. Unsure if you need this
range.Collapse(WdCollapseDirection.wdCollapseEnd);

// Insert into the selected range
range.InsertFile(Environment.CurrentDirectory + "\\bullet-text.docx");

我引用的参考文献:

Nested Bulleted lists in Novacode docx

How to embed file to word docx?

Collapse

InsertFile

【讨论】:

  • 这成功了!我确信仅使用互操作库可以达到类似的解决方案,但这解决了问题。让它继续编号有一个小问题,但它解决了在现有文档中插入和缩进列表项的实际问题。
  • 我必须对您的代码进行一些更改才能使其正常工作。 1) 在循环外初始化 list 变量,以便我可以在循环内访问它,2) 将 doc.InsertList(list); 调用移到循环外以防止生成重复项,以及 3) 将 range.Collapse 调用更改为包括完整的枚举名称,range.Collapse(WdCollapseDirection.wdCollapseEnd)
  • 很高兴听到它
【解决方案2】:

请使用此代码,但首先Add DocX DLL

 using (var document = DocX.Create(@"docs\Lists.docx"))
    {
        var numberedList = document.AddList("First List Item.", 0, ListItemType.Numbered);
                //Add a numbered list starting at 2
        document.AddListItem(numberedList, "Second List Item.");
        document.AddListItem(numberedList, "Third list item.");
        document.AddListItem(numberedList, "First sub list item", 1);

        document.AddListItem(numberedList, "Nested item.", 2);
        document.AddListItem(numberedList, "Fourth nested item.");

        var bulletedList = document.AddList("First Bulleted Item.", 0, ListItemType.Bulleted);
        document.AddListItem(bulletedList, "Second bullet item");
        document.AddListItem(bulletedList, "Sub bullet item", 1);
        document.AddListItem(bulletedList, "Second sub bullet item", 2);
        document.AddListItem(bulletedList, "Third bullet item");

        document.InsertList(numberedList);
        document.InsertList(bulletedList);
        document.Save();
        Console.WriteLine("\tCreated: docs\\Lists.docx");
    }

找到Reference From Here

【讨论】:

  • 这不能解决我的问题。我需要向现有文档添加列表,而不是创建新文档。我尝试使用 DocX 库来执行此操作。 InsertList 方法能够在文档中的特定字符索引处插入列表。这似乎可以解决问题,但该库没有提供任何实际获取任何索引的方法,至少不是我能够找到的。
  • 但最后你可以使用这个库来解决我猜想的一些不同代码的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
  • 2011-04-07
  • 1970-01-01
相关资源
最近更新 更多