Conversión de documentos DOC y DOCX a HTML con extracción de imágenes, audio y video

1. Dependencias Maven

<!-- Conversión DOCX a HTML -->
<dependency>
    <groupId>fr.opensagres.xdocreport</groupId>
    <artifactId>fr.opensagres.xdocreport.document</artifactId>
    <version>1.0.6</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.14</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>3.14</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.14</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>3.14</version>
</dependency>
<dependency>
    <groupId>fr.opensagres.xdocreport</groupId>
    <artifactId>org.apache.poi.xwpf.converter.xhtml</artifactId>
    <version>1.0.6</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>ooxml-schemas</artifactId>
    <version>1.3</version>
</dependency>

2. Implementación del código

El siguiente fragmento de código muestra dos métodos: uno para archivos DOCX (Office Open XML) y otro para DOC (antiguo formato binario). Ambos extraen las imágenes y las guardan en un directorio definido por la propiedad rutaImagenes.

@Value("${file.upload}") // Ejemplo: D:\test\files
private String rutaImagenes;

// Endpoint de prueba para DOCX
@RequestMapping("/convertir/docx")
public void convertirDocxEndpoint() throws Exception {
    convertirDocxAHtml("D:\\docs\\ejemplo.docx", 
                       "D:\\docs\\ejemplo.html");
}

// Endpoint de prueba para DOC
@RequestMapping("/convertir/doc")
public void convertirDocEndpoint() throws Exception {
    convertirDocAHtml("D:\\docs\\antiguo.doc", 
                      "D:\\docs\\antiguo.html");
}

/**
 * Convierte un archivo DOCX a HTML, extrayendo imágenes al directorio configurado.
 * Para audio y video, el HTML resultante contendrá referencias a los archivos 
 * embebidos (si el documento los incluye).
 */
public void convertirDocxAHtml(String entradaDocx, String salidaHtml) throws Exception {
    XWPFDocument documento = new XWPFDocument(new FileInputStream(entradaDocx));
    XHTMLOptions opciones = XHTMLOptions.create().indent(4);
    
    // Carpeta para guardar los recursos extraídos (imágenes, etc.)
    File carpetaRecursos = new File(rutaImagenes);
    opciones.setExtractor(new FileImageExtractor(carpetaRecursos));
    opciones.URIResolver(new FileURIResolver(carpetaRecursos));
    
    File archivoSalida = new File(salidaHtml);
    archivoSalida.getParentFile().mkdirs();
    
    try (OutputStream out = new FileOutputStream(archivoSalida)) {
        XHTMLConverter.getInstance().convert(documento, out, opciones);
    }
}

/**
 * Convierte un archivo DOC (binario) a HTML, manejando imágenes y otros recursos.
 */
public void convertirDocAHtml(String entradaDoc, String salidaHtml) throws Exception {
    try (FileInputStream fis = new FileInputStream(entradaDoc)) {
        HWPFDocument documentoWord = new HWPFDocument(fis);
        
        WordToHtmlConverter conversor = new WordToHtmlConverter(
            DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()
        );
        
        // Gestor de imágenes: define la ruta donde se guardarán
        conversor.setPicturesManager(new PicturesManager() {
            @Override
            public String savePicture(byte[] contenido, PictureType tipo, 
                                      String nombreSugerido, float ancho, float alto) {
                // Retorna la ruta relativa que se usará en el HTML
                return rutaImagenes + File.separator + nombreSugerido;
            }
        });
        
        conversor.processDocument(documentoWord);
        
        // Guardar físicamente todas las imágenes extraídas
        List<Picture> listaPics = documentoWord.getPicturesTable().getAllPictures();
        if (listaPics != null) {
            for (Picture pic : listaPics) {
                String rutaCompleta = rutaImagenes + File.separator + pic.suggestFullFileName();
                try (FileOutputStream fos = new FileOutputStream(rutaCompleta)) {
                    pic.writeImageContent(fos);
                }
            }
        }
        
        // Obtener el documento HTML transformado
        Document htmlDoc = conversor.getDocument();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer serializador = tf.newTransformer();
        serializador.setOutputProperty(OutputKeys.ENCODING, "utf-8");
        serializador.setOutputProperty(OutputKeys.INDENT, "yes");
        serializador.setOutputProperty(OutputKeys.METHOD, "html");
        serializador.transform(new DOMSource(htmlDoc), new StreamResult(baos));
        
        // Escribir el contenido HTML al archivo de salida
        escribirArchivo(new String(baos.toByteArray()), salidaHtml);
    }
}

/**
 * Método auxiliar para escribir una cadena en un archivo.
 */
private void escribirArchivo(String contenido, String rutaArchivo) throws IOException {
    try (BufferedWriter bw = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(rutaArchivo), "utf-8"))) {
        bw.write(contenido);
    }
}

La conversión de DOCX utiliza XHTMLConverter de xdocreport, que extrae automáticamente imágenes y otros recursos incrustados. El método para DOC emplea WordToHtmlConverter de Apache POI y requiere un manejo explícito de las imágenes. Para audio y video, el HTML generado incluirá las referencias a los archivos multimedia si el documento Word los contiene; estos se almacenarán en el mismo directorio de recursos.

Etiquetas: Apache POI XDocReport conversión DOCX conversión DOC HTML

Publicado el 6-21 04:41