2017-02-06 8 views
1

OpenXMLライブラリを使用して、単語テンプレート(。dotx)から.docxファイルを作成しようとしています。より正確には、私はthisに従うことを試みていますが、ファイルへのパスではなくMemoryStreamを使用してドキュメントを開きたいとします。XML SDKを開きます - docxホルダーとしてMemoryStreamを使用してテンプレート(dotx)からdocxを作成します

上記のリンクのアプローチは次のとおりです。テンプレートファイルをディスク上の新しいファイルにコピーします。 WordProcessingDocumentとして新しいファイルを開き、そのタイプをDocumentに変更してテンプレートへの参照を追加してください(なぜこれが必要なのか分かりません...)

私が必要なのは何ですか。バイト配列としてDBからテンプレートを取得します。配列をストリームにコピーし、WordProcessingDocumentとして開きます。その後、上記と同じことをします。 ディスクなどの一時ファイルを使用したくありません。私が気付いていないのは、新しい文書のテンプレートファイルを参照する必要がある理由です(実際には、docxアーカイブのxmlファイルを調べると、テンプレートの名前を含むxmlノードが追加されます...理由?)

私の問題は、ファイルへの物理パスではなくMemoryStreamを使用すると、docxが壊れていることです。。 「一部の部分が見つからないか無効なため、Microsoft Officeでこのファイルを開くことができません。」です。 一時的なディスクファイルを使用すると動作します。 なぜこれが起こっていますか?

簡体は、私のコードは次のようになります。

byte[] result = null; 
byte[] templateBytes = System.IO.File.ReadAllBytes("template.dotx"); 
using (MemoryStream templateStream = new MemoryStream()) 

{ 
    templateStream.Write(templateBytes, 0, (int)templateBytes.Length); 

    using (WordprocessingDocument doc = WordprocessingDocument.Open(templateStream, true)) 
      { 
       doc.ChangeDocumentType(WordprocessingDocumentType.Document); 
       var mainPart = doc.MainDocumentPart; 

       //Here I should create an AttachedTemplate object and assign a relationship id to it, which also implies 
       //setting a "reference" to the template ? I'm not using files so there's nothing to "reference" anyway 
       // If it's doing more than just putting a visual reference to the template file, then why limit the way of referencing the template 
       // only by using the Uri to the file? Please take a look at the above link to see what I'm referring to. 

       //Write some text in the file .... 
       mainPart.Document.Save(); 

       File.WriteAllBytes("Result.docx", templateStream.ToArray()); 
      } 
    } 

これは私の破損のdocxファイルを取得します。私がMemoryStreamから(もしWordProcessingDocumentクラスの他のコンストラクタを使って)新しいdocxファイルをディスクから開くと、それは動作します。 私は間違ったことをしていません(メモリストリームを破棄した後に結果をファイルに書き込もうとするなど)ので、同じ結果が得られます。

私のコードで何が問題になっていますか?

おかげ

答えて

1

あなたは内部使用のブロックのうち、あなたのコードFile.WriteAllBytesの最後の行を取る場合は、それが正常に動作するはずです。ブロックを使用している外側の閉じ括弧の直前にその行を置きます。

+0

答えをありがとう、マイケル。それは遅く、私はそれを見ていない。あなたは正しいです、ドキュメントのusingブロックを終了することによって、Open XMLは変更を保存しており、アンマネージドリソースを閉じたり破棄したりしています。だから私は基本的に完全に保存されていないものを開くことを試みた。 – darkdante

関連する問題