Как включить сортировку/фильтрацию столбцов XSSFTable с помощью Apache POI?

Я работаю над приложением, которое извлекает записи из базы данных и создает документ Excel из этих данных.

Документ Excel создается нормально, и все данные доступны для чтения; что касается предыдущего ответа с этого форума, таблица также сгенерирована соответствующим образом (строка заголовка остается видимой, даже когда я прокручивал ее, поэтому таблица определенно присутствует). Однако я ожидал, что когда у меня будет таблица, я смогу сортировать и фильтровать столбцы, как в случае «Вставить -> Таблица» в Excel, но при открытии документа таких опций нет.

Я не вижу setFitlerable или setSortable или что-то подобное в классах XSSFTable или XSSFTableColumn... Как включить сортировку/фильтрацию столбцов таблицы?

Ниже приведен код создания таблицы, если он полезен:

//Create table
CellReference topLeft = new CellReference(sheet.getRow(3).getCell(0));
CellReference bottomRight = new CellReference(sheet.getRow(nextRow-1).getCell(3));
AreaReference tableArea = workbook.getCreationHelper().createAreaReference(topLeft, bottomRight);
XSSFTable dataTable = sheet.createTable(tableArea);

dataTable.setName("TableData" + EXCEL_OBJECT_NUMBER);
dataTable.setDisplayName("TableData" + EXCEL_OBJECT_NUMBER);

XSSFTableColumn column = dataTable.getColumns().get(0);
column.setId(1);
column.setName("COLUMN1");

column = dataTable.getColumns().get(1);
column.setId(2);
column.setName("COLUMN2");

column = dataTable.getColumns().get(2);
column.setId(3);
column.setName("COLUMN3");

column = dataTable.getColumns().get(3);
column.setId(4);
column.setName("COLUMN4");

person Wickerbough    schedule 20.04.2020    source источник
comment
Я почувствовал этот дополнительный вопрос. Так что все уже было в моем полном примере кода в stackoverflow.com/questions/61315130/.   -  person Axel Richter    schedule 20.04.2020


Ответы (1)


Если dataTable является XSSFTable, а tableArea является AreaReference этого XSSFTable, то следующий код устанавливает автоматические фильтры в заголовки таблицы, поскольку Excel также делает это:

dataTable.getCTTable().addNewAutoFilter().setRef(tableArea.formatAsString());

Полный пример:

import java.io.FileOutputStream;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;

import java.util.GregorianCalendar;

class CreateExcelTable {

 public static void main(String[] args) throws Exception {

  Object[][] data = new Object[][] {
   new Object[] {"Text", "Date", "Number", "Boolean"},
   new Object[] {"Text 1", new GregorianCalendar(2020, 0, 1), 1234d, true},
   new Object[] {"Text 2", new GregorianCalendar(2020, 1, 15), 5678d, true},
   new Object[] {"Text 3", new GregorianCalendar(2020, 2, 1), 90.1234, false},
   new Object[] {"Text 4", new GregorianCalendar(2020, 3, 15), 567.89, false}
  };

  try (XSSFWorkbook workbook = new XSSFWorkbook();
       FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {

   XSSFCellStyle dateCellStyle = workbook.createCellStyle();
   dateCellStyle.setDataFormat(14);

   XSSFSheet sheet = workbook.createSheet();
   XSSFRow row = sheet.createRow(0);
   XSSFCell cell = row.createCell(0);
   cell.setCellValue("Lorem ipsum");
   row = sheet.createRow(1);
   cell = row.createCell(0);
   cell.setCellValue("semit dolor");

   int nextRow = 3;
   int nextCol = 0;
   for (Object[] dataRow : data) {
    row = sheet.createRow(nextRow++);
    nextCol = 0;
    for (Object value : dataRow) {
     cell = row.createCell(nextCol++);
     if (value instanceof String) cell.setCellValue((String)value);
     else if (value instanceof GregorianCalendar) {
      cell.setCellValue((GregorianCalendar)value);
      cell.setCellStyle(dateCellStyle);
     }
     else if (value instanceof Double) cell.setCellValue((Double)value);
     else if (value instanceof Boolean) cell.setCellValue((Boolean)value);
    }
   }

   CellReference topLeft = new CellReference(sheet.getRow(3).getCell(0));
   CellReference bottomRight = new CellReference(sheet.getRow(nextRow-1).getCell(3));
   AreaReference tableArea = workbook.getCreationHelper().createAreaReference(topLeft, bottomRight);
   XSSFTable dataTable = sheet.createTable(tableArea);
   //dataTable.setName("Table1");
   dataTable.setDisplayName("Table1");

   //this styles the table as Excel would do per default
   dataTable.getCTTable().addNewTableStyleInfo();
   XSSFTableStyleInfo style = (XSSFTableStyleInfo)dataTable.getStyle();
   style.setName("TableStyleMedium2");
   style.setShowColumnStripes(false);
   style.setShowRowStripes(true);

   //this sets auto filters
   dataTable.getCTTable().addNewAutoFilter().setRef(tableArea.formatAsString());

   workbook.write(fileout);
  }

 }
}
person Axel Richter    schedule 20.04.2020