Class ReceiptTemplate
java.lang.Object
io.github.chkrishnatej.rp3200.template.ReceiptTemplate
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
- Placeholders (
{{name}},{{#each}},{{#if}}, ...) are filled from the data object - aMap, 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. - 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
| Syntax | Meaning |
|---|---|
{{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
| Tag | Effect |
|---|---|
[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|c | table 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 Summary
Modifier and TypeMethodDescriptionstatic ReceiptTemplateCompiles a template from a string.Runs only the placeholder pass and returns the intermediate markup text.static ReceiptTemplatefromClasspath(String resourcePath) Loads and compiles a UTF-8 template from the classpath, e.g.static ReceiptTemplateLoads and compiles a UTF-8 template file from disk - useful when shops customise templates without rebuilding the application.Preview for 80 mm paper.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.byte[]Renders for 80 mm paper.byte[]render(Object data, PrinterProfile profile) Renders the template to ESC/POS bytes ready to send to the printer (for example as anapplication/octet-streamresponse that the browser forwards to rp3200-agent).renderInto(EscPosBuilder builder, Object data) Appends this template to an existing builder, so templates and Java code can be mixed:
-
Method Details
-
compile
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- ifsourceis null
-
fromClasspath
Loads and compiles a UTF-8 template from the classpath, e.g."receipts/bill.txt"forsrc/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 compiledUncheckedIOException- if it cannot be read
-
fromFile
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 compiledUncheckedIOException- if it cannot be read
-
render
Renders for 80 mm paper. Shortcut forrender(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
Renders the template to ESC/POS bytes ready to send to the printer (for example as anapplication/octet-streamresponse that the browser forwards to rp3200-agent).- Parameters:
data- values for the placeholders (Map, record or JavaBean); may be nullprofile- the paper / printer profile- Returns:
- the complete receipt as ESC/POS bytes
- Throws:
TemplateException- if the markup is invalid or a value cannot be formattedIllegalArgumentException- if printed content is invalid, e.g. a non-ASCII barcode
-
renderInto
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 todata- 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
Returns a plain-text picture of what would be printed - ideal for logs and unit tests of templates without a printer. SeeEscPosBuilder.preview()for the format.- Parameters:
data- values for the placeholders; may be nullprofile- the paper / printer profile- Returns:
- the preview text
- Throws:
TemplateException- if the markup is invalid or a value cannot be formatted
-
preview
Preview for 80 mm paper. Shortcut forpreview(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
Runs only the placeholder pass and returns the intermediate markup text. Useful to debug a template:TemplateExceptionmessages 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)
-