2

画像をドキュメントの本文にコピーする場合など、さまざまな状況で機能するコードがあります。

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

画像を含むヘッダーをコピーすると、結果のファイルが破損し、OpenXML SDKで開こうとすると、「圧縮された部分のデータ長に一貫性がありません」という例外がスローされます。画像は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));
      }  
  }

上記は、ソースと宛先のヘッダーパーツ、およびこの後に宛先ドキュメントにコピーされるソースヘッダーのXMLの受け渡しと呼ばれます。上記のプロシージャを呼び出した後、destinationHeaderPart.Header.Save()が呼び出されます。

上で述べたように、ソースヘッダーに画像がない場合、結果のドキュメントは問題ありません(つまり、foreachがソースXMLで描画要素を見つけられない場合)。

しかし、ヘッダーの画像のこの症状はおそらく赤いニシンであり、本当の問題はどこかにあるのではないかと思います。

4

1 に答える 1

4

質問へのコメントで述べたように、画像をヘッダーとフッターに含めるコードは問題ありませんでした。

私のコード(他の場所)が作成していた破損したファイルの問題をどのように解決したかは、少し試行錯誤したことによるものでした。他の寄稿者が言っているように、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メソッドを呼び出すと、破損が回避されます。

于 2012-04-02T07:56:26.313 に答える