java.lang.Object
io.github.chkrishnatej.rp3200.template.ReceiptTemplate

public final class ReceiptTemplate extends Object
A compiled receipt template: plain text with {{placeholders}} and [markup].

Typical use in Spring Boot


 @Bean
 ReceiptTemplate billTemplate() {                       // compile once at start-up
     return ReceiptTemplate.fromClasspath("receipts/bill.txt");
 }

 @GetMapping(value = "/api/bills/{id}/receipt", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
 byte[] receipt(@PathVariable long id) {
     return billTemplate.render(bills.find(id), PrinterProfile.RP3200_80MM);
 }
 

Template example

 [center][big]{{shop.name}}[/big]
 [line]
 {{#each items}}
 [cols *,4r,10r]{{name}}|{{qty}}|{{amount:%.2f}}
 {{/each}}
 [line]
 [b][cols *,12r]TOTAL|{{total:%.2f}}
 [center][qr]{{upiLink}}[/qr]
 [cut]
 

How rendering works

  1. Placeholders ({{name}}, {{#each}}, {{#if}}, ...) are filled from the data object - a Map, a record or any JavaBean. Values are escaped, so a customer called "[cut]" prints literally instead of cutting the paper. Missing values print as empty text.
  2. Markup ([center], [b], [cols], [qr], [cut], ...) is interpreted line by line into ESC/POS commands. Every line starts fresh: left aligned, plain, normal size.

Placeholder syntax

Placeholders
SyntaxMeaning
{{name}}value, escaped
{{price:%.2f}}value formatted with String.format(java.util.Locale, String, Object...) (Locale.ROOT); works for int, long, double and BigDecimal
{{{name}}}raw value - markup inside it is interpreted
{{customer.name}}nested value (Map key, record component, getter or public field)
{{#each items}}...{{/each}}loop; inside: item properties, {{this}}, {{@number}} (1-based), {{@index}} (0-based), @first, @last; outer values stay reachable
{{#if x}}...{{else}}...{{/if}}condition; null, false, 0, "" and empty collections are false
{{#unless x}}...{{/unless}}inverse condition
{{! comment }}ignored

A block tag alone on its line removes that whole line, so loops leave no blank lines.

Markup syntax

Markup tags
TagEffect
[left] [center] [right]alignment, at the start of a line
[b]..[/b] [u]..[/u] [inv]..[/inv]bold, underline, white on black
[big]..[/big] [tall]..[/tall] [wide]..[/wide]double size, double height, double width
[cols *,4r,10r]a|b|ctable row, see Columns
[line], [line =]full-width separator
[qr]data[/qr], [qr 8]data[/qr]QR code, optional module size 1..16
[barcode]data[/barcode], [barcode 60]..CODE128, optional height in dots
[feed], [feed 3]blank lines
[cut], [cut partial]paper cut
[drawer], [drawer 5]open the cash drawer
\[ \] \| \\literal characters

Block tags (line, feed, cut, drawer, qr, barcode, cols) must start their line (after optional alignment/style tags). Unknown tags throw TemplateException.

Thread-safety: instances are immutable and thread-safe - compile once, render from any number of threads.

See Also:
  • Method Details

    • compile

      public static ReceiptTemplate compile(String source)
      Compiles a template from a string.
      Parameters:
      source - the template text
      Returns:
      the compiled template
      Throws:
      TemplateException - if the placeholder structure is invalid, e.g. an unclosed {{#each}}. Markup errors are reported when rendering.
      NullPointerException - if source is null
    • fromClasspath

      public static ReceiptTemplate fromClasspath(String resourcePath)
      Loads and compiles a UTF-8 template from the classpath, e.g. "receipts/bill.txt" for src/main/resources/receipts/bill.txt. Works inside Spring Boot fat jars.
      Parameters:
      resourcePath - classpath location, with or without a leading slash
      Returns:
      the compiled template
      Throws:
      TemplateException - if the resource does not exist or cannot be compiled
      UncheckedIOException - if it cannot be read
    • fromFile

      public static ReceiptTemplate fromFile(Path file)
      Loads and compiles a UTF-8 template file from disk - useful when shops customise templates without rebuilding the application.
      Parameters:
      file - the template file
      Returns:
      the compiled template
      Throws:
      TemplateException - if it cannot be compiled
      UncheckedIOException - if it cannot be read
    • render

      public byte[] render(Object data)
      Renders for 80 mm paper. Shortcut for render(data, PrinterProfile.RP3200_80MM).
      Parameters:
      data - values for the placeholders (Map, record or JavaBean); may be null
      Returns:
      ESC/POS bytes ready to send to the printer
      Throws:
      TemplateException - if the markup is invalid or a value cannot be formatted
    • render

      public byte[] render(Object data, PrinterProfile profile)
      Renders the template to ESC/POS bytes ready to send to the printer (for example as an application/octet-stream response that the browser forwards to rp3200-agent).
      Parameters:
      data - values for the placeholders (Map, record or JavaBean); may be null
      profile - the paper / printer profile
      Returns:
      the complete receipt as ESC/POS bytes
      Throws:
      TemplateException - if the markup is invalid or a value cannot be formatted
      IllegalArgumentException - if printed content is invalid, e.g. a non-ASCII barcode
    • renderInto

      public EscPosBuilder renderInto(EscPosBuilder builder, Object data)
      Appends this template to an existing builder, so templates and Java code can be mixed:
      
       EscPosBuilder b = new EscPosBuilder(PrinterProfile.RP3200_80MM);
       header.renderInto(b, shop);           // template
       b.row(cols, "Extra item", "1", "10.00"); // Java
       footer.renderInto(b, bill);           // template
       byte[] bytes = b.build();
       

      Each template line starts fresh (left, plain), and the builder is left with that plain state afterwards.

      Parameters:
      builder - the builder to append to
      data - values for the placeholders; may be null
      Returns:
      the same builder, for chaining
      Throws:
      TemplateException - if the markup is invalid or a value cannot be formatted
    • preview

      public String preview(Object data, PrinterProfile profile)
      Returns a plain-text picture of what would be printed - ideal for logs and unit tests of templates without a printer. See EscPosBuilder.preview() for the format.
      Parameters:
      data - values for the placeholders; may be null
      profile - the paper / printer profile
      Returns:
      the preview text
      Throws:
      TemplateException - if the markup is invalid or a value cannot be formatted
    • preview

      public String preview(Object data)
      Preview for 80 mm paper. Shortcut for preview(data, PrinterProfile.RP3200_80MM).
      Parameters:
      data - values for the placeholders; may be null
      Returns:
      the preview text
      Throws:
      TemplateException - if the markup is invalid or a value cannot be formatted
    • expand

      public String expand(Object data)
      Runs only the placeholder pass and returns the intermediate markup text. Useful to debug a template: TemplateException messages for markup errors refer to "output lines" of this text.
      Parameters:
      data - values for the placeholders; may be null
      Returns:
      the template with all placeholders filled in (values escaped)