gpt4 book ai didi

c# - 使用 Word Interop 在列表前插入文本

转载 作者:太空宇宙 更新时间:2023-11-03 13:52:28 25 4
gpt4 key购买 nike

我正在尝试在列表前插入文本。我有列表的 Microsoft.Office.Interop.Word.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);

例如之前:

  1. 项目 1
  2. 第 2 项

之后(我想要什么):

我的 list

  1. 项目 1
  2. 第 2 项

之后(我目前得到的):

  1. 我的 list
  2. 项目 1
  3. 第 2 项

编辑:根据 Lasse 的回答和我的评论,除了以下极端情况外,我正在让一切正常工作。注意:第二个列表不是第一个列表的子列表,每个列表之间没有空行。

if (previousRange.ListParagraphs.Count > 0)

之前:

  1. 项目 1
  2. 项目 2

    1. 第 3 项
    2. 第 4 项

之后(我想要的):

  1. 项目 1
  2. 项目 2

    另一个列表:

    1. 第 3 项
    2. 第 4 项

最佳答案

在这段代码中:

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);
}
...

只需将该代码添加到我上面提供的示例代码的 foreach 循环内的 if-else block 中,您就可以开始了 :) 我有在我的机器上使用 MS Word 2013 对其进行了测试,它似乎可以正常工作。

关于c# - 使用 Word Interop 在列表前插入文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13311310/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com