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:
- Carregar o documento .doc utilizando
HWPFDocument. - Configurar um
PicturesManagerpara extrair e salvar as imagens em um diretório específico. - Processar o documento para gerar um objeto
Documentdo W3C DOM. - Utilizar um
Transformerpara 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.
- Carregar o documento .docx com
XWPFDocument. - Configurar opções de conversão (
XHTMLOptions), definindo umURIResolverpara especificar como as imagens serão referenciadas e umFileImageExtractorpara salvá-las. - Utilizar
XHTMLConverterpara realizar a conversão diretamente para umOutputStream.
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.