Apache poi
имеет только элементарную поддержку для создания сводных таблиц. Он только создает сводные таблицы по умолчанию, но не может создавать специальные параметры без возврата к базовым ooxml-schemas
классам.
Для вашего источника данных следующий код создает то, что apache poi
поддерживает по умолчанию:
import java.io.FileOutputStream;
import java.io.FileInputStream;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.*;
class CreatePivotTableDefault {
public static void main(String[] args) throws Exception {
try (XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("ExcelSource.xlsx"));
FileOutputStream fileout = new FileOutputStream("ExcelResult.xlsx") ) {
XSSFSheet dataSheet = workbook.getSheetAt(0);
XSSFSheet pivotSheet = workbook.createSheet("Pivot");
AreaReference areaReference = new AreaReference("A1:D5", SpreadsheetVersion.EXCEL2007);
XSSFPivotTable pivotTable = pivotSheet.createPivotTable(areaReference, new CellReference("A1"), dataSheet);
pivotTable.addRowLabel(2);
pivotTable.addRowLabel(3);
pivotTable.addRowLabel(0);
pivotTable.addRowLabel(1);
workbook.write(fileout);
}
}
}
Это создает сводную таблицу в формате структуры, которая является значением по умолчанию.
Если вы хотите создать сводную таблицу, которая не в формате структуры и не показывает промежуточные итоги для каждого поля, нам нужно использовать базовые ooxml-schemas
классы. Нам нужно создать правильные элементы поля сводной таблицы. И нам нужно создать определение кэша, в котором есть общие элементы для этих элементов. См. Также Apache POI XSSFPivotTable setDefaultSubtotal .
Следующий код должен создать сводную таблицу, которую вы хотите получить из своего источника данных:
import java.io.FileOutputStream;
import java.io.FileInputStream;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotField;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.usermodel.*;
class CreatePivotTable {
static void addRowLabel(XSSFPivotTable pivotTable, XSSFSheet dataSheet, AreaReference areaReference, int column) {
DataFormatter formatter = new DataFormatter(java.util.Locale.US);
//create row label - apache poi creates as much fields for each as rows are in the pivot table data range
pivotTable.addRowLabel(column);
//determine unique labels in column
java.util.TreeSet<String> uniqueItems = new java.util.TreeSet<String>();
for (int r = areaReference.getFirstCell().getRow()+1; r < areaReference.getLastCell().getRow()+1; r++) {
uniqueItems.add(formatter.formatCellValue(dataSheet.getRow(r).getCell(column)));
}
//System.out.println(uniqueItems);
//build pivot table and cache
CTPivotField ctPivotField = pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(column);
int i = 0;
for (String item : uniqueItems) {
//take the items as numbered items: <item x="0"/><item x="1"/>
ctPivotField.getItems().getItemArray(i).unsetT();
ctPivotField.getItems().getItemArray(i).setX((long)i);
//build a cache definition which has shared elements for those items
pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(column)
.getSharedItems().addNewS().setV(item);
i++;
}
//set pivot field settings
ctPivotField.setOutline(false); // no outline format
ctPivotField.setDefaultSubtotal(false); // no subtotals for this field
//remove further items
if (ctPivotField.getDefaultSubtotal()) i++; //let one default item be if there shall be subtotals
for (int k = ctPivotField.getItems().getItemList().size()-1; k >= i; k--) {
ctPivotField.getItems().removeItem(k);
}
ctPivotField.getItems().setCount(i);
}
public static void main(String[] args) throws Exception {
try (XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("ExcelSource.xlsx"));
FileOutputStream fileout = new FileOutputStream("ExcelResult.xlsx") ) {
XSSFSheet dataSheet = workbook.getSheetAt(0);
XSSFSheet pivotSheet = workbook.createSheet("Pivot");
AreaReference areaReference = new AreaReference("A1:D5", SpreadsheetVersion.EXCEL2007);
XSSFPivotTable pivotTable = pivotSheet.createPivotTable(areaReference, new CellReference("A1"), dataSheet);
addRowLabel(pivotTable, dataSheet, areaReference, 2);
addRowLabel(pivotTable, dataSheet, areaReference, 3);
addRowLabel(pivotTable, dataSheet, areaReference, 0);
addRowLabel(pivotTable, dataSheet, areaReference, 1);
workbook.write(fileout);
}
}
}
Этот код протестирован с использованием текущая apache poi 4.1.2
и требует полного jar всех схем ooxml-schemas-1.4.jar
(более низкие версии для более старых выпусков), как указано в apache poi FAQ-N10025 .