Pivot Tables
Axyra Sheets does not merely preserve pivot tables through a round trip — it computes them. The engine holds the pivot cache, applies the field layout, filters, groupings, and calculated fields, and writes the resulting grid into the sheet.
Creating a pivot table
int index = sheet.addPivotTable("SalesPivot", "H1", "Data!A1:E500");
PivotTableView pivot = sheet.pivotTable("SalesPivot");
addPivotTable(name, location, sourceRef) takes the output anchor and the source
range. sheet.pivotTable(name) or pivotTable(index) returns a live
PivotTableView — a view onto the model, so every call reads or writes the
actual pivot table.
Fields
pivot.sourceFields(); // what the cache offers
pivot.addRowField("Region");
pivot.addRowField("Product"); // nested, in order added
pivot.addColumnField("Quarter");
pivot.addDataField("Amount", AggregateFunction.SUM);
pivot.addDataField("Amount", AggregateFunction.AVERAGE, "Avg Amount");
pivot.addFilterField("Channel");
pivot.addPageField("Year");
pivot.refresh();
The pivot’s cells are written by refresh(). It recomputes the pivot from
the cache and writes the grid; it returns the number of cells written. Batch your
layout changes and refresh once. Saving and rendering refresh the pivot for you,
but until then its cells are empty, so call refresh() before reading them in
code. (0.1.0 builds did not refresh on save or render: call refresh() before
either there.)
addPageField is an alias of addFilterField (the OOXML name for a report
filter).
Fields are positional. removeRowField(position), removeDataField(position),
and moveRowField(from, to) work on the 0-based position within that axis, not
on the source field name — which matters when the same source field is used
twice, as Amount is above.
AggregateFunction covers SUM, COUNT, AVERAGE, MAX, MIN, PRODUCT,
COUNT_NUMS, STD_DEV, STD_DEVP, VAR, and VARP.
Filters
Four kinds, matching Excel’s own distinctions:
// Explicit item selection
pivot.setItemFilter("Region", "APAC", "EMEA");
// A single item on a page/report filter
pivot.setPageFilter("Year", "2026");
// Label filters — on the field's own labels
pivot.setLabelFilter("Product", PivotLabelFilterType.BEGINS_WITH, "Wid");
// Value filters — on an aggregated data field
pivot.setValueFilterBetween("Region", 0, 1000.0, 50000.0);
pivot.setTopNFilter("Region", 0, 5, false); // top 5 by data field 0
The dataField argument on value and top-N filters is the 0-based position of
the data field the filter is measured against. Each has a matching
clearLabelFilter / clearValueFilter / clearTopNFilter and a getter that
returns the current filter, or null.
Sorting
pivot.sortField("Region", true); // alphabetical
pivot.sortFieldByValue("Region", false, 0); // by data field 0, descending
pivot.clearFieldSort("Region");
Grouping
pivot.groupFieldByDate("OrderDate", PivotDateGroupBy.MONTHS);
pivot.groupFieldByDate("OrderDate",
PivotDateGroupBy.YEARS, PivotDateGroupBy.QUARTERS, PivotDateGroupBy.MONTHS);
pivot.groupFieldNumeric("Amount", 0, 10000, 1000); // start, end, interval
pivot.ungroupField("Amount");
Multi-component date grouping creates one grouped field per component, which is how Excel presents a Year → Quarter → Month hierarchy.
Show values as
Recasting a data field as a percentage, a running total, a rank, or a difference:
pivot.setShowDataAs(0, PivotShowDataAsType.PERCENT_OF_TOTAL);
pivot.setShowDataAs(0, PivotShowDataAsType.RUNNING_TOTAL);
pivot.clearShowDataAs(0);
The argument is the data field’s position. The engine computes these itself, including the multi-level running totals and ranks that depend on the row hierarchy.
Calculated fields and items
pivot.addCalculatedField("Margin", "Revenue - Cost");
pivot.addCalculatedItem("Region", "Americas", "'North' + 'South'");
pivot.calculatedFields();
pivot.calculatedItems();
A calculated field is a formula over other fields, evaluated per cell. A calculated item is a formula over other items within one field.
Layout and style
pivot.setStyle("PivotStyleMedium9");
pivot.setStyle(PivotStyle.of("PivotStyleMedium9").withRowStripes());
PivotLayout layout = ...; // compact / outline / tabular, subtotals, grand totals
Slicers and timelines
Slicers and timelines are workbook-level objects that filter one or more pivot tables:
wb.addSlicer("RegionSlicer", "Region", "SalesPivot",
0, 0, 8, 8, 14); // sheet, from row/column, to row/column
wb.setSlicerSelection("RegionSlicer", "APAC", "EMEA");
wb.setSlicerStyle("RegionSlicer", "SlicerStyleLight2");
String[] selected = wb.slicerSelection("RegionSlicer");
wb.addTimeline("DateTimeline", "SalesPivot", "OrderDate");
LocalDate[] range = wb.timelineRange("DateTimeline");
Changing a slicer selection changes the pivot table’s filter state; refresh the pivot to see it in the grid.
Pivot charts
A chart whose source is a pivot table follows the pivot’s filters. Build the chart against the pivot’s output range and add it as usual — see Charts.