如何使用C#和Open XML SDK按特定文本拆分Word文档?

时间:2012-08-02 08:24:49

标签: c# ms-word openxml openxml-sdk

我想使用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();

                }
            }
        }
    }

1 个答案:

答案 0 :(得分: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();
        }
    }