Skip to content

Exporting Multiple Header Rows #146

@brunoagretti

Description

@brunoagretti

Describe the bug

When exporting a grid that contains multiple header rows, the exporter only takes the last header row into account and omits the previous ones. This affects the correct representation of headers in the exported file.

Grid with multiple header rows:
image

Exported .xlsx file:
image

Expected behavior

The exporter should be able to handle multiple header rows, exporting all of them instead of just the last one. I assume the same issue might occur with footer rows.

Minimal reproducible example

public class GridExporterMultipleHeaderRowsDemo extends Div {

  public GridExporterMultipleHeaderRowsDemo() throws EncryptedDocumentException, IOException {
    Grid<Person> grid = new Grid<>(Person.class);
    DecimalFormat decimalFormat = new DecimalFormat("$#,###.##");
    grid.removeAllColumns();
    grid.addColumn(
            LitRenderer.<Person>of("<b>${item.name}</b>").withProperty("name", Person::getName))
        .setHeader("Name");
    grid.addColumn("lastName").setHeader("Last Name");
    grid.addColumn(item -> Faker.instance().lorem().characters(30, 50)).setHeader("Big column");
    Column<Person> budgetColumn =
        grid.addColumn(item -> decimalFormat.format(item.getBudget()))
            .setHeader("Budget")
            .setTextAlign(ColumnTextAlign.END);
    BigDecimal[] total = new BigDecimal[1];
    total[0] = BigDecimal.ZERO;
    Stream<Person> stream =
        IntStream.range(0, 100)
            .asLongStream()
            .mapToObj(
                number -> {
                  Faker faker = new Faker();
                  Double budget = faker.number().randomDouble(2, 10000, 100000);
                  total[0] = total[0].add(BigDecimal.valueOf(budget));
                  budgetColumn.setFooter(new DecimalFormat("$#,###.##").format(total[0]));
                  return new Person(
                      faker.name().firstName(),
                      (Math.random() > 0.3 ? faker.name().lastName() : null),
                      faker.number().numberBetween(15, 50),
                      budget);
                });
    
    grid.setItems(DataProvider.fromStream(stream));
    grid.setWidthFull();
    this.setSizeFull();
    
	HeaderRow firstExtraHeaderRow = grid.appendHeaderRow();
	HeaderRow secondExtraHeaderRow = grid.appendHeaderRow();
	for (Column<Person> column : grid.getColumns()) {
		String columnHeader = grid.getHeaderRows().get(0).getCell(column).getText();
		
		HeaderCell firstHeaderCell = firstExtraHeaderRow.getCell(column);
		firstHeaderCell.setComponent(new Span(columnHeader + " 1"));
		HeaderCell secondHeaderCell = secondExtraHeaderRow.getCell(column);
		secondHeaderCell.setComponent(new Span(columnHeader + " 2"));
	}

    GridExporter<Person> exporter =
        GridExporter.createFor(grid, "/custom-template.xlsx", "/custom-template.docx");
    HashMap<String, String> placeholders = new HashMap<>();
    placeholders.put("${date}", new SimpleDateFormat().format(Calendar.getInstance().getTime()));
    exporter.setAdditionalPlaceHolders(placeholders);
    exporter.setSheetNumber(1);
    exporter.setCsvExportEnabled(false);
    exporter.setNumberColumnFormat(budgetColumn, decimalFormat, "$#,###.##");
    exporter.setTitle("People information");
    exporter.setNullValueHandler(() -> "(No lastname)");
    exporter.setFileName(
        "GridExport" + new SimpleDateFormat("yyyyddMM").format(Calendar.getInstance().getTime()));
    add(grid);
  }
}

Add-on Version

1.9.2-SNAPSHOT

Vaadin Version

23.3.15

Additional information

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions