Fidelidade e segurança do DOCX
O endpoint de exportação do Next.js gera localmente um pacote WordprocessingML nativo. Esta matriz está vinculada ao teste de fidelidade em nível de pacote que roda no repositório; ela não afirma que qualquer CSS de navegador tenha um equivalente exato no Word. Duas construções têm textos próprios: equações que sobrevivem a uma ida e volta pelo Word e o que realmente há dentro de um .docx.
Mapeamentos testados
| Área | Saída DOCX nativa |
|---|---|
| Estrutura do documento | Títulos, parágrafos, citações em bloco, listas com marcadores e listas decimais aninhadas, tabelas de layout fixo |
| Formatação inline | Negrito, itálico, sublinhado, tachado, código, família e tamanho da fonte, cor do texto/fundo, subscrito e sobrescrito |
| Layout de parágrafo | Alinhamento, margens, altura da linha, recuo da primeira linha, page-break-before e quebras de página explícitas |
| Layout de página | Carta ou A4, retrato ou paisagem, margens dentro de limites, cabeçalhos e rodapés padrão, campos de página atual/total |
| Tabelas | Grade DXA exata, linhas de cabeçalho repetidas, mesclagem de colunas, mesclagem de linhas, sombreamento de célula e alinhamento vertical |
| Semântica de revisão | Inserções, exclusões, comentários, notas de rodapé e notas de fim nativas do DOCX |
| Equações | LaTeX convertido em OMML nativo — frações, índices, radicais, operadores n-ários, delimitadores, funções, limites, acentos, barras e caixas; editáveis no editor de equações do Word, não como imagem |
| Links e mídia | Links HTTP/HTTPS/mailto; data URIs PNG, JPEG, GIF e BMP; mapa de imagens confiável resolvido pelo servidor |
Contrato da requisição
POST /api/export/docx
{
"html": "<h1>Report</h1><p>Body</p>",
"title": "Report",
"fileName": "report.docx",
"headerHtml": "<p>Private report</p>",
"footerHtml": "<p>Page <span data-page-number="current"></span></p>",
"page": { "size": "a4", "orientation": "landscape",
"margin": { "top": 1080, "right": 900, "bottom": 1080, "left": 900 } },
"imageMap": { "https://trusted.example/chart.png": "data:image/png;base64,..." }
}As margens usam vigésimos de ponto (twips) e ficam limitadas entre 360 e 2880. A requisição é limitada a 1 MiB. Um mapa de imagens aceita no máximo oito chaves HTTP(S), apenas valores data-image e 768 KiB decodificados no total.
Convenções de HTML semântico
<ins data-author="Ada" data-date="2026-07-16T12:00:00Z">added</ins>
<del data-author="Ada">removed</del>
<span data-comment="Check the source" data-comment-author="Reviewer">claim</span>
<sup data-footnote="Source citation"></sup>
<span data-endnote="Appendix detail"></span>
<hr class="page-break">Importação de DOCX
A importação roda inteiramente no navegador, sem biblioteca e sem ida e volta ao servidor. Um .docx é um ZIP de XML: o diretório central do ZIP é lido diretamente e DecompressionStream("deflate-raw") faz a descompressão. Nada é enviado para lugar nenhum.
| Importado | Como, e o que um conversor ingênuo perde |
|---|---|
| URLs de hyperlinks | w:hyperlink carrega apenas um r:id; o endereço fica em word/_rels/document.xml.rels. Resolvido — sem isso, todo link é importado como texto simples e a URL é descartada. |
| Imagens | w:drawing → a:blip → word/media/*, incorporadas como data URIs. Defina documentImportImages: false para ignorá-las em arquivos com muitas imagens. |
| Listas numeradas vs. com marcadores | document.xml armazena todas as listas da mesma forma; só word/numbering.xml as diferencia. Esse arquivo é lido, então as listas numeradas continuam sendo <ol> em vez de virarem marcadores. |
| Aninhamento de listas | w:ilvl produz aninhamento real, e a sublista é colocada dentro do <li> pai para que a marcação seja válida. |
| Notas de rodapé e notas de fim | O Word guarda o corpo das notas em partes separadas, word/footnotes.xml e word/endnotes.xml; document.xml contém apenas um id. Todas são lidas e reconstruídas como notas dinâmicas — insira uma acima de uma nota importada e tudo é renumerado. As duas partes compartilham um schema, mas não o nome do elemento (w:footnote vs. w:endnote), então um parser escrito para uma silenciosamente não retorna nada para a outra. As entradas de separador do Word são ignoradas. |
| Caixas de texto | O conteúdo de uma caixa de texto fica seis níveis abaixo do run (w:pict → v:shape → v:textbox → w:txbxContent), então um conversor que lê apenas os filhos diretos descarta cada palavra dele. Recuperado como um bloco .rte-imported-textbox na ordem do documento, com parágrafos e tabelas intactos. Um bloco mc:AlternateContent carrega a mesma caixa duas vezes — uma versão DrawingML e um fallback VML — e só uma é emitida. |
| Alterações controladas e comentários | w:ins e w:del são importados como <ins>/<del> com autor e data — as mesmas convenções que a exportação emite, então a marcação de revisão faz a ida e volta. O texto excluído fica em w:delText, não em w:t. Os intervalos de comentário viram spans data-comment, com o corpo extraído de word/comments.xml. |
| Equações | O Word armazena equações como uma árvore m:oMath em seu próprio namespace math, intercalada entre os runs — um conversor que percorre os elementos w:r nunca a vê, e a equação desaparece enquanto a frase ao redor é importada normalmente. Elas são traduzidas para LaTeX e emitidas como o span rte-math-inline do próprio editor, então ficam editáveis na caixa de diálogo de matemática e são renderizadas por qualquer renderizador que a página carregue. Frações, subscritos/sobrescritos, radicais, operadores n-ários (o operador é um atributo, não texto), delimitadores, funções, limites, acentos, barras, matrizes e arrays alinhados são mapeados; o que não for reconhecido mantém seu texto literal em vez de sumir. |
| SmartArt | O desenho em document.xml contém apenas ids de relacionamento; cada palavra do diagrama fica em word/diagrams/dataN.xml, em um namespace separado, então um leitor que procura a:blip não encontra nada e descarta o gráfico inteiro. O layout não pode ser reproduzido em HTML, mas o conteúdo é recuperado como um esboço .rte-imported-smartart — um organograma importado como lista é utilizável; um importado como espaço em branco é um buraco. Os pontos de apresentação e de conector do Word (pres, parTrans, sibTrans) não têm conteúdo e são ignorados. |
| Imagens WMF/EMF | Metarquivos do Windows não têm uma forma que o navegador consiga renderizar, então não podem ser incorporados. Em vez de desaparecer sem deixar rastro, cada um deixa um placeholder nomeado com data-source, para que o leitor saiba que havia uma figura ali e qual procurar no original. |
| Formatação de caracteres | Cor (w:color), realce, sobrescrito/subscrito e tamanho — w:sz é expresso em meios pontos, então 36 vira 18pt, e não 36pt. |
| Estrutura e formatação | Títulos a partir de w:pStyle, tabelas, alinhamento de parágrafo, negrito, itálico, sublinhado, tachado, tabulações e quebras de linha. |
Markdown, HTML, texto simples e o .doc com sabor de HTML do Word são tratados da mesma forma. Para qualquer coisa além disso — ou para encaminhar a conversão pelo seu próprio serviço — forneça config.documentImportResolver(file), que tem precedência para todos os formatos.
Limitações conhecidas — e são limitações de forma, não de conteúdo. Nada em um .docx é mais descartado silenciosamente. O que o HTML não consegue reproduzir se degrada de forma visível e avisa: caixas de texto voltam como conteúdo, e não como quadros flutuantes (o HTML do navegador não tem equivalente para a ancoragem absoluta na página do Word), SmartArt como um esboço, e não como um gráfico diagramado, e imagens WMF/EMF como um placeholder nomeado. As equações chegam como LaTeX, que precisa de KaTeX ou MathJax na página para ser renderizado como matemática, e não como código-fonte. Essas são lacunas da importação, não da exportação — a tabela acima cobre o que faz a ida e volta hoje. As equações são verificadas como um ciclo real, e não como dois recursos independentes: quinze fórmulas exportadas para OOXML e reimportadas voltam idênticas byte a byte, inclusive os três sinais de ângulo Unicode visualmente idênticos que geradores diferentes emitem.
Fronteira de segurança
O conversor nunca faz requisições de rede. Uma URL em um elemento img é ignorada, a menos que o servidor chamador forneça uma entrada exata de URL para data URI em imageMap. Isso mantém DNS, redirecionamentos, endereços privados, credenciais e autorização de tenant fora da fronteira de confiança do conversor.
Limitações intencionais
- O Word é paginado, e o HTML do navegador é um layout de fluxo. Floats, CSS grid, filtros, scripts, formulários, animações e estilos arbitrários não são traduzidos.
- Apenas os cabeçalhos e rodapés padrão da seção são expostos; variantes de primeira página/página par e várias seções definidas em HTML exigem um template específico da aplicação.
- O conjunto automatizado de testes inspeciona as partes e os relacionamentos OOXML gerados. A aprovação visual no Microsoft Word ou no LibreOffice continua sendo uma etapa de release para templates com marca própria.