You are reading the documentation of sheetsmith 1.0.x.See the latest version (1.0.x)
Complete example
A fictional service company produces a monthly report of the cases handled by its teams, in the corporate style shared by all its reports.
public enum CaseStatus implements Labelled { OPEN("Open"), WAITING("Waiting for customer"), CLOSED("Closed"); private final String label; CaseStatus(String label) { this.label = label; } @Override public String label() { return label; }}
@ExcelSheet( title = "Case handling, September 2026", titleStyle = "corp-title", preset = TablePreset.LIGHT, accentColor = "#0B3D5C", styleSheets = CorporateStyles.class, autoFilter = true, header = @HeaderStyles(base = "corp-header"), body = @BodyStyles(base = "corp-cell", firstColumn = "case-number"))@ExcelStyle(name = "case-number", bold = Toggle.TRUE)@ExcelStyle(name = "centered", align = Align.CENTER)public record CaseRow( @ExcelColumn(header = "Case", order = 10, width = 14) String number, @ExcelColumn(header = "Opened on", order = 20, format = "dd/mm/yyyy", styles = @ColumnStyles(base = "centered")) LocalDate openedOn, @ExcelColumn(header = "Team", order = 30) String team, @ExcelColumn(header = "Category", order = 40) String category, @ExcelColumn(header = "Status", order = 50) CaseStatus status, @ExcelColumn(header = "Due on", order = 60, format = "dd/mm/yyyy", styles = @ColumnStyles(base = "centered")) LocalDate dueOn, @ExcelColumn(header = "Days open", order = 70, format = "0") int daysOpen, @ExcelColumn(header = "Charged", order = 80, styles = @ColumnStyles(base = "corp-money")) BigDecimal charged, @ExcelColumn(header = "Notes", order = 90, width = 60) String notes) {}Spring configuration:
sheetsmith: formats: date: dd/mm/yyyy document: author: Example Services Ltd application: Case Reporting validation: packages: com.example.reporting@Configurationclass ReportingConfiguration { @Bean CellConverter<Labelled> labelConverter() { return (value, context) -> CellValue.text(value.label()); }}
@Serviceclass CaseReportService {
private final Sheetsmith sheetsmith; private final CaseQueries queries;
CaseReportService(Sheetsmith sheetsmith, CaseQueries queries) { this.sheetsmith = sheetsmith; this.queries = queries; }
void writeMonthlyReport(YearMonth month, OutputStream out) { List<SheetData<?>> sheets = List.of( SheetData.of("Cases", CaseRow.class, queries.cases(month)), SheetData.of("By team", TeamSummaryRow.class, queries.summaryByTeam(month))); sheetsmith.generate(sheets, out); }}What the reader sees: a title in the corporate font; a header with bold text, a dark accent line and wrapped labels; light zebra rows separated by thin lines; bold case numbers; centred dates in dd/mm/yyyy; status labels instead of constant names; amounts right-aligned with two decimals; an auto-filter on every column; the file properties showing “Example Services Ltd” and “Case Reporting”. Styling that depends on the value of a cell, such as overdue cases in red, is not part of version 1.0.0: styles depend on the position of the cell, never on its content.