2

我想使用 C# 和 Open XML SDK 以编程方式将 Word 文档一分为二。我为第一部分所做的是删除所有段落,直到包含所需文本的段落。这工作得很好。然后在原始文档的副本上,我做了同样的事情,只是这次删除了从包含所需文本的段落开始的所有段落。由于某种原因,第二部分原来是无效的文档,无法使用 word 打开。使用“Open XML SDK 2.0 Productivity Tool”打开损坏的文档并对其进行验证,未检测到文档有任何问题。

这是在所需文本之前删除部分的代码(工作正常):

public static void DeleteFirstPart(string docName)
    {
        using (WordprocessingDocument document = WordprocessingDocument.Open(docName, true))
        {
            DocumentFormat.OpenXml.Wordprocessing.Document doc = document.MainDocumentPart.Document;

            List<Text> textparts = document.MainDocumentPart.Document.Body.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>().ToList();
            foreach (Text textfield in textparts)
            {
                if (!textfield.Text.Contains("split here"))
                {
                    RemoveItem1(textfield);
                }
                else
                {
                    break;
                }
            }
        }
    }

我尝试了两种不同的删除项目方法,都具有相同的结果:

private static void RemoveItem1(Text item)
    {
        // Need to go up at least two levels to get to the run.
        if ((item.Parent != null) &&
          (item.Parent.Parent != null) &&
          (item.Parent.Parent.Parent != null))
        {
            var topNode = item.Parent.Parent;
            var topParentNode = item.Parent.Parent.Parent;
            if (topParentNode != null)
            {
                topNode.Remove();
                // No more children? Remove the parent node, as well.
                if (!topParentNode.HasChildren)
                {
                    topParentNode.Remove();
                }
            }
        }
    }


private static void RemoveItem2(Text textfield)
    {
        if (textfield.Parent != null)
        {
            if (textfield.Parent.Parent != null)
            {
                if (textfield.Parent.Parent.Parent != null)
                {
                    textfield.Parent.Parent.Remove();
                }
                else
                {
                    textfield.Parent.Remove();
                }
            }
            else
            {
                textfield.Remove();
            }
        }   
    }

这是从所需文本开始删除部分的代码(损坏文档):

public static void DeleteSecondPart(string docName)
    {
        using (WordprocessingDocument document = WordprocessingDocument.Open(docName, true))
        {
            DocumentFormat.OpenXml.Wordprocessing.Document doc = document.MainDocumentPart.Document;

            List<Text> textparts = document.MainDocumentPart.Document.Body.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>().ToList();
            bool remove = false;
            foreach (Text textfield in textparts)
            {
                if (textfield.Text.Contains("split here"))
                {
                    remove = true;
                }

                if(remove)
                {
                    RemoveItem1(textfield);
                    //Using this commented code line, instead of the one above, removes only the text field itself, it works fine, the document is valid, but it leaves empty paragraphs that could be pages long.
                    //textfield.Remove();

                }
            }
        }
    }
4

1 回答 1

2

重写 RemoveItem 方法就成功了:

 private static void RemoveItem3(Text textfield)
    {
        OpenXmlElement element = textfield;
        while (!(element.Parent is DocumentFormat.OpenXml.Wordprocessing.Body) && element.Parent != null)
        {
            element = element.Parent;
        }

        if (element.Parent != null)
        {
            element.Remove();
        }
    }
于 2012-08-02T11:19:06.570 回答