我正在使用OpenXML SDK合并两个Word文档,但在将图像复制到标题时会出现损坏的文档
我的代码适用于各种不同的情况,包括将图像复制到文档正文中。
只要正在复制的页眉/页脚不包含图像,代码就可以在将页眉和页脚从一个文档复制(添加)到另一个文档时起作用。
当我复制其中包含图像的标头时,生成的文件已损坏,当我尝试使用OpenXML SDK打开它时,它会抛出一个exception,说“压缩部分的数据长度不一致”。 我知道必须在HeaderPart中创建图像(与复制到主体时的MainDocumentPart相对)。
合并图像的代码如下所示:
private void AddSourceImagesToDestination(XElement sourceXml, OpenXmlPart sourcePart, OpenXmlPart destPart) { foreach(XElement drawingElement in sourceXml.Descendants(_mswDrawingElementName)) { XAttribute aBlipEmbedAttribute = drawingElement.Descendants(_ablipElementName).First().Attribute(_embedAttributeName); string relationshipId = aBlipEmbedAttribute.Value; ImagePart sourceImagePart = (ImagePart)sourcePart.GetPartById(relationshipId); ImagePart destinationImagePart = ((HeaderPart)destPart).AddImagePart(sourceImagePart.ContentType); string newRelationshipId = destPart.GetIdOfPart(destinationImagePart); aBlipEmbedAttribute.SetValue(newRelationshipId); destinationImagePart.FeedData(sourceImagePart.GetStream(FileMode.Open, FileAccess.Read)); } }
上面的内容称为传递源和目标HeaderParts,以及源头的XML,在此之后将其复制到目标文档中。 调用上述过程后,调用destinationHeaderPart.Header.Save()。
如上所述,如果源标头中没有图像,则生成的文档很好(即当foreach在源XML中找不到任何绘图元素时)。
不过,我想知道标题中图像的这种症状是否可能是红鲱鱼,真正的问题是在其他地方。
正如我在关于这个问题的评论中所说,将图像包含在页眉和页脚中的代码很好 – 它完成了诀窍。
我如何解决我的代码(其他地方)正在创建的损坏文件的问题是通过一些试验和错误。 正如其他贡献者所说,围绕OpenXML的文档,温和地说,并不是很好。 所以可能会有另一个解决这个问题的方法,也许我的“解决方案”因其他一些副作用而起作用。
无论如何,我有一些看起来像这样的代码:
private MemoryStream _memoryStream; private WordprocessingDocument _wordDocument; ... _wordDocument = WordprocessingDocument.Open(_memoryStream, true); ... private void ReopenDocument() { _wordDocument.Package.Flush(); _wordDocument.Close(); MemoryStream newStream = new MemoryStream(); _memoryStream.WriteTo(newStream); _memoryStream.Close(); _memoryStream = newStream; _memoryStream.Position = 0L; _wordDocument = WordprocessingDocument.Open(_memoryStream, true); }
如果在将_memoryStream写入FileStream之前立即调用ReopenDocument方法,则会避免损坏。
- System.Net.HttpWebResponse.GetResponseStream()在WebException中返回截断的主体
- 检查整数类型是否属于枚举成员
- (Console.BufferHeight)我无法看到/滚动以查看Console.WriteLine的所有控制台输出
- 无法将T value1与T value2 = default(T)进行比较。 为什么以及如何在C#上做到这一点?
- ProgressBar在Windows窗体中很慢
- 在Linq中执行Parent然后Child排序
- 如何将字符串值转换为对象属性名称
- 为什么我们需要SqlCeCommand.Parameters.AddWithValue()来插入一个值?
- 在C#中使除法返回double的最佳做法是什么?