我正在尝试在列表前插入文本。我有列表的Microsoft.Office.Interop.Word.Range
,并在列表前获取前一个Range。然后我尝试将段落文本添加到上一个范围,但是,段落被添加为列表中的第一个项目而不是列表之前。
// rangeObj is the Range object for the list
var previousRange = rangeObj.Previous(MSWord.WdUnits.wdCharacter, 1);
Paragraph paragraph;
if (previousRange == null)
{
var rangeCopy = rangeObj.Duplicate;
rangeCopy.InsertParagraphBefore();
paragraph = rangeCopy.Paragraphs[1];
}
else
{
paragraph = previousRange.Paragraphs[1];
}
Range range = paragraph.Range;
range.Text = String.Format("{0} {1}", "My list", range.Text);
E.g。 之前:
之后(我想要的):
我的清单
之后(我目前得到的):
修改 Per Lasse的回答和我的评论,除了下面的边缘情况外,我得到了一切。注意:第二个列表不是第一个列表的子列表,每个列表之间没有空行。
if (previousRange.ListParagraphs.Count > 0)
在:
第2项
之后(我想要的):
第2项
另一个清单:
答案 0 :(得分:1)
在此代码中:
else
{
paragraph = previousRange.Paragraphs[1];
}
..你冒着覆盖列表之前的任何东西的风险(包括其中只有\r
的空行),当我在样本上运行它时,很有意义的是事情被覆盖并且在端。
在此代码中:
if (previousRange == null)
{
var rangeCopy = rangeObj.Duplicate;
rangeCopy.InsertParagraphBefore();
paragraph = rangeCopy.Paragraphs[1];
}
..你在列表之前插入一个新段落(这很好 - 即使我不明白为什么有必要克隆范围,如the range automatically expands to include the newly inserted paragraph)然后存储新段落的范围在您的本地变量paragraph
中。此时,paragraph = '\r'
的内容 - (如果您在调试阶段使用调试器逐步执行应用程序,同时在调试阶段保持单词可见)。因此,此时光标位于列表之前,这是您想要的位置 - 但是您可以执行以下操作:
Range range = paragraph.Range;
range.Text = "My paragraph";
...意味着代替段落中的待处理文本,您只需覆盖包括\r
在内的所有内容,这会导致Word将文本插入列表而不是之前。
为了绕过这个,我做了一个似乎有效的替代实现。它基于您在列表前使用范围插入文本的想法。我已经为大多数行添加了注释,因此应该直接跟踪发生的事情:)
using System;
using System.Linq;
using Microsoft.Office.Interop.Word;
using Application = Microsoft.Office.Interop.Word.Application;
namespace WordDocStats
{
internal class Program
{
private static void Main()
{
var wordApplication = new Application() { Visible = true };
// Open document A
var documentA = wordApplication.Documents.Open(@"C:\Users\MyUser\Documents\documentA.docx", Visible: true);
// This inserts text in front of each list found in the document
const string myText = "My Text Before The List";
foreach (List list in documentA.Lists)
{
// Range of the current list
var listRange = list.Range;
// Range of character before the list
var prevRange = listRange.Previous(WdUnits.wdCharacter);
// If null, the list might be located in the very beginning of the doc
if (prevRange == null)
{
// Insert new paragraph
listRange.InsertParagraphBefore();
// Insert the text
listRange.InsertBefore(myText);
}
else
{
if (prevRange.Text.Any())
{
// Dont't append the list text to any lines that might already be just before the list
// Instead, make sure the text gets its own line
prevRange.InsertBefore("\r\n" + myText);
}
else
{
// Insert the list text
prevRange.InsertBefore(myText);
}
}
}
// Save, quit, dones
Console.WriteLine("Dones");
Console.ReadLine();
documentA.Save();
wordApplication.Quit();
}
}
}
简而言之,代码在给定文档中的每个列表之前插入一个字符串。如果列表前面的行上已有文本,则实现确保在列表之前和列表前行上的文本之后插入列表描述文本。
希望这会有所帮助:)
---更新以回答已修改的问题:
在第二轮中完成你所要求的方法是做一些事情:
...
// The paragraph before the current list is also a list -> so in order to insert text, we must do "some magic"
else if(prevRange.ListParagraphs.Count > 0)
{
// First, insert a new line -> this causes a new item to be inserted into the above list
prevRange.InsertAfter("\r");
// Modify current range to be on the line of the new list item
prevRange.Start = prevRange.Start + 1;
prevRange.End = prevRange.Start;
// Convert the list item line into a paragraph by removing its numbers
prevRange.ListFormat.RemoveNumbers();
// Insert the text
prevRange.InsertBefore(myText);
}
...
只需将该代码添加到我上面提供的示例代码的if-else
循环内的foreach
块中,您应该很高兴:)我已经在我的机器上用MS Word测试了它2013年,似乎有效。