r2soft/docx-toolkit

Manipulação de DOCX por tags e exportação para DOCX/PDF (PHP puro).

v0.1.0 2025-08-14 20:48 UTC

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() ou toPdf(), 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ência numero
  • tabela_lotes_lista (array): se a variável quadra_q existir no template, clona a tabela com essa referência
  • dados_tabela_simples (array): clona tabela com referência item

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 usar toPdf().
  • $pdfRendererPath: caminho do renderer (casos avançados). Normalmente omita.
  • $moneyFormatter: callback para formatar valores monetários. Se não informado, usa Format::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.
  • DocxEngine::toBase64(string $binary): string e DocxEngine::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) ou rs_dinheiro().
  • formatTabelaAtrasadas(array $linhas, $moneyFormatter = null): array — formata números (dinheiro) e datas (dd/mm/YYYY) para a tabela especial tabela_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ência item.
  • 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