Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add table heading drop-down with Apache Poi

I'm generating Excel tables with Apache POI, but my generated tables lack the drop-down menu on each header that appear when I "format as table" in Excel itself.

I'd like to generate this:

Table with menu button

But instead I get this:

Table without menu button

I'm following this blog post, and my code looks like this:

        XSSFTable table = sheet.createTable();
        table.setDisplayName("Data");
        CTTable ctTable = table.getCTTable();
        ctTable.setDisplayName("Data");
        ctTable.setId(1L);
        ctTable.setName("DATA");
        CTTableStyleInfo table_style = ctTable.addNewTableStyleInfo();
        table_style.setName("TableStyleMedium9");
        table_style.setShowColumnStripes(false);
        table_style.setShowRowStripes(true);

Each column is then created like this:

            CTTableColumn column = ctColumns.addNewTableColumn();
            column.setName(headers.get(i));
            column.setId(i + 1);

What am I missing?

like image 406
Adrian Cox Avatar asked Feb 09 '15 21:02

Adrian Cox


People also ask

How do I create a drop down list in Excel using Apache POI?

The dependency of dropdown lists must be managed in Excel s GUI where the generated file is running in. Apache poi only can create the Excel file so that this is possible then. One approach is using named ranges for the data validation lists who's names are then got using INDIRECT .

How do I use XSSFWorkbook?

XSSFWorkbook(java.io.InputStream is) Constructs an XSSFWorkbook object, by buffering the whole input stream into memory and then opening an OPCPackage object for it.

What is XSSF and HSSF?

Overview. HSSF is the POI Project's pure Java implementation of the Excel '97(-2007) file format. XSSF is the POI Project's pure Java implementation of the Excel 2007 OOXML (. xlsx) file format. HSSF and XSSF provides ways to read spreadsheets create, modify, read and write XLS spreadsheets.


1 Answers

Thanks to Alan Hay for the clue - the solution is to add an auto-filter, but this needs to be added as a CTAutoFilter for each individual column of the CTTable. The working solution looks like this:

    CTTableColumns ctColumns = ctTable.addNewTableColumns();
    CTAutoFilter autofilter = ctTable.addNewAutoFilter();
    ctColumns.setCount(table_headers.size());

    for(int i = 0; i < table_headers.size(); i++) {
        CTTableColumn column = ctColumns.addNewTableColumn();
        column.setName(table_headers.get(i));
        column.setId(i + 1);
        CTFilterColumn filter = autofilter.addNewFilterColumn();
        filter.setColId(i + 1);
        filter.setShowButton(true);
    }

When auto-sizing columns, it's also necessary to add extra width for the drop down menu:

    for(int i = 0; i < table_headers.size(); i++) {
        sheet.autoSizeColumn(i);
        // Include width of drop down button
        sheet.setColumnWidth(i, sheet.getColumnWidth(i) + 1000);
    }
like image 196
Adrian Cox Avatar answered Sep 22 '22 07:09

Adrian Cox