Is there a way to get the column header value in a grid from the column obj

I know we can set column.key(x) (or grid.addColumn().setKey(x)) but is there a way to do something like:

grid.getColumns().stream()
	.filter(column -> column.getHeader())
	...

The reason being is that I’m trying to re-use the same table but based on a toggle a specific column could have it’s title changed based on that toggle.

I could not find any way to query the column header name.

There is indeed no such api. I tried writing a workaround right now but it seems that the HeaderCell class only has ways to set its content (String or Component) but no way to ever read it again:

// HeaderRow.HeaderCell class
public static class HeaderCell extends AbstractCell {
	HeaderCell(AbstractColumn<?> column) {
		super(column);
		if (column.getHeaderRenderer() == null) {
			column.setHeaderText("");
		}
	}

	public void setText(String text) {
		this.getColumn().setHeaderText(text);
	}

	public void setComponent(Component component) {
		this.getColumn().setHeaderComponent(component);
	}
}

I think this is beacuse there is a Renderer being used in the header, and Renderers do not have an unrender() function, they are one-way. It seems that you will have to find another way. Maybe track the state of your toggle in a member variable as well, and then do this:

grid.getColumns().stream()
	.filter(column -> column.getKey().equals(FOO_COLUMN) && fooColumnIsToggled)
	...

Has the situation changed on this at all?

We’re trying to write a generalized “export” function, and in Vaadin 8 we could read the column headers to use those as the headers in the export file. Why can’t I do the same in Vaadin Flow?

No, there have been no changes on this. But you could simply map each column key to the string you use for the header, so you wouldn’t read the header-string from the grid itself when making the export, but instead using the column key you get the header string from your own map.

Map<String, String> columnHeadersMap = new HashMap<>();
columnHeadersMap.put("name", "Nom"); // in case of I18N you could even `getTranslation("person.name")` instead of hardcoding the header string.
columnHeadersMap.put("gender", "Gent");

grid.addColumn(Person::getName);
grid.addColumn(Person::getGender);

....

private void export(){
	for(Grid.Column<Person> column : grid.getColumns()){
		String columnHeaderString = columnHeadersMap.get(column.getKey());
		...
	}
}

Thanks, but the whole point of using a framework is to write less code

Perhaps there is an internal technical reason that access to the headers cannot be provided, but if not this seems to be an artificial limitation that could easily be addressed with a few strategic getter methods.

There is a ticket about it. you can vote and add a comment in this ticket: https://github.com/vaadin/vaadin-grid-flow/issues/567

I think the change between Vaadin 8 and flow is that in flow you can add a text or a component.

In your case, getheader that returns a text can be workaround with Kaspar’s solution. it doesn’t add that much code.
But if you want to access to the header component to modify it then the workaround doesn’t help.