Relatórios e Impressão Gráfica (HTML / PDF)
O RuB disponibiliza um motor de renderização gráfica baseado em HTML5 e CSS (RuBHtmlReport), integrado à biblioteca JasperReports e com suporte ao padrão Thymeleaf (xmlns:th="http://www.thymeleaf.org"). Ele converte templates HTML diretamente em documentos PDF de alta resolução e impressões gráficas formatadas em páginas com dimensões industriais (A4, A5 ou etiquetas gráficas).
1. Funcionamento do Motor Gráfico (RuBHtmlReport)
Diferente do Script de Impressão RUB (que envia comandos brutos em linguagens térmicas como ZPL e EPL), o motor HTML processa elementos visuais avançados, incluindo:
- Interpolação de variáveis de produto e cabeçalho via sintaxe
${VAR}. - Diretivas de repetição e iteração dinâmica via
th:each="item : ${reportCollection}". - Formatação visual avançada via CSS (
@page, flexbox, bordas arredondadas, badges e tipografia corporativa). - Renderização de cartazes de oferta em folha cheia (A4/A5) com preços gigantes e destaque DE/POR.
- Geração de folhas de conferência e separação com caixas de marcação (checklists).
graph LR
A[Template .html / .htm] --> B[RuBHtmlReport Engine]
C[Variáveis de Produto / Cabeçalho: toJasperMap] --> B
D[Coleção de Itens: reportCollection] --> B
B --> E[Documento PDF Gerado]
B --> F[Spooler de Impressão Gráfica]
2. Aplicações e Casos de Uso
| Cenário de Uso | Contexto RuB | Formato Recomendado | Descrição |
|---|---|---|---|
| Cartaz Promocional / Splash de Oferta | Produto | A4 Paisagem ou Retrato | Cartazes de precificação com destaque visual de produto, preço DE/POR e parcelamento para vitrines, pontas de gôndola e ilhas promocionais. |
| Cartazete de Gôndola com Atacarejo | Produto | A5 Retrato | Sinalização de prateleira com destaque de preço unitário e desconto por volume de embalagens. |
| Ficha de Discriminação de Kits | Conjunto | A4 Vertical | Listagem completa de todos os itens, quantidades, setores e códigos de barras que compõem um kit promocional ou cesta de final de ano. |
| Folha de Separação e Montagem | Conjunto / Logística | A4 Vertical | Roteiro de separação de mercadorias com caixas de marcação (checklist) e campos para assinatura do operador e conferente. |
3. Variáveis Disponíveis no Contexto HTML
Ao renderizar um template HTML de Produto ou Conjunto, as seguintes variáveis estão disponíveis no escopo do documento:
Variáveis de Produto
| Variável | Descrição | Exemplo de Valor |
|---|---|---|
${DESCPRODUTO} | Descrição comercial do produto. | SABÃO EM PÓ BRILHO TOTAL 1KG |
${SKU} ou ${CODIGO} | Código interno / SKU do produto. | 102030 |
${COD_PRECO} | Código da tabela de preço aplicada. | 1 |
${PRECO} | Preço de venda atual formatado. | 24,90 |
${PRECO_DE} | Preço regular anterior (se em promoção). | 29,90 |
${PRECO_PROMOCIONAL} | Preço promocional ativo. | 24,90 |
${EMB_1O_VALUE} | Preço unitário da 1ª menor embalagem. | 24,90 |
${EMB_1O_DESC} | Descrição da unidade de venda (UN, KG, CX). | UN |
${EMB_1O_CODIGO_1} | Código de barras EAN principal. | 7891000123456 |
${EMB_2O_VALUE} | Preço por unidade na 2ª embalagem (atacado). | 21,90 |
${EMB_2O_QTD} | Quantidade de unidades na 2ª embalagem. | 6 |
${EMB_2O_TOTAL} | Preço total da 2ª embalagem (ex: fardo/caixa). | 131,40 |
${EMB_2O_DESC} | Descrição da 2ª embalagem (ex: CX, FARDO). | CX |
${FORNECEDOR_NOME} | Razão social ou nome fantasia do fornecedor. | INDÚSTRIA QUÍMICA NACIONAL S.A. |
${PROP_MARCA} | Propriedade extra de marca do produto. | BRILHO TOTAL |
${LOJA} | Nome da filial / loja emitente. | HIPERMERCADO CENTRAL |
${ID_LOJA} | Identificador numérico da loja. | 101 |
${DT_ATUAL} | Data da emissão (dd/MM/yyyy). | 24/08/2026 |
${DTH_ATUAL} | Data e hora completas da emissão. | 24/08/2026 18:30:00 |
4. Exemplos de Modelos HTML para Produto
Exemplo 1: Cartaz Promocional A4 Splash de Oferta (DE / POR)
Template para impressão de cartaz promocional em folha A4 com destaque visual, precificação DE/POR e selo de oferta:
Template HTML (cartaz_oferta_a4.html):
<!DOCTYPE html>
<html lang="pt-BR" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<style>
@page {
size: A4 portrait;
margin: 15mm;
}
* {
box-sizing: border-box;
font-family: 'Arial Black', Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
}
body {
background-color: #ffffff;
color: #111111;
text-align: center;
}
.container {
border: 6px solid #cc0000;
border-radius: 12px;
padding: 20px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.badge-oferta {
background-color: #cc0000;
color: #ffffff;
font-size: 28pt;
font-weight: 900;
padding: 10px 20px;
border-radius: 8px;
display: inline-block;
letter-spacing: 2px;
text-transform: uppercase;
}
.descricao-produto {
font-size: 26pt;
font-weight: bold;
color: #222222;
margin-top: 25px;
line-height: 1.2;
min-height: 70px;
}
.meta-produto {
font-family: Arial, sans-serif;
font-size: 13pt;
color: #555555;
margin-top: 10px;
}
.bloco-preco {
margin-top: 30px;
background: #fff8e7;
border: 3px dashed #e6a100;
border-radius: 10px;
padding: 25px 15px;
}
.preco-de {
font-size: 18pt;
color: #777777;
text-decoration: line-through;
font-family: Arial, sans-serif;
}
.preco-por-container {
display: flex;
justify-content: center;
align-items: baseline;
margin-top: 10px;
color: #cc0000;
}
.simbolo-cifrao {
font-size: 40pt;
margin-right: 5px;
}
.preco-principal {
font-size: 90pt;
font-weight: 900;
line-height: 0.9;
}
.unidade-venda {
font-size: 20pt;
color: #333333;
margin-left: 8px;
font-family: Arial, sans-serif;
}
.rodape-cartaz {
border-top: 2px solid #dddddd;
padding-top: 15px;
display: flex;
justify-content: space-between;
font-family: Arial, sans-serif;
font-size: 11pt;
color: #666666;
}
</style>
</head>
<body>
<div class="container">
<div>
<div class="badge-oferta">OFERTA ESPECIAL</div>
<div class="descricao-produto">${DESCPRODUTO}</div>
<div class="meta-produto">Cód: ${SKU} | Cód. Barras: ${EMB_1O_CODIGO_1}</div>
</div>
<div class="bloco-preco">
<div class="preco-de" th:if="${PRECO_DE != null and PRECO_DE != ''}">DE: R$ ${PRECO_DE}</div>
<div class="preco-por-container">
<span class="simbolo-cifrao">R$</span>
<span class="preco-principal">${PRECO}</span>
<span class="unidade-venda">/${EMB_1O_DESC}</span>
</div>
</div>
<div class="rodape-cartaz">
<div>Loja: ${LOJA} (ID: ${ID_LOJA})</div>
<div>Oferta válida enquanto durarem os estoques | Emitido em: ${DT_ATUAL}</div>
</div>
</div>
</body>
</html>
Protótipo visual do cartaz A4:
+===============================================================================+
| |
| [ OFERTA ESPECIAL ] |
| |
| SABÃO EM PÓ BRILHO TOTAL 1KG |
| Cód: 102030 | Cód. Barras: 7891000123456 |
| |
| + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + |
| | | |
| | DE: R$ 29,90 | |
| | | |
| | R$ 24,90 /UN | |
| | | |
| + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + |
| |
| Loja: HIPERMERCADO CENTRAL (ID: 101) Emitido em: 24/08/2026 |
+===============================================================================+
Exemplo 2: Cartazete de Gôndola A5 com Preço Atacarejo
Modelo compacto A5 para precificação de gôndola e pontas de corredor com diferenciação de preço unitário e preço por atacado (fardo/caixa fechada):
Template HTML (cartazete_atacarejo_a5.html):
<!DOCTYPE html>
<html lang="pt-BR" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<style>
@page {
size: A5 portrait;
margin: 10mm;
}
* {
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
}
body { color: #222222; text-align: center; }
.box {
border: 3px solid #0b5394;
border-radius: 8px;
padding: 12px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.header-top {
background-color: #0b5394;
color: #ffffff;
padding: 6px;
font-size: 14pt;
font-weight: bold;
border-radius: 4px;
}
.titulo-prod {
font-size: 18pt;
font-weight: bold;
margin-top: 10px;
line-height: 1.2;
}
.grade-precos {
display: flex;
justify-content: space-around;
margin-top: 15px;
gap: 10px;
}
.card-varejo, .card-atacado {
flex: 1;
padding: 12px 8px;
border-radius: 6px;
}
.card-varejo {
background-color: #f2f5f8;
border: 1px solid #d0dbe5;
}
.card-atacado {
background-color: #fff2e6;
border: 2px solid #e67e22;
}
.label-tipo { font-size: 11pt; font-weight: bold; color: #555555; }
.label-atacado { font-size: 11pt; font-weight: bold; color: #d35400; }
.valor-preco { font-size: 32pt; font-weight: 900; color: #0b5394; margin-top: 4px; }
.valor-atacado { font-size: 32pt; font-weight: 900; color: #d35400; margin-top: 4px; }
.obs-atacado { font-size: 9.5pt; color: #666666; margin-top: 4px; }
.footer-info {
font-size: 9pt;
color: #777777;
border-top: 1px solid #e0e0e0;
padding-top: 8px;
display: flex;
justify-content: space-between;
}
</style>
</head>
<body>
<div class="box">
<div class="header-top">ECONOMIZE NO ATACADO</div>
<div class="titulo-prod">${DESCPRODUTO}</div>
<div class="grade-precos">
<div class="card-varejo">
<div class="label-tipo">UNITÁRIO (VAREJO)</div>
<div class="valor-preco">R$ ${EMB_1O_VALUE}</div>
<div class="obs-atacado">Por ${EMB_1O_DESC}</div>
</div>
<div class="card-atacado">
<div class="label-atacado">A PARTIR DE ${EMB_2O_QTD} UN</div>
<div class="valor-atacado">R$ ${EMB_2O_VALUE}</div>
<div class="obs-atacado">Total ${EMB_2O_DESC}: R$ ${EMB_2O_TOTAL}</div>
</div>
</div>
<div class="footer-info">
<div>SKU: ${SKU} | EAN: ${EMB_1O_CODIGO_1}</div>
<div>Loja: ${LOJA} | ${DT_ATUAL}</div>
</div>
</div>
</body>
</html>
Protótipo visual do cartazete A5:
+===============================================================+
| ECONOMIZE NO ATACADO |
| |
| REFRIGERANTE COLA LATA 350ML |
| |
| +--------------------------+ +--------------------------+ |
| | UNITÁRIO (VAREJO) | | A PARTIR DE 12 UN | |
| | R$ 4,50 | | R$ 4,00 | |
| | Por UN | | Total CX: R$ 48,00 | |
| +--------------------------+ +--------------------------+ |
| |
| SKU: 45892 | EAN: 7894900011517 Loja: CENTRAL | 24/08 |
+===============================================================+
5. Modelos HTML para Conjunto
Para relatórios discriminados de kits, cestas básicas e folhas de conferência com iteração em lista de produtos via th:each, consulte a seção dedicada: