I'm trying to create an Excel Pivot with apache poi, but I dont really understand how to create the format that I want. I use this code to create, but I get empty values:
XSSFPivotTable pivotTable = sheet.createPivotTable(aref, pos);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 2, colNames[2]);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 3, colNames[3]);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 0, colNames[0]);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1, colNames[1]);
My data looks like this:
and I want it to look like this:
How do I achieve that?
Apache poi
has only rudimentary support for creating pivot tables. It only creates default pivot tables but is not able creating special settings without falling back to the underlying ooxml-schemas
classes.
For your data source the following code creates what apache poi
supports by default:
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);
}
}
}
This creates a pivot table in outline format, which is the default.
If you wants creating a pivot table which is not in outline format and is not showing subtotals for each field, we need using the underlying ooxml-schemas
classes. We need creating the correct pivot table field items. And we need to build a cache definition which has shared elements for those items. See also Apache POI XSSFPivotTable setDefaultSubtotal .
The following code should create the pivot table you wants from your data source:
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);
}
}
}
This code is tested using current apache poi 4.1.2
and needs the full jar of all of the schemas ooxml-schemas-1.4.jar
(lower versions for older releases) as mentioned in apache poi FAQ-N10025 .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.