2017-10-06 5 views
0

Ich möchte fragen, wie kann ich Kopf-/Fußzeile Teil von MS Word-Dokument (doc/docx) in HTML konvertieren. Ich öffne das Dokument wie:Exportieren docx/doc Erste Kopfzeile und Fußzeile als docx Datei Mit openXML

using (WordprocessingDocument wDoc = WordprocessingDocument.Open(memoryStream, true)) 

aka OpenXML

ich das Dokument mit WmlToHtmlConverter Umwandlung, die das Dokument ausgezeichnet außer umwandelt, dass die Kopf- und Fußzeilen sind skipt, Cuz html standart doesnt Unterstützung Paginierung . Ich habe mich gefragt, wie ich sie bekommen und als HTML extrahieren kann. Ich versuche, indem man sich wie immer:

using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(mainFileMemoryStream, true)) 
{ 
    Document mainPart = wdDoc.MainDocumentPart.Document; 
    DocumentFormat.OpenXml.Packaging.HeaderPart firstHeader = 
      wdDoc.MainDocumentPart.HeaderParts.FirstOrDefault(); 

    if (firstHeader != null) 
    { 
     using (var headerStream = firstHeader.GetStream()) 
     { 
      return headerStream.ReadFully(); 
     } 
    } 
    return null; 
} 

und dann an die Funktion Convertion vorbei, aber ich Ausnahme erhalten, die sagt:

Datei enthält beschädigte Daten, mit Stack-Trace:

at System.IO.Packaging.ZipPackage..ctor(Stream s, FileMode packageFileMode, FileAccess packageFileAccess) 
at System.IO.Packaging.Package.Open(Stream stream, FileMode packageMode, FileAccess packageAccess) 
at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.OpenCore(Stream stream, Boolean readWriteMode) 
at DocumentFormat.OpenXml.Packaging.WordprocessingDocument.Open(Stream stream, Boolean isEditable, OpenSettings openSettings) 
at DocumentFormat.OpenXml.Packaging.WordprocessingDocument.Open(Stream stream, Boolean isEditable) 
at DocxToHTML.Converter.HTMLConverter.ParseDOCX(Byte[] fileInfo, String fileName) in D:\eTemida\eTemida.Web\DocxToHTML.Converter\HTMLConverter.cs:line 96 

Jede mögliche Hilfe

+0

Hallo, Es gibt keine direkte Methode, um Header und Fußzeile als HTML (dh, in OpenXML Powertools) in OpenXML zu erhalten, anstatt dass Sie Kopf- und Fußzeileninhalt als Text lesen müssen, dann müssen Sie dafür Stil anwenden Überschrift. Bitte beachten Sie: https: // github.com/OfficeDev/Open-Xml-PowerTools/issues/66 # issuecomment-326629828 –

Antwort

0

viel Kampf führte mich zu folgender Lösung geschätzt werden:

habe ich eine Funktion zum Umwandeln von docx-Dokument in HTML-Byte-Array als

Folgt
public string ConvertToHtml(byte[] fileInfo, string fileName = "Default.docx") 
    { 
     if (string.IsNullOrEmpty(fileName) || Path.GetExtension(fileName) != ".docx") 
      return "Unsupported format"; 

     //FileInfo fileInfo = new FileInfo(fullFilePath); 

     string htmlText = string.Empty; 
     try 
     { 
      htmlText = ParseDOCX(fileInfo, fileName); 
     } 
     catch (OpenXmlPackageException e) 
     { 

      if (e.ToString().Contains("Invalid Hyperlink")) 
      { 
       using (MemoryStream fs = new MemoryStream(fileInfo)) 
       { 
        UriFixer.FixInvalidUri(fs, brokenUri => FixUri(brokenUri)); 
       } 
       htmlText = ParseDOCX(fileInfo, fileName); 
      } 
     } 
     return htmlText; 
    } 

Wo die ParseDOCX macht die ganze convertion. Der Code von ParseDOCX:

private string ParseDOCX(byte[] fileInfo, string fileName) 
    { 
     try 
     { 
      //byte[] byteArray = File.ReadAllBytes(fileInfo.FullName); 
      using (MemoryStream memoryStream = new MemoryStream()) 
      { 
       memoryStream.Write(fileInfo, 0, fileInfo.Length); 

       using (WordprocessingDocument wDoc = WordprocessingDocument.Open(memoryStream, true)) 
       { 

        int imageCounter = 0; 

        var pageTitle = fileName; 
        var part = wDoc.CoreFilePropertiesPart; 
        if (part != null) 
         pageTitle = (string)part.GetXDocument().Descendants(DC.title).FirstOrDefault() ?? fileName; 

        WmlToHtmlConverterSettings settings = new WmlToHtmlConverterSettings() 
        { 
         AdditionalCss = "body { margin: 1cm auto; max-width: 20cm; padding: 0; }", 
         PageTitle = pageTitle, 
         FabricateCssClasses = true, 
         CssClassPrefix = "pt-", 
         RestrictToSupportedLanguages = false, 
         RestrictToSupportedNumberingFormats = false, 
         ImageHandler = imageInfo => 
         { 
          ++imageCounter; 
          string extension = imageInfo.ContentType.Split('/')[1].ToLower(); 
          ImageFormat imageFormat = null; 
          if (extension == "png") imageFormat = ImageFormat.Png; 
          else if (extension == "gif") imageFormat = ImageFormat.Gif; 
          else if (extension == "bmp") imageFormat = ImageFormat.Bmp; 
          else if (extension == "jpeg") imageFormat = ImageFormat.Jpeg; 
          else if (extension == "tiff") 
          { 
           extension = "gif"; 
           imageFormat = ImageFormat.Gif; 
          } 
          else if (extension == "x-wmf") 
          { 
           extension = "wmf"; 
           imageFormat = ImageFormat.Wmf; 
          } 

          if (imageFormat == null) 
           return null; 

          string base64 = null; 
          try 
          { 
           using (MemoryStream ms = new MemoryStream()) 
           { 
            imageInfo.Bitmap.Save(ms, imageFormat); 
            var ba = ms.ToArray(); 
            base64 = System.Convert.ToBase64String(ba); 
           } 
          } 
          catch (System.Runtime.InteropServices.ExternalException) 
          { return null; } 


          ImageFormat format = imageInfo.Bitmap.RawFormat; 
          ImageCodecInfo codec = ImageCodecInfo.GetImageDecoders().First(c => c.FormatID == format.Guid); 
          string mimeType = codec.MimeType; 

          string imageSource = string.Format("data:{0};base64,{1}", mimeType, base64); 

          XElement img = new XElement(Xhtml.img, 
           new XAttribute(NoNamespace.src, imageSource), 
           imageInfo.ImgStyleAttribute, 
           imageInfo.AltText != null ? 
            new XAttribute(NoNamespace.alt, imageInfo.AltText) : null); 
          return img; 
         } 

        }; 
        XElement htmlElement = WmlToHtmlConverter.ConvertToHtml(wDoc, settings); 

        var html = new XDocument(new XDocumentType("html", null, null, null), htmlElement); 
        var htmlString = html.ToString(SaveOptions.DisableFormatting); 
        return htmlString; 
       } 
      } 
     } 
     catch (Exception) 
     { 
      return "File contains corrupt data"; 
     } 
    } 

Bisher sah alles schön und einfach, aber dann wurde mir klar, dass der Header und die Fußzeile des Dokuments nur skipt ist, so musste ich sie irgendwie konvertieren. Ich habe versucht, die GetStream() Methode von HeaderPart zu verwenden, aber natürlich Ausnahme war werfen, denn der Header-Struktur ist nicht das gleiche wie das des Dokuments.

Dann habe ich beschlossen, die Kopfzeile und Fußzeile als neue Dokumente (mit Schwierigkeiten damit) mit OpenXML WordprocessingDocument headerDoc = WordprocessingDocument.Create(headerStream,Document) zu extrahieren, aber unglücklicherweise war die Konvertierung dieses Dokuments auch nicht erfolgreich, da Sie nur ein einfaches docx Dokument erstellen ohne irgendwelche Einstellungen, Stile, WebSettings etc. Das nahm viel Zeit in Anspruch.

So endlich habe ich beschlossen, ein neues Dokument über Cathal DocX-Bibliothek zu erstellen und es kam endlich zum Leben. Der Code lautet wie folgt:

public string ConvertHeaderToHtml(HeaderPart header) 
    { 

     using (MemoryStream headerStream = new MemoryStream()) 
     { 
      //Cathal's Docx Create 
      var newDocument = Novacode.DocX.Create(headerStream); 
      newDocument.Save(); 

      using (WordprocessingDocument headerDoc = WordprocessingDocument.Open(headerStream,true)) 
      { 
       var headerParagraphs = new List<OpenXmlElement>(header.Header.Elements()); 
       var mainPart = headerDoc.MainDocumentPart; 

       //Cloning the List is necesery because it will throw exception for the reason 
       // that you are working with refferences of the Elements 
       mainPart.Document.Body.Append(headerParagraphs.Select(h => (OpenXmlElement)h.Clone()).ToList()); 

       //Copies the Header RelationShips as Document's 
       foreach (IdPartPair parts in header.Parts) 
       { 
        //Very important second parameter of AddPart, if not set the relationship ID is being changed 
        // and the wordDocument pictures, etc. wont show 
        mainPart.AddPart(parts.OpenXmlPart,parts.RelationshipId); 
       } 
       headerDoc.MainDocumentPart.Document.Save(); 
       headerDoc.Save(); 
       headerDoc.Close(); 
      } 
      return ConvertToHtml(headerStream.ToArray()); 
     } 
    } 

Das war also mit dem Header. Ich übergebe den HeaderPart und bekomme seinen Header dann Elemente. Extrahieren der Beziehungen, was sehr wichtig ist, wenn Sie Bilder in der Kopfzeile haben, und importieren Sie sie in das Dokument selbst Und das Dokument ist bereit für die Konvertierung.

Die gleichen Schritte werden verwendet, um die HTML aus der Fußzeile zu generieren.

Hoffnung Dies wird einigen in seiner Pflicht helfen.

+0

Ich habe den Code zum Erstellen von Word-Dokument aus 3 HTML-Strings (HtmlBody, HtmlHeader, HtmlFooter). Es gibt auch ein paar Eckpfeiler, bei Bedarf werde ich mich bemühen, es hochzuladen. –

Verwandte Themen