2013-08-06 20 views
16

Bir OpenXML belgesi oluşturmak için Microsoft'un OpenXML 2.5 kitaplığını kullanmaya çalışıyorum. Her şey harika çalışıyor, belgeye bir HTML dizesi eklemeye çalışana kadar. ,OpenXML'e HTML Dizesi Ekle (* .docx) Belge

Açıkçası
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); 

, ben aslında bu örnekte altChunk eklememiş: Ben web dolaştılar ve burada şimdiye kadar (sadece kısmına ben sorun yaşıyorum için snipped) ile gelip ne olduğunu var ama ben her yerde eklemeye çalıştım - koşmak, paragraf, vücut, vb. Her durumda, Word 2010'da docx dosyasını açamıyorum.

Bu bana biraz nutty yapıyor çünkü bu sanki Basit olmalı (AltChunk "şey" i tam olarak anlamadığımı itiraf etmeliyim). Herhangi bir yardım için minnettarım.

Yan Not: Bu bir şey ilginç olduğunu buldum ve aslında bir sorun olup olmadığını bilmiyorum, AltChunk bir MemoryStream çalışırken dosya bozan diyor this response olduğunu. Bunun doğru olduğunu kimse doğrulayabilir mi?

+0

Oluşturulan docx dosyasını Word 2010'da açmaya çalıştığınızda bir hata iletisi alıyor musunuz? – Hans

+0

Yaparım. "Dosya [dosyaadı] açılamıyor, çünkü içeriğiyle ilgili sorunlar var." Müfettişteki içeriğe bakıyorum ama aslında neyin yanlış olduğuna dair net bir şey göremiyorum. – JasCav

cevap

16

hatası üretebilir alternatif biçim ithalat kısmının içeriği olarak tamamlanmamış bir HTML belgesi kullanarak "... içeriğiyle ilgili bir sorun var." Örneğin, aşağıdaki HTML snippet'ini kullanırsanız <h1>HELLO</h1> MS Word belgeyi açamıyor.

Aşağıdaki kod, bir Word belgesine bir AlternativeFormatImportPart eklemeyi gösterir. (Bu kodu MS Word 2013 ile test ettim). w:altChunk elemanı için Office açık XML şartname geçerli bir üst elemanlarına göre

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); 
} 

body, comment, docPartBody, endnote, footnote, ftr, hdr and tc bulunmaktadır. Yani, gövde öğesine w:altChunk ekledim.

w:altChunk öğesi hakkında daha fazla bilgi için bu MSDN bağlantıya bakın.

DÜZENLEME

olarak, UTF-8 önsöz eklemek gerekir OPENXML kütüphane correctlty UTF-8 olarak bayt dizisi yorumladığı emin olmak için, @ user2945722 tarafından işaret etti. Bu, bu şekilde yapılabilir:

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

Bu ¤ en olarak à © 'ın, senin ä yıllardan olarak görüntülerini adresinin E'nin önleyecektir vb

+0

"... tamamlanmamış bir HTML belgesini kullanarak ..." - Tam olarak sorunun ne olduğunu. Böyle basit bir şey, henüz bana çok açık olmayan bir şey. Yardım ettiğin için teşekkür ederim. – JasCav

+3

UTF8 BOM'unu bayt dizisine, memorystream'e iletmeden önce eklemeyi düşünmelisiniz. Bu, docx dosyasının bazı UTF8 karakterlerini doğru göstermediği senaryona yardımcı oldu. Bunun gibi bir şey - 'byte [] utf8Bom = yeni UTF8Encoding (true) .GetPreamble();' ve daha sonra "GetBytes" sonucuna hazırla – user2945722

+0

@ user2945722 Teşekkürler! Bu benim sorunum için doğru cevaptı. Cevaplara dahil edilmelidir. –

1

burada aynı problem vardı, ama bir tamamen farklı sebep. Kabul edilen çözüm yardımcı olmazsa denemeye değer. Kaydedildikten sonra dosyayı kapatmayı deneyin. Benim durumumda, bozuk ve temiz bir docx dosyası arasındaki fark oldu. Garip bir şekilde, diğer birçok işlem sadece bir Save() ve program çıkışı ile çalışır.

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

Bir MemoryStream'e (WordprocessingDocument.Open yerine WordprocessingDocument.Create kullanarak) ve belgenin "sihirbazını" yazmaya çalışıyorum.Close() tam olarak temiz bir bellek akışı elde etmek için gerekli olan şeydi * IF * Denedim kullanım ifadesinden dönün (veya bir kullanma ifadesi kullanmadı). Kullanım ifadesinin dışında geri dönmek bu sihri gerektirmedi. Kullanım ifadesinin, nesneyi elden çıkarırken document.Close() işleviyle aynı görevi gerçekleştirdiğinden şüpheleniyorum. –