Skip to content
sheetsmith

Sheetsmith

Type Kind Role
Sheetsmith interface The generator.
Sheetsmith.Builder interface Configures and builds generators.
SheetData<T> record One sheet to generate: name, sheet class, data.
SheetsmithDefaults record Application defaults: default formats, default preset and accent colour.
DocumentProperties record Author and application recorded in every file.
SheetsmithException sealed abstract class Base of the library exceptions.
SheetsmithConfigurationException final class Configuration errors, with the list of ConfigurationError.
SheetsmithGenerationException final class Data errors during writing, with sheet, row and field.
ConfigurationError record One configuration error.

All of them are in cloud.baldilorenzo.sheetsmith. The converter types are described in section 9.

public interface Sheetsmith {
byte[] generate(List<SheetData<?>> sheets);
void generate(List<SheetData<?>> sheets, OutputStream out);
void validate(Class<?> type);
static Builder builder();
}

Instances are immutable and thread-safe. Create one, with the builder or through the Spring Boot auto-configuration, and share it across the application. The default implementation is created by the builder; applications do not implement the interface, apart from test doubles.

Generates an .xlsx file containing the given sheets and returns its content.

Parameters sheets: the sheets, in workbook order; not null, without null elements
Returns the content of the file
Throws SheetsmithConfigurationException if the input violates V-18 to V-20 or a sheet class violates any of V-01 to V-17, every error listed; SheetsmithGenerationException if an element or a value cannot be written; UncheckedIOException if serialisation fails (practically unreachable with this method, which writes to memory); NullPointerException if sheets is null or contains a null element

Behaviour:

  • Sheets appear in the workbook in list order.
  • Each sheet can use a different sheet class, and one class can be used by several sheets.
  • An empty data list is valid: its sheet contains the title, if any, and the header only.
  • The input and every sheet class are validated before anything is written; the errors of the input and of all the classes are reported together.
  • A class that fails validation is not cached and is rejected at every call until fixed.

generate(List<SheetData<?>>, OutputStream)

Section titled “generate(List<SheetData<?>>, OutputStream)”

Generates the same file and writes it to a stream supplied by the caller.

Parameters sheets: as above; out: the stream that receives the file, not null
Throws as above; UncheckedIOException wraps any IOException during serialisation, including a failure of the stream itself, with the original exception as cause; NullPointerException if sheets or out is null

Contract of the stream:

  • The stream belongs to the caller: it is flushed after the file is written and never closed.
  • The whole workbook is built before serialisation starts, so nothing is written to the stream when a configuration error or a generation error occurs.
  • Partial content can be left in the stream only when an I/O failure occurs during serialisation.

The two methods produce identical content and use practically the same memory: the whole workbook is built in memory before it is written, its in-memory model is far larger than the file, and the extra copy of the file held by the byte[] method is negligible in comparison. Choose by destination:

Destination of the file Method
A file on disk, an HTTP response, a cloud storage upload stream, any other stream generate(sheets, out)
Bytes needed as such: an e-mail attachment, a database column, a message payload, a cache, a test assertion, a Content-Length header generate(sheets)

Validates a sheet class without generating anything.

Parameters type: the sheet class, not null
Throws SheetsmithConfigurationException listing every error of the class; NullPointerException if type is null

It runs every check that generate runs on a class: annotation rules V-01 to V-09 and V-13 to V-17, and converter binding V-10 to V-12, using the application converters and the converter factory of this instance. Validate with an instance configured like the one that generates the files, otherwise a type covered by an application converter can be reported as V-10. Typical uses: unit tests and startup validation.

@Test
void sheetClassesAreValid() {
Sheetsmith sheetsmith = Sheetsmith.builder().converter(Money.class, new MoneyConverter()).build();
assertDoesNotThrow(() -> sheetsmith.validate(InvoiceLine.class));
}

Returns a new builder with default settings: no application converters (only the built-in converters apply), field converters created through their public no-argument constructor, SheetsmithDefaults.standard() and DocumentProperties.standard().

Method Description Throws
<T> Builder converter(Class<T> type, CellConverter<? super T> converter) Registers an application converter for a type. Applies to every column whose declared type is type or a subtype, in every sheet class, unless the column has a field converter or a converter is registered for a closer supertype. Primitive types are registered as their wrappers (double.class and Double.class are the same key). A converter for a type with a built-in converter (Boolean, LocalDate, Enum, …) replaces the built-in behaviour. The converter must be thread-safe. IllegalArgumentException if a converter is already registered for the type (message: a converter is already registered for type X); NullPointerException for a null argument
Builder converterFactory(CellConverterFactory factory) Sets the factory that creates field converters. Called once per converter class, the first time a sheet class declaring it is validated or generated; the result is reused. A converter the factory cannot create violates V-12. NullPointerException
Builder defaults(SheetsmithDefaults defaults) Sets the application defaults. NullPointerException
Builder documentProperties(DocumentProperties properties) Sets the author and application recorded in every file. NullPointerException
Sheetsmith build() Builds an immutable, thread-safe instance with the current settings. none

Every configuration method returns the builder, so calls can be chained.

Sheetsmith sheetsmith = Sheetsmith.builder()
.defaults(new SheetsmithDefaults("dd/mm/yyyy", "dd/mm/yyyy hh:mm", "", TablePreset.LIGHT, "#1F4E79"))
.documentProperties(new DocumentProperties("Example Ltd", "Billing"))
.converter(Money.class, new MoneyConverter())
.converter(Instant.class, new InstantConverter(ZoneId.of("Europe/Rome")))
.build();