2015-01-28 2 views
0

Я внедрил XHTML-конвертер в DocX с помощью DocX4J. Он создает файл DocX без проблем.Невозможно подсчитать количество символов в файле docx, сгенерированном из незаполненного XHTML

Для завершения моей задачи я решил реализовать простой тест. Тест состоит в подсчете числа символов os в создаваемом DocX и затем сравнении его с уже известным количеством символов из XHTML (см. Исходный код ниже).

Код моего теста основан на образце с сайта DocX4J, но не работает для меня. Хотя я вижу, что содержимое DocX, созданного моим конвертером, равно содержимому файла XHTML, мой тестовый код всегда возвращает ноль к числу символов файла DocX. : - \

Кто-нибудь может помочь мне обнаружить причину этого неожиданного результата?

Заранее благодарен!

package main; 
 

 
import java.io.File; 
 
import java.io.IOException; 
 
import java.io.StringWriter; 
 

 
import org.docx4j.TextUtils; 
 
import org.docx4j.jaxb.Context; 
 
import org.docx4j.openpackaging.contenttype.ContentType; 
 
import org.docx4j.openpackaging.exceptions.Docx4JException; 
 
import org.docx4j.openpackaging.exceptions.InvalidFormatException; 
 
import org.docx4j.openpackaging.packages.WordprocessingMLPackage; 
 
import org.docx4j.openpackaging.parts.PartName; 
 
import org.docx4j.openpackaging.parts.WordprocessingML.AlternativeFormatInputPart; 
 
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; 
 
import org.docx4j.relationships.Relationship; 
 
import org.docx4j.wml.CTAltChunk; 
 
import org.docx4j.wml.Document; 
 

 
/** 
 
* Count chars from a DocX file generated from a XHTML using Docx4J 
 
* 
 
* @author Cláudio 
 
*/ 
 
public class CountChars { 
 

 
    public static void main(String[] args) { 
 
\t String xhtml = "<html><body><table border=\"1\"><tr><td>Propriedade</td><td>Amostra 1</td><td>Amostra 2</td></tr><tr><td>Prop1</td><td>10.0</td><td>111.0</td></tr><tr><td>Prop2</td><td>20.0</td><td>222.0</td></tr></table></body></html>"; 
 
\t int expectedNChars = 57; 
 

 
\t WordprocessingMLPackage docx = export(xhtml); 
 
\t try { 
 
\t  docx.save(new File("test.docx")); // Proves that docx is 
 
\t \t        // successfully created 
 
\t } catch (Docx4JException e) { 
 
\t  // TODO Auto-generated catch block 
 
\t  e.printStackTrace(); 
 
\t } 
 

 
\t if (countCharacters(docx) == expectedNChars) { 
 
\t  System.out.println("Success"); 
 
\t } else { 
 
\t  System.out.println("Fail"); 
 
\t } 
 
    } 
 

 
    private static WordprocessingMLPackage export(String xhtml) { 
 
\t WordprocessingMLPackage wordMLPackage = null; 
 
\t AlternativeFormatInputPart afiPart = null; 
 
\t Relationship altChunkRel = null; 
 

 
\t try { 
 
\t  wordMLPackage = WordprocessingMLPackage.createPackage(); 
 
\t  afiPart = new AlternativeFormatInputPart(new PartName("/hw.html")); 
 
\t } catch (InvalidFormatException e) { 
 
\t  // TODO Auto-generated catch block 
 
\t  e.printStackTrace(); 
 
\t } 
 

 
\t afiPart.setBinaryData(xhtml.getBytes()); 
 
\t afiPart.setContentType(new ContentType("text/html")); 
 

 
\t try { 
 
\t  altChunkRel = wordMLPackage.getMainDocumentPart().addTargetPart(
 
\t \t  afiPart); 
 
\t } catch (InvalidFormatException e) { 
 
\t  // TODO Auto-generated catch block 
 
\t  e.printStackTrace(); 
 
\t } 
 

 
\t // .. the bit in document body 
 
\t CTAltChunk ac = Context.getWmlObjectFactory().createCTAltChunk(); 
 
\t ac.setId(altChunkRel.getId()); 
 
\t wordMLPackage.getMainDocumentPart().addObject(ac); 
 

 
\t // .. content type 
 
\t wordMLPackage.getContentTypeManager().addDefaultContentType("html", 
 
\t   "text/html"); 
 

 
\t return wordMLPackage; 
 
    } 
 

 
    /** 
 
    * Counts chars (even whitespaces) in a docx. 
 
    * 
 
    * Referência: 
 
    * http://www.docx4java.org/forums/docx-java-f6/how-to-count-number 
 
    * -of-characters-in-a-docx-file-t767.html 
 
    * 
 
    * @param docx 
 
    *   Document 
 
    * 
 
    * @return Number of chars in the document 
 
    */ 
 
    private static int countCharacters(WordprocessingMLPackage docx) { 
 
\t String strString = null; 
 

 
\t MainDocumentPart documentPart = docx.getMainDocumentPart(); 
 
\t Document wmlDocument = documentPart.getJaxbElement(); 
 

 
\t StringWriter strWriter = null; 
 
\t try { 
 
\t  strWriter = new StringWriter(); 
 
\t  TextUtils.extractText(wmlDocument, strWriter); 
 
\t  strString = strWriter.toString(); 
 
\t } catch (Exception e) { 
 
\t  // TODO Auto-generated catch block 
 
\t  e.printStackTrace(); 
 
\t } finally { 
 
\t  if (strWriter != null) { 
 
\t \t try { 
 
\t \t  strWriter.close(); 
 
\t \t } catch (IOException e) { 
 
\t \t  // TODO Auto-generated catch block 
 
\t \t  e.printStackTrace(); 
 
\t \t } 
 
\t  } 
 
\t } 
 

 
\t if (strString == null) { 
 
\t  throw new NullPointerException(); 
 
\t } 
 

 
\t return strString.length(); 
 
    } 
 
}

ответ

1

Вы добавляете свой XHTML как AlternativeFormatInputPart (AFIP), который обычно оставляет его до Слова для преобразования XHTML в режиме реального содержания DOCX.

В то же время содержимое XHTML не находится в документе DocumentPart MainDocumentPart, его в AFIP. Так, конечно, считать слова в documentPart не даст вам то, что вы надеетесь ...

+0

некоторые сомнения : 1. AFIP не является частью JAXB, не так ли? 2. Каков рекомендуемый способ преобразования XHTML в DocX, чтобы сохранить его стили контента? В моей новой реализации программа может рассчитывать корректно, но когда я открываю docx, созданный в Word, он делает контент немного другим. –

0

Использование docx4j 2.8.1 Правильная реализация экспорта метода должны быть следующие:

private static WordprocessingMLPackage export(String xhtml) { 
WordprocessingMLPackage wordMLPackage = null; 

try { 
    wordMLPackage = WordprocessingMLPackage.createPackage(); 
    List<Object> content = XHTMLImporter.convert(xhtml, null, 
     wordMLPackage); 
    wordMLPackage.getMainDocumentPart().getContent().addAll(content); 
} catch (Docx4JException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

return wordMLPackage; 
}