2017-01-24 1 views
0

나는 아파치 포이 (poi poi)를 사용하여 HTML 문서로 변환하는 ms 워드 문서 파일을 가지고있다. 아파치 poi 변환기의 인코딩 문제

내가

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

코드는 잘 작동을하고 있는데 코드, 그것은 이미지와 스타일을 유지합니다. 그러나 html의 일부 문자에 문제가있는 것 같습니다. 제대로 인코딩되지 않았습니다. 예를 들어 원본 .doc 파일의 일부 글 머리 스타일이 올바르게 출력되지 않습니다. 나는 여러 글자 세트 (ASCII, UTF-8, gbk ...)를 시도했는데 모두 글 머리 점을 올바르게 생성하지 못했다.

인코딩 때문에 총알이 횡설수설하고 있다고 확신합니다 (%). 누구든지 아파치로 이런 문제를 보았습니까?

답변

1

이것은 인코딩 문제가 아니라 글꼴 문제입니다. WordANSI 코드와 특수 글꼴을 기본 글 머리 기호 목록으로 사용합니다. 예를 들어 첫 번째 글 머리 기호는 "Symbol"글꼴의 글 머리 기호입니다. 두 번째 글 머리 기호는 "Courier New"글꼴의 원이고 세 번째 글 머리 기호는 글꼴 "Wingdings"의 사각형입니다.

그래서 가장 쉬운 방법은 총알 텍스트의 ANSI 코드를 유니 코드로 바꾸는 것입니다. 이렇게하면 HTML에 UTF-8을 사용할 수 있습니다.

예 :

말씀 WordBulletList.doc :

enter image description here

자바 :

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

나는이 접근법을 시도해 보았다. 이전과 같이 최종 HTML 페이지에서 동일한 결함이있는 결과를 얻었다. – Acidburn73

+0

그런 다음 Word에서 다른 글 머리 기호를 사용하고 있습니다. '//System.out.println((int)bulletText.charAt(0));'의 주석을 제거하고 어떤 문자 코드가 사용되었는지 살펴보고 그것을 16 진수로 변환하고 "\ u ...."문자를 대체하십시오. . –

0

문제가 해결되었습니다.

마지막으로이 특정 문제를 해결할 수있는 방법을 발견했습니다. 대답은 내가 한 모든 지금 내 웹 페이지가 제대로 표시됩니다

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

내 HTML 문자열

에 URLEncoder/디코더를 사용했다, 자신의 질문 Encoding issue with Apache POI

해결책은 간단하다와 함께 @ pawelini1에 의해 영감을했다.