Conversão de Documentos Word para HTML em Java com Apache POI

Este artigo detalha como converter documentos Microsoft Word (.doc e .docx) para o formato HTML utilizando a biblioteca Apache POI em Java. O processo envolve a análise do conteúdo do Word, incluindo texto, formatação e imagens, e sua reestruturação como um documanto HTML.

Para realizar essa conversão, são necessárias as seguintes dependências no seu projeto:


<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>fr.opensagres.xdocreport</groupId>
    <artifactId>xdocreport</artifactId>
    <version>1.0.6</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>3.14</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>ooxml-schemas</artifactId>
    <version>1.3</version>
</dependency>
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.11.3</version>
</dependency>

Conversão de Documentos Word 2003 (.doc) para HTML

Para arquivos no formato antigo (.doc), a classe WordToHtmlConverter é utilizada. O processo envolve:

  1. Carregar o documento .doc utilizando HWPFDocument.
  2. Configurar um PicturesManager para extrair e salvar as imagens em um diretório específico.
  3. Processar o documento para gerar um objeto Document do W3C DOM.
  4. Utilizar um Transformer para serializar o DOM em um arquivo HTML, garantindo a codificação correta e a formatação indentada.

O método Word2003ToHtml gerencia esse fluxo, recebendo os caminhos do arquivo Word e do diretório de saída HTML. Imagens são salvas em um subdiretório 'image' e referenciadas de forma relativa no HTML gerado.


import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;

public class WordConverter {

    private static final Logger logger = LogManager.getLogger(WordConverter.class);

    /**
     * Converte um documento Word 2003 (.doc) para HTML.
     *
     * @param wordDirectory  Diretório onde o arquivo Word está localizado.
     * @param wordFileName   Nome do arquivo Word sem a extensão.
     * @param wordFileSuffix Extensão do arquivo Word (ex: ".doc").
     * @param htmlOutputDir  Diretório onde o arquivo HTML e as imagens serão salvos.
     * @return O caminho absoluto do arquivo HTML gerado.
     * @throws IOException              Se ocorrer um erro de I/O.
     * @throws TransformerException     Se ocorrer um erro durante a transformação XML/HTML.
     * @throws ParserConfigurationException Se houver um problema na configuração do parser XML.
     */
    public static String convertDocToHtml(String wordDirectory, String wordFileName, String wordFileSuffix, String htmlOutputDir)
            throws IOException, TransformerException, ParserConfigurationException {
        
        String htmlFileName = wordFileName + ".html";
        final String imageOutputDirPath = htmlOutputDir + File.separator + "images" + File.separator;
        File outputHtmlFile = new File(htmlOutputDir + File.separator + htmlFileName);

        if (outputHtmlFile.exists()) {
            logger.info("Arquivo HTML já existe: {}", outputHtmlFile.getAbsolutePath());
            return outputHtmlFile.getAbsolutePath();
        }

        // Caminho completo do arquivo Word original
        final String fullWordPath = wordDirectory + File.separator + wordFileName + wordFileSuffix;
        InputStream wordInputStream = new FileInputStream(new File(fullWordPath));
        HWPFDocument wordDocument = new HWPFDocument(wordInputStream);

        // Configura o conversor e o gerenciador de imagens
        WordToHtmlConverter htmlConverter = new WordToHtmlConverter(
                DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());

        htmlConverter.setPicturesManager(new PicturesManager() {
            @Override
            public String savePicture(byte[] content, PictureType pictureType, String suggestedName, float width, float height) {
                File imageDir = new File(imageOutputDirPath);
                if (!imageDir.exists()) {
                    imageDir.mkdirs();
                }
                File outputFile = new File(imageOutputDirPath + suggestedName);
                try (OutputStream imageStream = new FileOutputStream(outputFile)) {
                    imageStream.write(content);
                } catch (IOException e) {
                    logger.error("Erro ao salvar imagem: {}", suggestedName, e);
                }
                // Retorna o caminho relativo da imagem para o HTML
                return "images/" + suggestedName;
            }
        });

        // Processa o documento Word
        htmlConverter.processDocument(wordDocument);
        Document htmlDom = htmlConverter.getDocument();

        // Cria o diretório de saída se não existir
        File outputDir = new File(htmlOutputDir);
        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }

        // Transforma o DOM em um arquivo HTML
        OutputStream htmlOutputStream = new FileOutputStream(outputHtmlFile);
        DOMSource domSource = new DOMSource(htmlDom);
        StreamResult streamResult = new StreamResult(htmlOutputStream);

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer serializer = transformerFactory.newTransformer();
        serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        serializer.setOutputProperty(OutputKeys.INDENT, "yes");
        serializer.setOutputProperty(OutputKeys.METHOD, "html");
        serializer.transform(domSource, streamResult);

