2012-03-08 30 views
1

文書の本文に画像をコピーする場合を含め、あらゆる状況で動作するコードがあります。2つのWord文書をOpenXML SDKとマージしていますが、画像をヘッダにコピーするときに壊れた文書を取得します。

コードは、コピーされているヘッダー/フッターにイメージが含まれていない限り、あるドキュメントから別のドキュメントにヘッダーとフッターをコピー(追加)するときに機能します。

イメージがあるヘッダーをコピーすると、結果のファイルが破損し、OpenXML SDKで開こうとすると「圧縮された部分のデータの長さが一貫しません」という例外がスローされます。 私は、画像をHeaderPartで作成しなければならないことを知っています(本体にコピーするときは、MainDocumentPartと同じように)。上記ソース及び宛先HeaderPartsを渡すと呼ばれ、この後にコピーされるソースヘッダのXML

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)); 
     } 
    } 

画像のマージを行うコードは次のように見えます宛先文書。上記のプロシージャを呼び出した後、destinationHeaderPart.Header.Save()が呼び出されます。

ソースヘッダーにイメージがない場合、結果のドキュメントは正常です(つまり、foreachがソースXMLで描画要素を見つけられない場合)。

ヘッダー内の画像のこの症状が、おそらく赤ちゃんであり、本当の問題がどこか他の場所にあるのかどうか、私は不思議です。

+0

解決策にもう少し近づいています。上記のコードスニペットは、実際に必要なものです。この問題は、私がXMLで行ったこととImagePartを追加することで出力文書に正しく書かれるように、正しいSDK呼び出しを取得してどこかにあるようだ。まだ働いています... – Peter

答えて

3

私が質問のコメントで言ったように、ヘッダーとフッターにイメージを含めるコードはうまくいきました - それはトリックでした。

私のコード(他の場所)が作成していた破損したファイルの問題を、どのように解決したかは、少しの試行錯誤によるものです。他の貢献者が言っているように、OpenXMLに関するドキュメントは、それを軽く置くのはあまり良くありません。ですから、この問題には別の解決策があるかもしれません。私の "解決策"は、他の副作用のために機能するかもしれません。

とにかく、私はこのようになりますいくつかのコードがあります:私は、FileStreamをする_memoryStreamを書き込む前すぐReopenDocumentメソッドを呼び出す場合

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); 
    } 

を、その後、破損が回避されます。

+0

こんにちは。この回答は私には役に立ちました。しかし、同様の問題がありましたが、私が見つけたことは、内容を読む前に_wordDocumentを適切に処分しなければならないことです。 – eburgos

関連する問題