Sheetsmith
Overview
Section titled “Overview”| 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.
Sheetsmith
Section titled “Sheetsmith”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.
generate(List<SheetData<?>>)
Section titled “generate(List<SheetData<?>>)”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.
Choosing between byte[] and OutputStream
Section titled “Choosing between byte[] and OutputStream”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) |
validate(Class<?>)
Section titled “validate(Class<?>)”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.
@Testvoid sheetClassesAreValid() { Sheetsmith sheetsmith = Sheetsmith.builder().converter(Money.class, new MoneyConverter()).build(); assertDoesNotThrow(() -> sheetsmith.validate(InvoiceLine.class));}builder()
Section titled “builder()”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().
Sheetsmith.Builder
Section titled “Sheetsmith.Builder”| 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();