После создания сводной таблицы Excel через Apache POI я хотел бы получить доступ к определенному определению сводного поля, чтобы получить его явный список элементов. Вместо «Выбрать все», активированного по умолчанию, я хотел бы выбрать/удалить некоторые элементы из этого списка программно.
Есть ли решение сделать это правильно на Java с библиотекой Apache POI? Я также открыт для альтернативных решений, таких как использование функций Aspose.
Поскольку я не нашел никакого решения для получения явных элементов, вот мое обходное решение для выбора явных элементов из известного списка, которому помогает следующая тема: Как установить множественное значение по умолчанию в фильтре отчета сводной таблицы Apache POI
Это просто состоит в добавлении фиктивного элемента и его последующем удалении.
public void setPivotFieldDataFilterPositive(String sheetName, String pivotName, String fieldName, List filterValuesList) {
XSSFPivotTable pivotTable = getPivotTable(sheetName, pivotName);
int fieldIndex = table.findColumnIndex(fieldName);
List<CTPivotField> pivotFieldsList = pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldList();
CTPivotField ctPivotField = pivotFieldsList.get(fieldIndex);
for (int i = 0; i < filterValuesList.size(); i++) {
//take the first 4 items as numbered items: <item x = "0"/><item x = "1"/><item x = "2"/><item x = "3"/>
ctPivotField.getItems().getItemArray(i).unsetT();
ctPivotField.getItems().getItemArray(i).setX((long)i);
//build a cache definition which has shared elements for those items
//<sharedItems><s v = "City 1"/><s v = "City 2"/><s v = "City 3"/><s v = "City 4"/></sharedItems>
pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(fieldIndex).getSharedItems().addNewS().setV(filterValuesList.get(i));
}
System.out.println("count : "+pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(fieldIndex).getSharedItems().sizeOfSArray());
ctPivotField.setMultipleItemSelectionAllowed(true);
//additional dummy element to hide it afterwards
ctPivotField.getItems().getItemArray(filterValuesList.size()).unsetT();
ctPivotField.getItems().getItemArray(filterValuesList.size()).setX((long)filterValuesList.size());
pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(fieldIndex).getSharedItems().addNewS().setV(null);//item with empty name
//hide dummy element
ctPivotField.getItems().getItemArray(filterValuesList.size()).setH(true);//item hidden but an empty item still visible on the list
//ctPivotField.getItems().removeItem(filterValuesList.size()); //does not keep the filtering
}
Это работает, но это сумасшедший способ сделать это, и я хотел бы избежать слишком большого изменения базовой структуры XML.
Для этой задачи вы можете использовать Aspose.Cells for Java. Вы можете использовать соответствующие API-интерфейсы для получения элементов сводного поля, вы можете соответственно выбирать и удалять несколько элементов. См. следующий пример для справки.
например
Образец кода:
Workbook wb_demo = new Workbook("f:\\files\\Book1.xlsx");
PivotTable pt_demo = wb_demo.getWorksheets().get(0).getPivotTables().get(0);
//Get the first Pivot column field
PivotField src_t_field = pt_demo.getColumnFields().get(0);
src_t_field.setMultipleItemSelectionAllowed(true);
System.out.println(src_t_field.getName());
System.out.println("Total Items: " + src_t_field.getItems().length);
System.out.println("Total Items: " + src_t_field.getPivotItems().getCount());
PivotItemCollection collection_src_t = src_t_field.getPivotItems();
System.out.println(collection_src_t.getCount());
for (int i = 0; i < collection_src_t.getCount(); i++)
{
PivotItem item = collection_src_t.get(i);
System.out.println(item.getName());
if (item.getName().equals("0.5 kg"))
{
item.setHidden(true);
}
else if (item.getName().equals("1 kg"))
{
item.setHidden(false);
}
else if (item.getName().equals("1.5 kg"))
{
item.setHidden(true);
}
else if (item.getName().equals("2.5 kg"))
{
item.setHidden(false);
}
else if (item.getName().equals("3 kg"))
{
item.setHidden(true);
}
else if (item.getName().equals("6.5 kg"))
{
item.setHidden(false);
}
}
pt_demo.calculateData();
wb_demo.save("f:\\files\\out1.xlsx");
PS. Я работаю разработчиком поддержки / евангелистом в Aspose.
Ваше решение Aspose протестировано и работает должным образом, спасибо. Я принимаю это, поскольку на данный момент решение Apache POI не предлагается.