r2soft / docx-toolkit
Manipulação de DOCX por tags e exportação para DOCX/PDF (PHP puro).
Requires
- php: >=8.1
- ext-zip: *
- phpoffice/phpword: ^1.4
Requires (Dev)
- dompdf/dompdf: ^3.1
- r2soft/utils: ^1.0
Suggests
- dompdf/dompdf: Necessário para conversão PDF via DomPDF
- mpdf/mpdf: Alternativa de conversão PDF
- tecnickcom/tcpdf: Alternativa de conversão PDF
This package is not auto-updated.
Last update: 2025-08-15 00:31:57 UTC
README
Biblioteca PHP para preencher templates DOCX (variáveis, tabelas e blocos) e converter DOCX em PDF, usando PhpOffice/PhpWord por baixo dos panos. Foco em simplicidade, zero dependências de framework e compatível com Docker.
- Preenchimento de variáveis simples (setValue)
- Preenchimento de tabelas (cloneRowAndSetValues)
- Preenchimento de blocos (cloneBlock com índices #1, #2, ...)
- Suporte a textos ricos básicos via setComplexValue a partir de tags HTML: , , , ,
- Conversão de DOCX para PDF com DomPDF, mPDF ou TCPDF
- Aceita template como binário ou Base64
Requisitos
- PHP >= 8.1
- Extensão ext-zip habilitada
- PhpOffice/phpword ^1.4
- Para PDF (opcional): dompdf/dompdf, mpdf/mpdf ou tecnickcom/tcpdf
Consulte composer.json
para detalhes de dependências e sugestões.
Instalação
Via Composer (dentro do seu projeto):
composer require r2soft/docx-toolkit
# Para PDF (opcional escolha um):
composer require dompdf/dompdf
# ou
composer require mpdf/mpdf
# ou
composer require tecnickcom/tcpdf
Uso rápido
Exemplo mínimo (baseado em test.php):
<?php
require __DIR__ . '/vendor/autoload.php';
use R2Soft\Docx\DocxEngine;
$engine = new DocxEngine(pdfRenderer: 'DomPDF'); // ou 'mPDF', 'TCPDF' ou null
$templateBinary = file_get_contents('exemplo.docx');
$docx = $engine->renderDocx($templateBinary, [
'nome' => 'Fulano',
]);
file_put_contents('saida.docx', $docx);
Converter para PDF
$pdfBinary = $engine->toPdf($docx); // $docx pode ser binário ou base64
file_put_contents('saida.pdf', $pdfBinary);
Observações importantes:
- Se você passar Base64 no
renderDocx()
outoPdf()
, a biblioteca detecta e converte automaticamente. - Para PDF, é obrigatório informar
pdfRenderer
no construtor e ter a dependência do motor instalada.
Como preparar o template DOCX
Você pode criar seu DOCX no Word/LibreOffice e inserir marcadores entre chaves. Exemplos:
- Variáveis simples: ${nome}
- Tabela (cloneRowAndSetValues): defina uma linha com marcadores como ${item_nome}, ${item_preco} e repita a linha. Ao chamar
preencherTabela('item', $linhas)
a engine multiplicará as linhas. - Blocos (cloneBlock): crie um bloco nomeado, por exemplo,
tabela_lotes
no conteúdo e use marcadores com sufixos#1
,#2
, ... ex.: ${campo#1}, ${campo#2}.
A engine já contempla alguns nomes especiais de chave para facilitar:
tabela_lotes
(array): usa cloneBlock com índices (#1, #2, ...)tabela_atrasadas
(array): aplica formatação de dinheiro e datas automaticamente e clona uma tabela com referêncianumero
tabela_lotes_lista
(array): se a variávelquadra_q
existir no template, clona a tabela com essa referênciadados_tabela_simples
(array): clona tabela com referênciaitem
Se você não usar esses nomes especiais, ainda pode preencher variáveis simples diretamente com o mesmo nome das chaves no array $termos
.
Texto rico básico
Quando o valor tiver HTML simples com <b>
, <strong>
, <i>
, <u>
ou <br>
, a engine converte para um TextRun
e usa setComplexValue()
, preservando estilo e quebras de linha. Caso contrário, usa setValue()
com limpeza de tags.
Há um tratamento especial para chaves contendo "assinatura": nelas o HTML não é removido na limpeza de variáveis simples.
API principal
R2Soft\Docx\DocxEngine
Construtor:
new DocxEngine(
?string $pdfRenderer = null, // 'DomPDF' | 'mPDF' | 'TCPDF' | null
?string $pdfRendererPath = null, // opcional; normalmente não é necessário
$moneyFormatter = null // callable|null para formatar dinheiro
)
$pdfRenderer
: define o motor para gerar PDF. Obrigatório para usartoPdf()
.$pdfRendererPath
: caminho do renderer (casos avançados). Normalmente omita.$moneyFormatter
: callback para formatar valores monetários. Se não informado, usaFormat::rs_dinheiro()
.
Métodos:
renderDocx(string $templateBase64OrBinary, array $termos): string
- Recebe o template como binário ou Base64 e um array de termos.
- Entrega o DOCX gerado (binário).
toPdf(string $docxBinaryOrBase64): string
- Converte um DOCX (binário/Base64) para PDF (binário). Requer
$pdfRenderer
.
- Converte um DOCX (binário/Base64) para PDF (binário). Requer
DocxEngine::toBase64(string $binary): string
eDocxEngine::fromBase64(string $b64): string
R2Soft\Docx\Support\Templating
toTextRun(string $html): TextRun
— converte HTML básico para TextRun.preencherTabela(TemplateProcessor $template, string $tagReferencia, array $dados): void
— clona linhas de tabela baseadas na tag de referência (ex.:item
). O array$dados
deve ser uma lista de arrays associativos.preencherBloco(TemplateProcessor $template, string $nomeBloco, array $dados): void
— clona blocos usando sufixos#1
,#2
, etc.
R2Soft\Docx\Support\Format
toDate(mixed $v): ?DateTime
— tenta converter para data.money(mixed $v, $moneyFormatter = null): string
— formata dinheiro usando callback customizado (se houver) ours_dinheiro()
.formatTabelaAtrasadas(array $linhas, $moneyFormatter = null): array
— formata números (dinheiro) e datas (dd/mm/YYYY) para a tabela especialtabela_atrasadas
.rs_dinheiro($value, int $decimal=2, string $dec=",", string $mil="."): string
— formatação brasileira:R$ 1.234,56
.
Estrutura esperada dos dados
Exemplos práticos:
$termos = [
'nome' => 'Fulano',
// Tabela simples com referência 'item' no template:
'dados_tabela_simples' => [
['item' => 'Produto A', 'preco' => 10.5],
['item' => 'Produto B', 'preco' => 22],
],
// Tabela atrasadas (formatação automática)
'tabela_atrasadas' => [
['numero' => 1, 'vencimento' => '2025-08-10', 'valor' => 140.9],
['numero' => 2, 'vencimento' => '2025-09-10', 'valor' => 200],
],
// Bloco 'tabela_lotes' com índices #1, #2 no template
'tabela_lotes' => [
['quadra' => 'Q1', 'lote' => 'L10'],
['quadra' => 'Q2', 'lote' => 'L20'],
],
];
No template, você usaria por exemplo:
${item}
e${preco}
na linha da tabela de referênciaitem
.- Para blocos,
${quadra#1}
,${lote#1}
,${quadra#2}
,${lote#2}
, etc.
Docker e Docker Compose
O projeto inclui Dockerfile
e docker-compose.yaml
para desenvolvimento.
Subindo o contêiner de desenvolvimento:
docker compose up --build -d
Entrar no contêiner e instalar dependências:
docker compose exec app bash
composer install
Rodar o exemplo test.php
dentro do contêiner:
php test.php
Arquivos são montados via volume em /app
. Ajuste PHP_MEMORY_LIMIT
em docker-compose.yaml
se necessário.
Boas práticas e dicas
- Use apenas HTML simples suportado para
setComplexValue
(, , , ,
). - Garanta que os nomes das chaves no array
$termos
existam como variáveis no DOCX. - Para tabelas com
cloneRowAndSetValues
, defina uma única linha modelo com os marcadores e deixe a engine multiplicar. - Valores não escalares em variáveis simples são convertidos para texto padrão "NÃO DEFINIDO".
- Campos contendo "assinatura" não têm o HTML removido automaticamente.
Solução de problemas
- Erro "Renderer de PDF não configurado": forneça
pdfRenderer
no construtor e instale o pacote do renderer (DomPDF/mPDF/TCPDF). - Problemas com fontes no PDF: pode ser necessário instalar fontes adicionais no contêiner/sistema ou configurar o renderer.
- Quebras de linha: use
<br>
ou\r\n
no valor para quebrar linhas adequadamente.
Licença
MIT.
Autores
- Ricardo de Paula Coelho — ricardo@r2soft.com.br
- R2 Soft - Informática e Softwares Ltda-ME — r2soft@r2soft.com.br