我正在尝试复制docx文件内容并使用C#中的OpenXML将它们保存在同一文件中
以下是代码:
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(wordFileNamePath, true))
{
foreach(OpenXmlElement element in wordDoc.MainDocumentPart.Document.ChildElements)
{
OpenXmlElement cloneElement = (OpenXmlElement)element.Clone();
wordDoc.MainDocumentPart.Document.Append(cloneElement);
}
wordDoc.MainDocumentPart.Document.Save();
}
代码工作正常,做我需要的。我的问题是生成的docx文件部分损坏。当我打开文件时,我收到以下两条消息:
单击“确定”,然后单击“是”将正常打开文件。但是,文件一直被破坏,直到我'保存为'它(使用相同或不同的名称)。这就是新保存文件的修复方式。
通过使用适用于Microsoft Office的Open XML SDK 2.5生产力工具,我可以验证文件并查看反映的代码。验证文件将产生以下5个错误:
所以我认为我在代码中使用的“Clone”函数会复制元素,因此当它附加到文档时,会发生一些ID重复。
任何想法在复制后获得正确的DOCX文件?任何替代代码都表示赞赏。
答案 0 :(得分:0)
您的方法存在的问题是它创建了无效的Open XML标记。这就是为什么。
假设您有一个非常简单的Word文档,该文档由以下标记表示:
undefined
在您的<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:r>
<w:t>First paragraph</w:t>
</w:r>
</w:p>
<w:p>
<w:r>
<w:t>Second paragraph</w:t>
</w:r>
</w:p>
<w:body>
<w:document>
循环中,foreach
将是一个仅包含wordDoc.MainDocumentPart.Document.ChildElements
元素的单元素列表。因此,您将创建w:body
元素的深层克隆并将其附加到w:body
。最终的Open XML标记如下:
w:document
上面是一个<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:r>
<w:t>First paragraph</w:t>
</w:r>
</w:p>
<w:p>
<w:r>
<w:t>Second paragraph</w:t>
</w:r>
</w:p>
<w:body>
<w:body>
<w:p>
<w:r>
<w:t>First paragraph</w:t>
</w:r>
</w:p>
<w:p>
<w:r>
<w:t>Second paragraph</w:t>
</w:r>
</w:p>
<w:body>
<w:document>
,带有两个w:document
子元素,这是无效的Open XML标记,因为w:body
必须恰好有一个w:document
子元素。因此,Word会显示该错误消息。
要解决此问题,无论您何时使用w:body
,都需要使用Document.Body
。下面的精简示例显示了操作方法。
Document
您将看到我没有显式保存using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(wordFileNamePath, true))
{
Body body = wordDoc.MainDocumentPart.Document.Body;
IEnumerable<OpenXmlElement> clonedElements = body
.Elements()
.Select(e => e.CloneNode(true))
.ToList();
body.Append(clonedElements);
}
,因为Document
语句和默认情况下自动保存这些文档的事实,这并不必要。其次,我在追加之前使用using
来实现集合。这是为了避免在枚举同时更改的元素时出现任何问题。
答案 1 :(得分:-1)
为什么不会被破坏?您正在打开文档,获取所有子元素,并将它们写入同一文档。我不确定应该做什么。