Dodaj łańcuch HTML do OpenXML (*.docx) dokument

Próbuję użyć biblioteki OpenXML 2.5 Microsoftu do utworzenia dokumentu OpenXML. Wszystko działa świetnie, dopóki nie spróbuję wstawić ciągu HTML do mojego dokumentu. Przeczesałem Sieć i oto co do tej pory wymyśliłem (fragment do tej części, z którą mam problem):

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

Oczywiście, nie dodałem altchunka w tym przykładzie, ale próbowałem go dodawać wszędzie - do biegu, akapitu, ciała itp. W każdym razie, nie jestem w stanie otworzyć docx plik w Wordzie 2010.

To sprawia, że jestem trochę szalony, ponieważ wydaje się, że powinno to być proste (przyznam, że nie do końca rozumiem AltChunk "rzecz"). Będę wdzięczny za każdą pomoc.

Uwaga na marginesie: jedną z rzeczy, które uznałem za interesujące i nie wiem, czy to rzeczywiście problem, jest ta odpowiedź , która mówi, że AltChunk psuje plik podczas pracy z MemoryStream. Czy ktoś może potwierdzić, że to prawda?

Author: Community, 2013-08-07

2 answers

Mogę odtworzyć błąd "... występuje problem z treścią " poprzez użycie niekompletny dokument HTML jako zawartość alternatywnej części importu formatu. Na przykład, jeśli używasz następującego fragmentu HTML <h1>HELLO</h1> MS Word nie może otworzyć dokumentu.

Poniższy kod pokazuje, jak dodać AlternativeFormatImportPart do dokumentu programu word. (Testowałem kod z 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);
}

Zgodnie ze specyfikacją Office OpenXML ważne elementy nadrzędne dla w:altChunk element are body, comment, docPartBody, endnote, footnote, ftr, hdr and tc. Dodałem w:altChunk do elementu ciała.

Aby uzyskać więcej informacji na temat elementu w:altChunk Zobacz ten link MSDN.

EDIT

Jak zauważył @user2945722, aby upewnić się, że biblioteka OpenXML correctlty interpretuje tablicę bajtów jako UTF-8, należy dodać preambułę UTF-8. Można to zrobić w ten sposób:

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

Zapobiegnie to renderowaniu Twoich é jako à © 's, Twoich ä jako ã¤'s itp.

 17
Author: Hans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-11 15:42:45

Miałem ten sam problem, ale zupełnie inną przyczynę. Warto spróbować, jeśli przyjęte rozwiązanie nie pomoże. Spróbuj zamknąć plik po zapisaniu. W moim przypadku zdarzyła się różnica między uszkodzonym a czystym plikiem docx. Co dziwne, większość innych operacji działa tylko z save () i zakończeniem programu.

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();
 1
Author: pragmar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-15 22:11:16