使用Word Interop在列表之前插入文本 [英] Insert text before a list using Word Interop

查看:117
本文介绍了使用Word Interop在列表之前插入文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在列表之前插入文本.我有列表的Microsoft.Office.Interop.Word.Range,并在列表之前获得了上一个Range.然后,我尝试将段落文本添加到上一个范围,但是,该段落被添加为列表中的第一项,而不是列表之前.

I'm trying to insert text before a list. I have the Microsoft.Office.Interop.Word.Range of the list, and get the previous Range before the list. I then try to add my paragraph text to the previous range, however, the paragraph is added as the first item in the list instead of before the list.

// 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项

(我想要的)之后:

我的列表

  1. 第1项
  2. 第2项

之后(我现在正在得到什么):

After (What I'm currently getting):

  1. 我的列表
  2. 第1项
  3. 第2项

根据Lasse的回答和我的评论,除以下情况外,我正在使所有工作正常进行.注意:第二个列表不是第一个列表的子列表,并且每个列表之间没有空行.

Per Lasse's answer and my comment, I'm getting everything to work except for the following edge case. Note: The 2nd list is not a sub list of the first one and there's no empty lines in-between each list.

if (previousRange.ListParagraphs.Count > 0)

之前:

  1. 第1项
  2. 项目2

  1. Item 1
  2. Item 2

  1. 第3项
  2. 第4项

之后(我想要什么):

  1. 第1项
  2. 项目2

  1. Item 1
  2. Item 2

另一个列表:

  1. 第3项
  2. 第4项

推荐答案

在此代码中:

else 
{
  paragraph = previousRange.Paragraphs[1];  
}

..您冒着覆盖列表之前的任何内容的风险(包括其中仅包含\r的空行),当我在示例中运行它时,事情被覆盖并最终发生怪异是很有意义的.

.. you are risking overwriting anything before the list (including empty lines with only \r in it), and when I run it on a sample, it makes good sense that things gets overwritten and occur weird in the end.

在此代码中:

if (previousRange == null)
{
  var rangeCopy = rangeObj.Duplicate;
  rangeCopy.InsertParagraphBefore();
  paragraph = rangeCopy.Paragraphs[1];
}

..您在列表之前插入一个新段落(很好-尽管我看不到为什么有必要克隆该范围,如

.. you insert a new paragraph before the list (which is fine - even though, I cannot see why it would be necessary to clone the range, as the range automatically expands to include the newly inserted paragraph) and then stores the range of the new paragraph in your local variable paragraph. At this point, the content of paragraph = '\r' - (this is seen if you step through your application with a debugger while keeping word visible during the debugging phase). So, at this point the cursor is positioned just before the list, which is where you want it to be - but then you do the following:

Range range = paragraph.Range;
range.Text = "My paragraph";

...意味着您无需覆盖文本到段落前,只需覆盖所有内容,包括\r,这将导致Word在列表中而不是文本之前插入文本.

... meaning that instead of pre-pending text to the paragraph, you simply overwrite everything including the \r, which causes Word to insert the text in the list instead of before it.

要绕过这个问题,我做了一个可行的替代实现.它基于您的想法,即使用列表前的范围来插入文本.我为大多数行添加了注释,因此应该顺理成章地进行:)

To bypass this, I have made an alternative implementation that seems to work. It is based on your idea of using the range before the list to insert text. I have added comments for most of the lines, so it should be straight forward to follow what is going on :)

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

简而言之,代码在给定文档的每个列表之前插入一个字符串.如果列表前面的行中已经有文本,则实现将确保在列表之前和列表之前的行中插入列表描述文本.

In short, the code inserts a string before each list in the given document. If there is already text on the line before the list, the implementation makes sure to insert the list description text before the list and after the text that was already on the line before the list.

希望这会有所帮助:)

---更新以回答已编辑的问题:

--- UPDATE to answer to edited question:

在第二轮中完成您要问的一种方法是执行以下操作:

A way to accomplish what you are asking here in the second round is doing something like:

...
// 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块中,您就可以使用了:)我已经在我的机器上使用MS Word 2013对它进行了测试,似乎有效.

Just add that code to the if-else block inside the foreach loop of the sample code I have provided above and you should be good to go :) I have tested it on my machine with MS Word 2013, and it seems to work.

这篇关于使用Word Interop在列表之前插入文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