MicrosoftのOpenXML 2.5ライブラリを使用してOpenXMLドキュメントを作成しようとしています。ドキュメントに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を追加していませんが、ラン、段落、本文など、どこにでも追加しようとしました。Word2010でdocxファイルを開くことができません。
単純明快なように見えるので、これは少し気が抜けています(AltChunkの「もの」を完全に理解していないことは認めます)。どんな助けにも感謝します。
補足:興味深いことに、実際に問題であるかどうかはわかりませんが、 この応答 は、MemoryStreamから作業しているときにAltChunkがファイルを破損することを示しています。誰かがこれが正しいかどうかを確認できますか?
エラーを再現できます "...内容に問題があります"不完全なHTMLドキュメントを代替形式のインポート部分のコンテンツとして使用することで。たとえば、次のHTMLスニペット<h1>HELLO</h1>
を使用すると、MS Wordはドキュメントを開くことができません。
以下のコードは、AlternativeFormatImportPart
をWord文書に追加する方法を示しています。 (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);
}
Office OpenXML仕様によると、w:altChunk
要素の有効な親要素はbody, comment, docPartBody, endnote, footnote, ftr, hdr and tc
です。そこで、w:altChunk
をbody要素に追加しました。
w:altChunk
要素の詳細については、この [〜#〜] msdn [〜#〜] リンクを参照してください。
[〜#〜]編集[〜#〜]
@ user2945722で指摘されているように、OpenXmlライブラリがバイト配列をUTF-8として正しく解釈できるようにするには、UTF-8プリアンブルを追加する必要があります。これは次の方法で行うことができます:
MemoryStream ms = new MemoryStream(new UTF8Encoding(true).GetPreamble().Concat(Encoding.UTF8.GetBytes(htmlEncodedString)).ToArray()
これにより、éがéとして、äがäとしてレンダリングされるのを防ぐことができます。
ここでは同じ問題がありましたが、原因はまったく異なります。受け入れられた解決策が役に立たないなら、試してみる価値があります。保存後にファイルを閉じてみてください。私の場合、それはたまたま破損したdocxファイルとクリーンな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();