Skip to content

Expressões

O ExpressionEvaluator resolve expressões em bindings de FieldElement e em condições. Suporta aritmética, funções de string, comparações e ternários.

Aritmética

quantity * price
price + tax
(total - discount) / installments

Operadores: +, -, *, /, ^

Funções matemáticas: sin, cos, sqrt, abs, pow

Funções de string

FunçãoExemploResultado
UPPER(x)UPPER('hello')HELLO
LOWER(x)LOWER('HELLO')hello
TRIM(x)TRIM(' text ')text
LEN(x)LEN('abc')3
CONCAT(a, b, ...)CONCAT('R$ ', amount)R$ 100
PARSE_NUMBER(x)PARSE_NUMBER('1.234,56')1234.56

PARSE_NUMBER

Converte uma string para número com suporte a localização BR e US:

EntradaSaídaLocalização
'10,90'10.9BR (vírgula decimal)
'1.234,56'1234.56BR (ponto = milhar, vírgula = decimal)
'1,234.56'1234.56US (vírgula = milhar, ponto = decimal)
'R$ 1.234,56'1234.56Símbolo de moeda removido automaticamente

Útil em conjunto com valueExpression em FieldElement para tratar campos string vindos de APIs antes de aplicar format numérico.

Comparações

Retornam 1.0 (verdadeiro) ou 0.0 (falso):

OperadorDescrição
>Maior que
<Menor que
==Igual
!=Diferente
>=Maior ou igual
<=Menor ou igual

Ternário

if(condition, valorVerdadeiro, valorFalso)

Exemplos:

if(amount > 1000, 'VIP', 'Regular')
if(status == 'completed', 'Concluído', 'Pendente')
if(quantity > 0, quantity * price, 0)

Variáveis do sistema

Datas

VariávelValor
TODAY()Data atual — yyyy-MM-dd
NOW()Data e hora — yyyy-MM-dd HH:mm:ss

Paginação (disponível em printWhen de bands no PDF)

Quando o motor renderiza o PDF, as variáveis abaixo são injetadas automaticamente no contexto de avaliação de printWhen:

VariávelTipoValor
pageNumberintNúmero da página atual (começa em 1)
totalPagesintTotal de páginas do documento

Exemplos em printWhen:

json
"printWhen": "pageNumber == 1"
"printWhen": "pageNumber == totalPages"
"printWhen": "pageNumber > 1"

Exclusivo do PDF

pageNumber e totalPages só fazem sentido no PDF. Em HTML, CSV e Excel não existe conceito de página — expresssões que usam essas variáveis são avaliadas sem elas e tendem a retornar true (comportamento fail-open).

Paginação em FieldElement (PDF apenas)

Nas bands header, footer e summary de um PDF, um FieldElement pode usar page ou totalPages como binding:

json
{
  "type": "field",
  "id": "pg",
  "x": 450, "y": 8,
  "width": 80,
  "binding": "page"
}
json
{
  "type": "field",
  "id": "total_pgs",
  "x": 530, "y": 8,
  "width": 40,
  "binding": "totalPages"
}

Paginação em TextElement (PDF apenas)

O campo content de TextElement aceita os marcadores {page} e {totalPages} (case-insensitive). Funciona apenas na renderização PDF:

json
{
  "type": "text",
  "id": "footer_pag",
  "x": 400, "y": 8,
  "width": 150,
  "content": "Página {page} de {totalPages}"
}

Nos demais formatos (HTML, CSV, Excel), esses marcadores ficam sem substituição pois HTML é um documento contínuo e CSV/Excel não têm páginas.

Literais

Strings entre aspas simples ou duplas:

CONCAT('Prefixo: ', field_name)
if(status == "active", 'Ativo', 'Inativo')

Variáveis do payload / contexto

Identificadores sem aspas são buscados no contexto disponível para o elemento:

product         → busca context['product']
quantity * price → busca context['quantity'] e context['price']

Em detail bands, o contexto é o registro atual do data source — cada chave do objeto da lista:

dart
// Payload passado ao engine:
await engine.processData(report, {
  'items': [
    {'product': 'Notebook', 'quantity': 1, 'price': 2500.0},
  ],
});

// No FieldElement: binding: "quantity * price" → 2500.0

Em header, footer e summary, o contexto é o payload global. Use dot-path para campos aninhados:

dart
await engine.processData(report, {
  'items': [...],
  'empresa': {'nome': 'ACME Corp', 'cnpj': '00.000.000/0001-00'},
  'titulo': 'Relatório de Vendas',
});

// FieldElement no header: binding: "empresa.nome"  → "ACME Corp"
// FieldElement no header: binding: "titulo"         → "Relatório de Vendas"

Uso em FieldElement

json
{
  "type": "field",
  "id": "total",
  "x": 300,
  "y": 5,
  "width": 100,
  "binding": "quantity * price",
  "format": "currency:BRL"
}
json
{
  "type": "field",
  "id": "status_label",
  "x": 400,
  "y": 5,
  "width": 80,
  "binding": "if(amount > 1000, 'VIP', 'Regular')"
}

Arredondamento

O ExpressionEvaluator também implementa applyRounding:

dart
evaluator.applyRounding(2.545, 2, mode: 'half_even'); // 2.54
evaluator.applyRounding(2.545, 2, mode: 'half_up');   // 2.55

Modos disponíveis

ModoO que faz2.5452.535
half_evenNo empate (dígito 5), vai para o par mais próximo. Padrão bancário.2.542.54
half_upNo empate, arredonda para cima. O "arredondamento escolar".2.552.54
half_downNo empate, arredonda para baixo.2.542.53
upSempre para cima, sem exceção.2.552.54
downSempre para baixo, sem exceção.2.542.53
truncateCorta as casas extras. Mesmo efeito de down para positivos.2.542.53

Todos os exemplos acima consideram precisão 2.

Sulfite do 🇧🇷 para o mundo © 2026 Rafael S. Pinheiro