2017-01-24 3 views
0

Ich habe eine ms Word-Dokument-Datei, die ich in ein HTML-Dokument mit Apache poi konvertieren.Codierung Problem mit Apache Poi-Konverter

dies ist der Code ich bin

InputStream input = new FileInputStream (path); 
    HWPFDocument wordDocument = new HWPFDocument (input);    
    WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter (DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); 

    List<Picture> pics = wordDocument.getPicturesTable().getAllPictures(); 
    if (pics != null) 
    { 
     for (int i = 0; i <pics.size(); i++) 
     { 
      Picture pic = (Picture) pics.get (i); 
      try 
      { 
       pic.writeImageContent (new FileOutputStream (path + pic.hashCode() + '.' + pic.suggestFileExtension())); 
      } 
      catch (FileNotFoundException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 

    wordToHtmlConverter.setPicturesManager (new PicturesManager() 
    {    
     public String savePicture (byte[] content, PictureType pictureType, String suggestedName, float widthInches, float heightInches) 
     { 
      for(Picture picName:pics) 
      { 
       return Integer.toString(picName.hashCode()) + '.' + picName.suggestFileExtension(); 
      } 

      return null; 
     } 
    }); 

    wordToHtmlConverter.processDocument(wordDocument);      
    Document htmlDocument = wordToHtmlConverter.getDocument();       
    ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 
    DOMSource domSource = new DOMSource(htmlDocument); 
    StreamResult streamResult = new StreamResult (outStream); 

    TransformerFactory tf = TransformerFactory.newInstance(); 
    Transformer serializer = tf.newTransformer(); 
    serializer.setOutputProperty (OutputKeys.ENCODING, "gbk"); 
    serializer.setOutputProperty (OutputKeys.INDENT, "yes"); 
    serializer.setOutputProperty (OutputKeys.METHOD, "html"); 
    serializer.transform (domSource, streamResult); 
    outStream.close(); 

    String html = new String (outStream.toByteArray()); 

Der Code funktioniert gut läuft, dann ist es Bilder und Stile zu erhalten. Es scheint jedoch ein Problem mit einigen Zeichen im HTML zu geben, das nicht richtig kodiert. Beispielsweise werden einige Aufzählungsstile in der ursprünglichen DOC-Datei nicht korrekt ausgegeben. Ich habe mehrere Zeichensätze ausprobiert (ASCII, UTF-8, Gbk ...), alle erzeugen die Aufzählungspunkte nicht korrekt.

Ich bin% 99 Prozent sicher, dass die Kugeln wegen der Kodierung Kauderwelsch zeigen. Ist jemand mit Apache auf ein solches Problem gestoßen?

Antwort

1

Dies ist kein Codierungsproblem, sondern ein Fontproblem. Word verwendet ANSI Code und spezielle Schriftarten für die Standard-Aufzählungszeichen. Der erste Punkt ist zum Beispiel eine Kugel aus der Schrift "Symbol". Der zweite Aufzählungspunkt ist ein Kreis aus der Schriftart "Courier New". Der dritte Aufzählungspunkt ist ein Quadrat aus der Schriftart "Wingdings".

Also die einfachste Möglichkeit wird einfach sein, die ANSI Codes der Aufzählungstexte durch Unicode zu ersetzen. So können wir UTF-8 für das HTML verwenden.

Beispiel:

Wort WordBulletList.doc:

enter image description here

Java:

import java.io.StringWriter; 
import java.io.FileInputStream; 
import java.io.File; 
import java.io.PrintWriter; 

import javax.xml.transform.OutputKeys; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 

import javax.xml.parsers.DocumentBuilderFactory; 

import org.apache.poi.hwpf.HWPFDocument; 
import org.apache.poi.hwpf.HWPFDocumentCore; 
import org.apache.poi.hwpf.usermodel.Paragraph; 
import org.apache.poi.hwpf.converter.WordToHtmlConverter; 
import org.apache.poi.hwpf.converter.FontReplacer; 
import org.apache.poi.hwpf.converter.FontReplacer.Triplet; 

import org.w3c.dom.Document; 

import java.awt.Desktop; 

public class TestWordToHtmlConverter { 

public static void main(String[] args) throws Exception { 

    Document newDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); 

    WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(newDocument) { 

    protected void processParagraph(HWPFDocumentCore hwpfDocument, 
            org.w3c.dom.Element parentElement, 
            int currentTableLevel, 
            Paragraph paragraph, 
            java.lang.String bulletText) { 
    if (bulletText!="") { 
    //System.out.println((int)bulletText.charAt(0)); 
    bulletText = bulletText.replace("\uF0B7", "\u2022"); 
    bulletText = bulletText.replace("\u006F", "\u00A0\u00A0\u26AA"); 
    bulletText = bulletText.replace("\uF0A7", "\u00A0\u00A0\u00A0\u00A0\u25AA"); 
    } 

    super.processParagraph(hwpfDocument, parentElement, currentTableLevel, paragraph, bulletText); 
    } 

    }; 

    wordToHtmlConverter.processDocument(new HWPFDocument(new FileInputStream("WordBulletList.doc"))); 

    StringWriter stringWriter = new StringWriter(); 
    Transformer transformer = TransformerFactory.newInstance().newTransformer(); 
    transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
    transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8"); 
    transformer.setOutputProperty(OutputKeys.METHOD, "html"); 
    transformer.transform(new DOMSource(wordToHtmlConverter.getDocument()), new StreamResult(stringWriter)); 

    String html = stringWriter.toString(); 

    try(PrintWriter out = new PrintWriter("WordBulletList.html")) { 
    out.println(html); 
    } 

    File htmlFile = new File("WordBulletList.html"); 
    Desktop.getDesktop().browse(htmlFile.toURI()); 

} 
} 

HTML:

... 
<body class="b1 b2"> 
<p class="p1"> 
<span>Word bullet list:</span> 
</p> 
<p class="p2"> 
<span class="s1">&bull;​&nbsp;</span><span>Bullet1</span> 
</p> 
<p class="p2"> 
<span class="s1">&nbsp;&nbsp;⚪​&nbsp;</span><span>Bullet2</span> 
</p> 
<p class="p2"> 
<span class="s1">&nbsp;&nbsp;&nbsp;&nbsp;▪​&nbsp;</span><span>Bullet3</span> 
</p> 
<p class="p2"> 
<span class="s1">&nbsp;&nbsp;⚪​&nbsp;</span><span>Bullet2</span> 
</p> 
<p class="p2"> 
<span class="s1">&bull;​&nbsp;</span><span>Bullet1</span> 
</p> 
<p class="p1"> 
<span>End</span> 
</p> 
</body> 
... 
+0

Ich habe diesen Ansatz versucht, ich habe die gleichen fehlerhaften Ergebnisse auf meiner endgültigen HTML-Seite wie zuvor. – Acidburn73

+0

Dann verwenden Sie andere Aufzählungszeichen in Word. Bitte kommentieren Sie '//System.out.println((int)bulletText.charAt(0));' und schauen Sie, welcher Zeichencode verwendet wird, konvertieren Sie ihn in hex und ersetzen Sie dann das Zeichen "\ u ...." . –

0

Problem gelöst

Ich habe endlich einen Weg gefunden, dieses spezielle Problem zu lösen. Die Antwort wurde inspiriert von @ pawelini1 mit seiner eigenen Frage Encoding issue with Apache POI

Die Lösung ist einfach, alles, was ich war einen URLEncoder/Decoder auf meinem HTML-String

String html = URLEncoder.encode(new String(outStream.toByteArray(), "UTF-8"), "UTF-8"); 
String decoded = URLDecoder.decode(html, "UTF-8"); 

nun wie meine Webseite angezeigt wird benutzt haben.