mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-09-19 14:36:48 +00:00
Add PivotTable samples
Adds runnable samples under samples/PivotTable demonstrating the pivot table feature, discovered automatically by the sample browser: - 01_Create_PivotTable: build a basic pivot (row/column/value fields) from a source range and save it as Xlsx. - 02_PivotTable_Page_Filter: add a page (report filter) field. - 03_PivotTable_Grouping: group a numeric field into ranges and a date field by quarter. - 04_Read_PivotTable: write a pivot, load it back, and inspect the pivot table object model (source, row/column/page fields, value aggregation). Directory is named PivotTable to match the PascalCase convention used by the other sample categories (Table, Chart, ...).
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PivotTable\PivotField;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PivotTable\PivotTableBuilder;
|
||||
|
||||
require __DIR__ . '/../Header.php';
|
||||
/** @var PhpOffice\PhpSpreadsheet\Helper\Sample $helper */
|
||||
|
||||
// Create new Spreadsheet object
|
||||
$helper->log('Create new Spreadsheet object');
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$spreadsheet->getProperties()
|
||||
->setCreator('PhpSpreadsheet')
|
||||
->setTitle('PhpSpreadsheet PivotTable Sample')
|
||||
->setCategory('PivotTable');
|
||||
|
||||
// Fill a worksheet with the source data for the pivot table.
|
||||
$helper->log('Add source data');
|
||||
$dataSheet = $spreadsheet->getActiveSheet();
|
||||
$dataSheet->setTitle('Data');
|
||||
$dataSheet->fromArray(
|
||||
[
|
||||
['Region', 'Product', 'Quarter', 'Amount'],
|
||||
['East', 'Widget', 'Q1', 100],
|
||||
['East', 'Gadget', 'Q1', 200],
|
||||
['West', 'Widget', 'Q1', 150],
|
||||
['West', 'Gadget', 'Q1', 250],
|
||||
['East', 'Widget', 'Q2', 120],
|
||||
['East', 'Gadget', 'Q2', 220],
|
||||
['West', 'Widget', 'Q2', 170],
|
||||
['West', 'Gadget', 'Q2', 270],
|
||||
],
|
||||
null,
|
||||
'A1'
|
||||
);
|
||||
|
||||
// Create a worksheet to hold the pivot table.
|
||||
$pivotSheet = $spreadsheet->createSheet();
|
||||
$pivotSheet->setTitle('PivotTable');
|
||||
|
||||
// Build a pivot table:
|
||||
// rows = Region
|
||||
// columns = Product
|
||||
// values = Sum of Amount
|
||||
$helper->log('Build pivot table');
|
||||
$builder = new PivotTableBuilder($dataSheet, 'A1:D9');
|
||||
$builder
|
||||
->addRowField('Region')
|
||||
->addColumnField('Product')
|
||||
->addDataField('Amount', PivotField::SUBTOTAL_SUM);
|
||||
|
||||
$pivotTable = $builder->build($pivotSheet, 'A3', 'SalesByRegion');
|
||||
|
||||
$helper->log('Pivot table "' . $pivotTable->getName() . '" created at ' . $pivotTable->getLocation());
|
||||
$helper->log(
|
||||
'The pivot table is written with refresh-on-load set, so the spreadsheet '
|
||||
. 'application fills in the summarised values when the file is opened.'
|
||||
);
|
||||
|
||||
// Pivot tables are an Xlsx feature.
|
||||
$helper->write($spreadsheet, __FILE__, ['Xlsx']);
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PivotTable\PivotField;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PivotTable\PivotTableBuilder;
|
||||
|
||||
require __DIR__ . '/../Header.php';
|
||||
/** @var PhpOffice\PhpSpreadsheet\Helper\Sample $helper */
|
||||
|
||||
$helper->log('Create new Spreadsheet object');
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$spreadsheet->getProperties()->setTitle('PhpSpreadsheet PivotTable Page Filter Sample');
|
||||
|
||||
$helper->log('Add source data');
|
||||
$dataSheet = $spreadsheet->getActiveSheet();
|
||||
$dataSheet->setTitle('Data');
|
||||
$dataSheet->fromArray(
|
||||
[
|
||||
['Region', 'Product', 'Quarter', 'Amount'],
|
||||
['East', 'Widget', 'Q1', 100],
|
||||
['East', 'Gadget', 'Q1', 200],
|
||||
['West', 'Widget', 'Q1', 150],
|
||||
['West', 'Gadget', 'Q1', 250],
|
||||
['East', 'Widget', 'Q2', 120],
|
||||
['East', 'Gadget', 'Q2', 220],
|
||||
['West', 'Widget', 'Q2', 170],
|
||||
['West', 'Gadget', 'Q2', 270],
|
||||
],
|
||||
null,
|
||||
'A1'
|
||||
);
|
||||
|
||||
$pivotSheet = $spreadsheet->createSheet();
|
||||
$pivotSheet->setTitle('PivotTable');
|
||||
|
||||
// The Quarter field is placed on the page axis, becoming a report filter that
|
||||
// the user can switch between "(All)", "Q1" and "Q2" in the spreadsheet app.
|
||||
$helper->log('Build pivot table with a page (report filter) field');
|
||||
$builder = new PivotTableBuilder($dataSheet, 'A1:D9');
|
||||
$builder
|
||||
->addPageField('Quarter')
|
||||
->addRowField('Region')
|
||||
->addColumnField('Product')
|
||||
->addDataField('Amount', PivotField::SUBTOTAL_SUM);
|
||||
|
||||
$pivotTable = $builder->build($pivotSheet, 'A4', 'SalesFilteredByQuarter');
|
||||
|
||||
$helper->log('Page fields: ' . implode(', ', array_map(
|
||||
static fn ($field) => $field->getName(),
|
||||
$pivotTable->getPageFields()
|
||||
)));
|
||||
|
||||
$helper->write($spreadsheet, __FILE__, ['Xlsx']);
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PivotTable\PivotField;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PivotTable\PivotFieldGroup;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PivotTable\PivotTableBuilder;
|
||||
|
||||
require __DIR__ . '/../Header.php';
|
||||
/** @var PhpOffice\PhpSpreadsheet\Helper\Sample $helper */
|
||||
|
||||
$helper->log('Create new Spreadsheet object');
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$spreadsheet->getProperties()->setTitle('PhpSpreadsheet PivotTable Grouping Sample');
|
||||
|
||||
$helper->log('Add source data');
|
||||
$dataSheet = $spreadsheet->getActiveSheet();
|
||||
$dataSheet->setTitle('Data');
|
||||
$dataSheet->fromArray(
|
||||
[
|
||||
['Customer', 'Age', 'OrderDate', 'Amount'],
|
||||
['Alice', 23, '2024-01-15', 100],
|
||||
['Bob', 37, '2024-06-20', 150],
|
||||
['Carol', 45, '2025-02-10', 200],
|
||||
['Dan', 51, '2025-11-05', 250],
|
||||
['Erin', 29, '2024-09-01', 175],
|
||||
['Frank', 62, '2025-07-22', 300],
|
||||
],
|
||||
null,
|
||||
'A1'
|
||||
);
|
||||
|
||||
// --- Numeric range grouping: bucket Age into bands of 10 (20-30, 30-40, ...) ---
|
||||
$helper->log('Build pivot table grouping Age into numeric ranges');
|
||||
$agePivotSheet = $spreadsheet->createSheet();
|
||||
$agePivotSheet->setTitle('ByAgeRange');
|
||||
|
||||
$ageBuilder = new PivotTableBuilder($dataSheet, 'A1:D7');
|
||||
$ageBuilder
|
||||
->groupFieldByNumericRange('Age', 10, 20, 70)
|
||||
->addRowField('Age')
|
||||
->addDataField('Amount', PivotField::SUBTOTAL_SUM);
|
||||
$ageBuilder->build($agePivotSheet, 'A3', 'SalesByAgeRange');
|
||||
|
||||
// --- Date grouping: group OrderDate by quarter ---
|
||||
$helper->log('Build pivot table grouping OrderDate by quarter');
|
||||
$datePivotSheet = $spreadsheet->createSheet();
|
||||
$datePivotSheet->setTitle('ByQuarter');
|
||||
|
||||
$dateBuilder = new PivotTableBuilder($dataSheet, 'A1:D7');
|
||||
$dateBuilder
|
||||
->groupFieldByDate('OrderDate', PivotFieldGroup::GROUP_BY_QUARTERS)
|
||||
->addRowField('OrderDate')
|
||||
->addDataField('Amount', PivotField::SUBTOTAL_SUM);
|
||||
$dateBuilder->build($datePivotSheet, 'A3', 'SalesByQuarter');
|
||||
|
||||
$helper->log(
|
||||
'Grouping is written into the pivot cache; the spreadsheet application '
|
||||
. 'materialises the buckets when it refreshes the pivot on open.'
|
||||
);
|
||||
|
||||
$helper->write($spreadsheet, __FILE__, ['Xlsx']);
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PivotTable\PivotField;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PivotTable\PivotTableBuilder;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
|
||||
|
||||
require __DIR__ . '/../Header.php';
|
||||
/** @var PhpOffice\PhpSpreadsheet\Helper\Sample $helper */
|
||||
|
||||
// First build a small workbook that contains a pivot table, so this sample is
|
||||
// self-contained. (In practice you would just load an existing .xlsx file.)
|
||||
$helper->log('Create a workbook containing a pivot table');
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$dataSheet = $spreadsheet->getActiveSheet();
|
||||
$dataSheet->setTitle('Data');
|
||||
$dataSheet->fromArray(
|
||||
[
|
||||
['Region', 'Product', 'Amount'],
|
||||
['East', 'Widget', 100],
|
||||
['West', 'Widget', 150],
|
||||
['East', 'Gadget', 200],
|
||||
['West', 'Gadget', 250],
|
||||
],
|
||||
null,
|
||||
'A1'
|
||||
);
|
||||
$pivotSheet = $spreadsheet->createSheet();
|
||||
$pivotSheet->setTitle('PivotTable');
|
||||
|
||||
$builder = new PivotTableBuilder($dataSheet, 'A1:C5');
|
||||
$builder
|
||||
->addRowField('Region')
|
||||
->addColumnField('Product')
|
||||
->addDataField('Amount', PivotField::SUBTOTAL_SUM);
|
||||
$builder->build($pivotSheet, 'A3', 'SalesByRegion');
|
||||
|
||||
$tempFile = $helper->getTemporaryFilename('xlsx');
|
||||
(new XlsxWriter($spreadsheet))->save($tempFile);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
|
||||
// Now read the file back and inspect its pivot tables.
|
||||
$helper->log('Load the workbook and inspect its pivot tables');
|
||||
$loaded = (new XlsxReader())->load($tempFile);
|
||||
|
||||
foreach ($loaded->getWorksheetIterator() as $worksheet) {
|
||||
foreach ($worksheet->getPivotTableCollection() as $pivotTable) {
|
||||
$helper->log(sprintf(
|
||||
'Pivot table "%s" on sheet "%s" at %s',
|
||||
$pivotTable->getName(),
|
||||
$worksheet->getTitle(),
|
||||
$pivotTable->getLocation()
|
||||
));
|
||||
|
||||
$cache = $pivotTable->getCacheDefinition();
|
||||
if ($cache !== null) {
|
||||
$helper->log(sprintf(
|
||||
' Source: %s!%s',
|
||||
(string) $cache->getSourceWorksheet(),
|
||||
(string) $cache->getSourceRange()
|
||||
));
|
||||
}
|
||||
|
||||
$helper->log(' Row fields: ' . implode(', ', names($pivotTable->getRowFields())));
|
||||
$helper->log(' Column fields: ' . implode(', ', names($pivotTable->getColumnFields())));
|
||||
$helper->log(' Page fields: ' . implode(', ', names($pivotTable->getPageFields())));
|
||||
|
||||
foreach ($pivotTable->getDataFields() as $dataField) {
|
||||
$helper->log(sprintf(
|
||||
' Value field: %s (%s)',
|
||||
$dataField->getName(),
|
||||
(string) $dataField->getSubtotal()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$loaded->disconnectWorksheets();
|
||||
@unlink($tempFile);
|
||||
|
||||
/**
|
||||
* @param PivotField[] $fields
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
function names(array $fields): array
|
||||
{
|
||||
return array_map(static fn (PivotField $field): string => $field->getName(), $fields);
|
||||
}
|
||||
Reference in New Issue
Block a user