2013-08-06 2 views
16

OpenXMLドキュメントを作成するためにMicrosoftのOpenXML 2.5ライブラリを使用しようとしています。ドキュメントにHTML文字列を挿入しようとするまで、すべてがうまくいきます。私は(私はとのトラブルを抱えていますちょうど部分に切り取ら)ウェブを精練し、ここで私は今のところ出ているものですしている:OpenXML(* .docx)ドキュメントにHTML文字列を追加

明らか
Paragraph paragraph = new Paragraph(); 
Run run = new Run(); 

string altChunkId = "id1"; 
AlternativeFormatImportPart chunk = 
     document.MainDocumentPart.AddAlternativeFormatImportPart(
      AlternativeFormatImportPartType.Html, altChunkId); 
chunk.FeedData(new MemoryStream(Encoding.UTF8.GetBytes(ioi.Text))); 
AltChunk altChunk = new AltChunk { Id = altChunkId }; 

run.AppendChild(new Break()); 

paragraph.AppendChild(run); 
body.AppendChild(paragraph); 

、私は実際にこの例ではaltChunkを追加していません、私は実行、段落、本文などにどこにでも追加しようとしました。これまでの場合、Word 2010でdocxファイルを開くことができません。

これは、それは簡単であるはずです(私はAltChunkの「もの」を完全に理解していないと認めます)。助けていただければ幸いです。

サイドノート:興味深いのは、実際に問題があるかどうかわからないことですが、this responseは、MemoryChannelから作業するときにAltChunkがファイルを破壊すると言います。誰もがこれが真実ではないことを確認できますか?

+0

Word 2010で生成されたdocxファイルを開こうとすると、エラーメッセージが表示されますか? – Hans

+0

です。 「ファイルには問題があるのでファイル[filename]を開くことができません」というメッセージが表示されます。私は検査官の中身を見ていますが、実際に間違っていることに関しては何も明白ではありません。 – JasCav

答えて

16

私はエラーを再現することができます別の形式のインポート一部のコンテンツとして 不完全なHTMLドキュメントを使用して「...内容に問題があります」。 たとえば、次のHTMLスニペットを使用する場合<h1>HELLO</h1> MS Wordで文書を開くことができません。

以下のコードは、単語文書にAlternativeFormatImportPartを追加する方法を示しています。 (私はMS Word 2013でコードをテストしました)。

using (WordprocessingDocument doc = WordprocessingDocument.Open(@"test.docx", true)) 
{ 
    string altChunkId = "myId"; 
    MainDocumentPart mainDocPart = doc.MainDocumentPart; 

    var run = new Run(new Text("test")); 
    var p = new Paragraph(new ParagraphProperties(
     new Justification() { Val = JustificationValues.Center }), 
        run); 

    var body = mainDocPart.Document.Body; 
    body.Append(p);   

    MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("<html><head></head><body><h1>HELLO</h1></body></html>")); 

    // Uncomment the following line to create an invalid word document. 
    // MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("<h1>HELLO</h1>")); 

    // Create alternative format import part. 
    AlternativeFormatImportPart formatImportPart = 
    mainDocPart.AddAlternativeFormatImportPart(
     AlternativeFormatImportPartType.Html, altChunkId); 
    //ms.Seek(0, SeekOrigin.Begin); 

    // Feed HTML data into format import part (chunk). 
    formatImportPart.FeedData(ms); 
    AltChunk altChunk = new AltChunk(); 
    altChunk.Id = altChunkId; 

    mainDocPart.Document.Body.Append(altChunk); 
} 

w:altChunk要素のために、Office OpenXMLの仕様有効な親要素によるbody, comment, docPartBody, endnote, footnote, ftr, hdr and tcです。 したがって、w:altChunkをbody要素に追加しました。

w:altChunk要素の詳細については、MSDNリンクを参照してください。

EDIT

としては、あなたがUTF-8プリアンブルを追加する必要がありますのOpenXMLライブラリcorrectltyがUTF-8としてバイト配列を解釈することを確認するために、@ user2945722によって指摘しました。これは、この方法を行うことができます。

MemoryStream ms = new MemoryStream(new UTF8Encoding(true).GetPreamble().Concat(Encoding.UTF8.GetBytes(htmlEncodedString)).ToArray() 

これはäのようéさん、お使いのAさんとしてレンダリングされているからあなたのEのを防ぐことができます、など

+0

"...不完全なHTML文書を使用しています..." - それはまさに問題の原因です。そんな単純なことですが、私にはまだ分かりません。ご協力いただきありがとうございます。 – JasCav

+3

memorystreamに渡す前に、UTF8 BOMをバイト配列に追加することを検討する必要があります。これは、docxファイルが正しくいくつかのUTF8文字を表示しない私のシナリオを助けた。何かこのように - 'byte [] utf8Bom = new UTF8Encoding(true).GetPreamble();'それを "GetBytes"の結果の前に付加します。 – user2945722

+0

@ user2945722ありがとう!これは私の問題の正解でした。答えに含める必要があります。 –

1

がここに同じ問題を抱えていたが、まったく異なる原因。受け入れられた解決策が役に立たない場合は試してみる価値があります。保存後にファイルを閉じてみてください。私の場合は、破損したファイルとクリーンなdocxファイルの違いになりました。奇妙なことに、他のほとんどの操作はSave()とプログラム終了のみで動作します。

String cid = "chunkid"; 
WordprocessingDocument document = WordprocessingDocument.Open("somefile.docx", true); 
Body body = document.MainDocumentPart.Document.Body; 
MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes("<html><head></head><body>hi</body></html>")); 
AlternativeFormatImportPart formatImportPart = document.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Html, cid); 
formatImportPart.FeedData(ms); 
AltChunk altChunk = new AltChunk(); 
altChunk.Id = cid; 
document.MainDocumentPart.Document.Body.Append(altChunk); 
document.MainDocumentPart.Document.Save(); 
// here's the magic! 
document.Close(); 
+0

私はMemoryStream(WordprocessingDocument.Openの代わりにWordprocessingDocument.Createを使用)に書き込もうとしていましたが、document.Close()の "magic"はきれいなメモリストリームを返すために必要なものでした。 usingステートメント内から戻ります(またはusingステートメントを使用しませんでした)。 usingステートメントの外側に戻ると、この魔法は必要ありませんでした。私は、オブジェクトを処分するときに、usingステートメントがdocument.Close()と同じタスクを効果的に実行することを疑う。 –

関連する問題