私は2つの単語文書をOpenXML SDKでマージしていますが、画像をヘッダーにコピーするときに破損した文書を入手しています

StackOverflow https://stackoverflow.com//questions/9617372

  •  09-12-2019
  •  | 
  •  

質問

私は、文書の本文に画像をコピーするときなど、あらゆる種類のさまざまな状況で機能するコードがあります。

コピーされているヘッダー/フッターに画像が含まれていない限り、1つの文書からヘッダーとフッターをコピー(追加)したときにコードが機能します。

イメージを持つヘッダーをコピーすると、結果のファイルは破損しています.OpenXML SDKで開こうとすると、「圧縮部分が矛盾するデータ長が矛盾している」という例外をスローします。 私は、イメージがヘッダーパートで作成されなければならないことを知っています(本文にコピーするときの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に描画要素を見つけられない場合)。

私は、ヘッダー内の画像のこの症状がおそらく赤のニシンであるかどうか、そして本当の問題は他のどこかであるのだろうか。

役に立ちましたか?

解決

質問についてのコメントで、画像を含むコードとフッターには素晴らしかったコードです - それはトリックをしました。

私のコード(他の場所)が作成されていた破損ファイルの問題は、少し試行錯誤によって解決されました。他の貢献者が言ったように、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に書き込む直前に再び上書き方法を呼び出すと、破損は回避されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top