1

我正在尝试以下代码。它需要一个文件名(包含许多部分的 docx 文件),我尝试遍历每个部分以获取部分名称。问题是我最终得到了不可读的 docx 文件。它没有错误,但我认为我在获取该部分中的元素时做错了。

public void Split(string fileName) {
            using (WordprocessingDocument myDoc =
                WordprocessingDocument.Open(fileName, true)) {
                string curCliCode = "";
                MainDocumentPart mdp = myDoc.MainDocumentPart;

                foreach (var element in mdp.Document.Body.ChildElements) {
                    if (element.Descendants().OfType<SectionProperties>().Count() == 1) {
                        //get the name of the section from the footer
                        var footer = (FooterPart) mdp.GetPartById(
                                                      element.Descendants().OfType<SectionProperties>().First().OfType
                                                          <FooterReference>().First().
                                                          Id.Value);
                        foreach (Paragraph p in footer.Footer.ChildElements.OfType<Paragraph>()) {
                            if (p.InnerText != "") {
                                curCliCode = p.InnerText;
                            }
                        }
                        if (curCliCode != "") {
                            var forFile = new List<OpenXmlElement>();
                            var els = element.ElementsBefore();
                            if (els != null) {
                                foreach (var e in els) {
                                    if (e != null) {
                                        forFile.Add(e);
                                    }
                                }
                                for (int i = 0; i < els.Count(); i++) {
                                    els.ElementAt(i).Remove();
                                }
                            }
                            Create(curCliCode, forFile);
                        }
                    }
                }

            }
        }
        private void Create(string cliCode,IEnumerable<OpenXmlElement> docParts) {
            var parts = from e in docParts select e.Clone();
            const string template = @"\Test\toSplit\blank.docx";
            string destination = string.Format(@"\Test\{0}.docx", cliCode);
            File.Copy(template, destination,true);
            /* Create the package and main document part */
            using (WordprocessingDocument myDoc =
                WordprocessingDocument.Open(destination, true)) {
                MainDocumentPart mainPart = myDoc.MainDocumentPart;
                /* Create the contents */
                foreach(var part in parts) {
                    mainPart.Document.Body.Append((OpenXmlElement)part);
                }

                /* Save the results and close */
                mainPart.Document.Save();
                myDoc.Close();
            }
        }

有谁知道问题可能是什么(或如何正确地将一个部分从一个文档复制到另一个文档)?

4

2 回答 2

1

与您所做的类似的方法仅适用于简单文档(即那些不包含图像、超链接、评论等的文档)。要处理这些更复杂的文档,请查看http://blogs.msdn.com/b/ericwhite/archive/2009/02/05/move-insert-delete-paragraphs-in-word-processing-documents-using -the-open-xml-sdk.aspx和生成的 DocumentBuilder API(CodePlex 上的 PowerTools for Open XML 项目的一部分)。

为了使用 DocumentBuilder 将 docx 拆分为多个部分,您仍然需要首先找到包含 sectPr 元素的段落的索引。

于 2011-01-11T22:45:18.363 回答
1

我在这方面做了一些工作,我发现无价的是将已知好的文件与预期文件进行比较;错误通常相当明显。

我要做的是获取一个您知道有效的文件,并将所有部分复制到模板中。理论上,这两个文件应该是相同的。在 docx 文件中的 document.xml 上运行它们的差异,您会看到差异。

顺便说一句,我假设您知道 docx 实际上是一个 zip;将扩展名更改为“zip”,您将能够获得构成该格式的实际 xml 文件。

至于差异工具,我使用 Scooter Software 的 Beyond Compare。

于 2011-01-11T17:36:50.757 回答