Logosulfite.app
rafagazani/sulfite 999999

Expressões

Referência do ExpressionEvaluator — funções, operadores e ternário

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.56 BR (ponto = milhar, vírgula = decimal)
'1,234.56' 1234.56 US (vírgula = milhar, ponto = decimal)
'R$ 1.234,56' 1234.56 Sí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
pageNumber int Número da página atual (começa em 1)
totalPagesintTotal de páginas do documento

Exemplos em printWhen:

"printWhen": "pageNumber == 1"
"printWhen": "pageNumber == totalPages"
"printWhen": "pageNumber > 1"
`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:

{
  "type": "field",
  "id": "pg",
  "x": 450, "y": 8,
  "width": 80,
  "binding": "page"
}
{
  "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:

{
  "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:

// 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:

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#

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

Arredondamento#

O ExpressionEvaluator também implementa applyRounding:

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

Modos disponíveis#

Modo O que faz 2.545 2.535
half_even No empate (dígito 5), vai para o par mais próximo. Padrão bancário. 2.54 2.54
half_up No empate, arredonda para cima. O "arredondamento escolar". 2.55 2.54
half_down No empate, arredonda para baixo. 2.54 2.53
up Sempre para cima, sem exceção. 2.55 2.54
down Sempre para baixo, sem exceção. 2.54 2.53
truncate Corta as casas extras. Mesmo efeito de down para positivos. 2.54 2.53

Todos os exemplos acima consideram precisão 2.