Setting filter on headers of an Excel sheet via POI

ExcelApache PoiAutofilter

Excel Problem Overview


I generate a sheet, pretty bog standard headers and columns of data.

I want to turn on the "Filter" function for the sheet, so the user can easily sort and filter the data.

Can I so this using POI?

Excel Solutions


Solution 1 - Excel

Save the first and last cell from filter area, and execute:

sheet.setAutoFilter(new CellRangeAddress(firstCell.getRow(), lastCell.getRow(), firstCell.getCol(), lastCell.getCol()));

For example, from the below sheet.

>x         (x, y)
  0123456  
0|--hhh--|   h = header
1|--+++--|   + = values
2|--+++--|   - = empty fields
3|--+++--|
4|-------|

first cell will be the header above the first + (2,1) cell. The last will be the last + cell (5,3)

Solution 2 - Excel

easiest way of adding filter on header :

sheet.setAutoFilter(new CellRangeAddress(0, 0, 0, numColumns));
sheet.createFreezePane(0, 1);

Solution 3 - Excel

If you also want to set a filter programmatically, you could use the following:

void setAutoFilter(final XSSFSheet sheet, final int column, final String value) {
	sheet.setAutoFilter(CellRangeAddress.valueOf("A1:Z1"));
	
	final CTAutoFilter sheetFilter = sheet.getCTWorksheet().getAutoFilter();
	final CTFilterColumn filterColumn = sheetFilter.addNewFilterColumn();
	filterColumn.setColId(column);
	final CTFilter filter = filterColumn.addNewFilters().insertNewFilter(0);
	filter.setVal(value);

    // We have to apply the filter ourselves by hiding the rows: 
	for (final Row row : sheet) {
		for (final Cell c : row) {
			if (c.getColumnIndex() == column && !c.getStringCellValue().equals(value)) {
				final XSSFRow r1 = (XSSFRow) c.getRow();
				if (r1.getRowNum() != 0) { // skip header
					r1.getCTRow().setHidden(true);
				}
			}
		}
	}
}

Relevant Gradle dependencies:

	// https://mvnrepository.com/artifact/org.apache.poi/poi
compile group: 'org.apache.poi', name: 'poi', version: '3.9'

// https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml
compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.9'

// https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas
compile group: 'org.apache.poi', name: 'poi-ooxml-schemas', version: '3.9'

// https://mvnrepository.com/artifact/org.apache.poi/ooxml-schemas
compile group: 'org.apache.poi', name: 'ooxml-schemas', version: '1.3'

Solution 4 - Excel

I figured out how to do this with NPOI.
You add a CT_AutoFilter to the CT_Table.

I am guessing the it works the same for POI as NPOI.

    cttable.autoFilter = new CT_AutoFilter();
    cttable.autoFilter.@ref = "A1:C5";   // value is data and includes header.

Solution 5 - Excel

Use sheet.setAutoFilter(CellRangeAddress.valueOf("B1:H1"));

We have to specify only the header cells of the tabular data. Here in my example header starts from cell B1 and ends at cell H1.
Excel will automatically find the data below it and show it in the filter options.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnders JohansenView Question on Stackoverflow
Solution 1 - ExcelVictorView Answer on Stackoverflow
Solution 2 - ExcelTiago MediciView Answer on Stackoverflow
Solution 3 - ExcelDennieView Answer on Stackoverflow
Solution 4 - ExcelMark HoldenView Answer on Stackoverflow
Solution 5 - ExcelSyam Kumar SView Answer on Stackoverflow