        logger.info("Documento Word convertido para HTML em: {}", outputHtmlFile.getAbsolutePath());
        return outputHtmlFile.getAbsolutePath();
    }
    
    // Exemplo de uso em um método main
    public static void main(String[] args) {
        try {
            String wordDir = "C:\\path\\to\\your\\word\\files";
            String wordName = "my_document";
            String wordSuffix = ".doc";
            String htmlDir = "C:\\path\\to\\output\\html";
            
            convertDocToHtml(wordDir, wordName, wordSuffix, htmlDir);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Conversão de Documentos Word 2007+ (.docx) para HTML

Para arquivos mais recentes (.docx), a abordagem utiliza as classes específicas para o formato OOXML, como XWPFDocument e XHTMLConverter.

  1. Carregar o documento .docx com XWPFDocument.
  2. Configurar opções de conversão (XHTMLOptions), definindo um URIResolver para especificar como as imagens serão referenciadas e um FileImageExtractor para salvá-las.
  3. Utilizar XHTMLConverter para realizar a conversão diretamente para um OutputStream.

O método convertDocxToHtml implementa esta lógica. Similarmente, ele cria um diretório para imagens e garante que o diretório de saída HTML exista.


import org.apache.poi.xwpf.converter.core.BasicURIResolver;
import org.apache.poi.xwpf.converter.core.FileImageExtractor;
import org.apache.poi.xwpf.converter.xhtml.XHTMLConverter;
import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import java.io.*;

public class WordConverter {

    // ... (método convertDocToHtml e logger podem estar aqui) ...

    /**
     * Converte um documento Word 2007+ (.docx) para HTML.
     *
     * @param wordDirectory  Diretório onde o arquivo Word está localizado.
     * @param wordFileName   Nome do arquivo Word sem a extensão.
     * @param wordFileSuffix Extensão do arquivo Word (ex: ".docx").
     * @param htmlOutputDir  Diretório onde o arquivo HTML e as imagens serão salvos.
     * @return O caminho absoluto do arquivo HTML gerado.
     * @throws IOException Se ocorrer um erro de I/O.
     */
    public static String convertDocxToHtml(String wordDirectory, String wordFileName, String wordFileSuffix, String htmlOutputDir)
            throws IOException {
        
        String htmlFileName = wordFileName + ".html";
        String imageOutputDirPath = htmlOutputDir + File.separator + "images" + File.separator;
        File outputHtmlFile = new File(htmlOutputDir + File.separator + htmlFileName);

        if (outputHtmlFile.exists()) {
            logger.info("Arquivo HTML já existe: {}", outputHtmlFile.getAbsolutePath());
            return outputHtmlFile.getAbsolutePath();
        }

        // Caminho completo do arquivo Word original
        File wordFile = new File(wordDirectory + File.separator + wordFileName + wordFileSuffix);
        
        // Carrega o documento .docx
        InputStream wordInputStream = new FileInputStream(wordFile);
        XWPFDocument document = new XWPFDocument(wordInputStream);

        // Configura as opções de conversão para XHTML
        File imageDirectory = new File(imageOutputDirPath);
        XHTMLOptions options = XHTMLOptions.create();
        options.setExtractor(new FileImageExtractor(imageDirectory)); // Define onde salvar imagens
        options.URIResolver(new BasicURIResolver("images")); // Define o prefixo do caminho das imagens no HTML
        options.setIgnoreStylesIfUnused(false); // Manter estilos mesmo se não usados
        options.setFragment(true); // Gera um fragmento HTML, não um documento completo

        // Cria o diretório de saída se não existir
        File outputDir = new File(htmlOutputDir);
        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }

        // Converte o documento Word para HTML
        OutputStream htmlOutputStream = new FileOutputStream(outputHtmlFile);
        XHTMLConverter.getInstance().convert(document, htmlOutputStream, options);

        logger.info("Documento .docx convertido para HTML em: {}", outputHtmlFile.getAbsolutePath());
        return outputHtmlFile.getAbsolutePath();
    }

    // Exemplo de uso em um método main
    public static void main(String[] args) {
        try {
            String wordDir = "C:\\path\\to\\your\\word\\files";
            String wordName = "my_complex_document";
            String wordSuffix = ".docx";
            String htmlDir = "C:\\path\\to\\output\\html";
            
            convertDocxToHtml(wordDir, wordName, wordSuffix, htmlDir);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Execução e Verificação

Para testar a funcionalidade, crie um arquivo Word de teste (.doc ou .docx) e ajuste os caminhos nos métodos main de exemplo para corresponder à localização dos seus arquivos. Após a execução, verifique o diretório de saída especificado. Você encontrará o arquivo HTML gerado e um subdiretório contendo as imagens extraídas do documento original. Ao abrir o arquivo HTML em um navegador, o conteúdo e as imagens devem ser renderizados conforme o documento original.

Tags: java apache poi word para html conversão de documentos docx para html

Publicado em 9-17 19:15