Skip to content

Commit 92a50d1

Browse files
committed
Format as Table for Xlsx
Initial implementation of Excel's tables feature (i.e. Select Home > Format as Table in Excel App). Tables are similar to AutoFilter but tables have other advantages like named ranges, easy formatting, totals row and header row with filter. Tables can also be converted to charts and pivot tables easily. Usage: $table = new Table(); $table->setName('Sales_Data'); $table->setRange('A1:D17'); $spreadsheet->getActiveSheet()->addTable($table); In this Commit: - Added Table API with initial support for header and totals row. - Added complete styling options for Table. - Added Xlsx Writer for Table. - Added samples. - Covered with unit tests. To be done: - Filter expressions similar to AutoFilter. - Precalucate formulas for totals row (Check sample 2). - Table named ranges in formulas and calculation.
1 parent 1801f58 commit 92a50d1

File tree

16 files changed

+1877
-3
lines changed

16 files changed

+1877
-3
lines changed

phpstan-baseline.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5527,7 +5527,7 @@ parameters:
55275527

55285528
-
55295529
message: "#^Parameter \\#2 \\$id of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeRelationship\\(\\) expects int, string given\\.$#"
5530-
count: 4
5530+
count: 5
55315531
path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php
55325532

55335533
-

samples/Table/01_Table.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
4+
use PhpOffice\PhpSpreadsheet\Worksheet\Table;
5+
use PhpOffice\PhpSpreadsheet\Worksheet\Table\TableStyle;
6+
7+
require __DIR__ . '/../Header.php';
8+
9+
// Create new Spreadsheet object
10+
$helper->log('Create new Spreadsheet object');
11+
$spreadsheet = new Spreadsheet();
12+
13+
// Set document properties
14+
$helper->log('Set document properties');
15+
$spreadsheet->getProperties()->setCreator('aswinkumar863')
16+
->setLastModifiedBy('aswinkumar863')
17+
->setTitle('PhpSpreadsheet Table Test Document')
18+
->setSubject('PhpSpreadsheet Table Test Document')
19+
->setDescription('Test document for PhpSpreadsheet, generated using PHP classes.')
20+
->setKeywords('office PhpSpreadsheet php')
21+
->setCategory('Table');
22+
23+
// Create the worksheet
24+
$helper->log('Add data');
25+
26+
$spreadsheet->setActiveSheetIndex(0);
27+
$spreadsheet->getActiveSheet()->setCellValue('A1', 'Year')
28+
->setCellValue('B1', 'Quarter')
29+
->setCellValue('C1', 'Country')
30+
->setCellValue('D1', 'Sales');
31+
32+
$dataArray = [
33+
['2010', 'Q1', 'United States', 790],
34+
['2010', 'Q2', 'United States', 730],
35+
['2010', 'Q3', 'United States', 860],
36+
['2010', 'Q4', 'United States', 850],
37+
['2011', 'Q1', 'United States', 800],
38+
['2011', 'Q2', 'United States', 700],
39+
['2011', 'Q3', 'United States', 900],
40+
['2011', 'Q4', 'United States', 950],
41+
['2010', 'Q1', 'Belgium', 380],
42+
['2010', 'Q2', 'Belgium', 390],
43+
['2010', 'Q3', 'Belgium', 420],
44+
['2010', 'Q4', 'Belgium', 460],
45+
['2011', 'Q1', 'Belgium', 400],
46+
['2011', 'Q2', 'Belgium', 350],
47+
['2011', 'Q3', 'Belgium', 450],
48+
['2011', 'Q4', 'Belgium', 500],
49+
];
50+
51+
$spreadsheet->getActiveSheet()->fromArray($dataArray, null, 'A2');
52+
53+
// Create Table
54+
$helper->log('Create Table');
55+
$table = new Table();
56+
$table->setName('Sales Data');
57+
$table->setRange('A1:D17');
58+
59+
// Create Columns
60+
$table->getColumn('D')->setShowFilterButton(false);
61+
62+
// Create Table Style
63+
$helper->log('Create Table Style');
64+
$tableStyle = new TableStyle();
65+
$tableStyle->setTheme(TableStyle::TABLE_STYLE_MEDIUM2);
66+
$tableStyle->setShowRowStripes(true);
67+
$tableStyle->setShowColumnStripes(true);
68+
$tableStyle->setShowFirstColumn(true);
69+
$tableStyle->setShowLastColumn(true);
70+
$table->setStyle($tableStyle);
71+
72+
// Add Table to Worksheet
73+
$helper->log('Add Table to Worksheet');
74+
$spreadsheet->getActiveSheet()->addTable($table);
75+
76+
// Save
77+
$helper->write($spreadsheet, __FILE__, ['Xlsx']);

samples/Table/02_Table_Total.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
use PhpOffice\PhpSpreadsheet\IOFactory;
4+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
5+
use PhpOffice\PhpSpreadsheet\Worksheet\Table;
6+
7+
require __DIR__ . '/../Header.php';
8+
9+
// Create new Spreadsheet object
10+
$helper->log('Create new Spreadsheet object');
11+
$spreadsheet = new Spreadsheet();
12+
13+
// Set document properties
14+
$helper->log('Set document properties');
15+
$spreadsheet->getProperties()->setCreator('aswinkumar863')
16+
->setLastModifiedBy('aswinkumar863')
17+
->setTitle('PhpSpreadsheet Table Test Document')
18+
->setSubject('PhpSpreadsheet Table Test Document')
19+
->setDescription('Test document for PhpSpreadsheet, generated using PHP classes.')
20+
->setKeywords('office PhpSpreadsheet php')
21+
->setCategory('Table');
22+
23+
// Create the worksheet
24+
$helper->log('Add data');
25+
26+
$spreadsheet->setActiveSheetIndex(0);
27+
$spreadsheet->getActiveSheet()->setCellValue('A1', 'Year')
28+
->setCellValue('B1', 'Quarter')
29+
->setCellValue('C1', 'Country')
30+
->setCellValue('D1', 'Sales');
31+
32+
$dataArray = [
33+
['2010', 'Q1', 'United States', 790],
34+
['2010', 'Q2', 'United States', 730],
35+
['2010', 'Q3', 'United States', 860],
36+
['2010', 'Q4', 'United States', 850],
37+
['2011', 'Q1', 'United States', 800],
38+
['2011', 'Q2', 'United States', 700],
39+
['2011', 'Q3', 'United States', 900],
40+
['2011', 'Q4', 'United States', 950],
41+
['2010', 'Q1', 'Belgium', 380],
42+
['2010', 'Q2', 'Belgium', 390],
43+
['2010', 'Q3', 'Belgium', 420],
44+
['2010', 'Q4', 'Belgium', 460],
45+
['2011', 'Q1', 'Belgium', 400],
46+
['2011', 'Q2', 'Belgium', 350],
47+
['2011', 'Q3', 'Belgium', 450],
48+
['2011', 'Q4', 'Belgium', 500],
49+
];
50+
51+
$spreadsheet->getActiveSheet()->fromArray($dataArray, null, 'A2');
52+
53+
// Table
54+
$helper->log('Create Table');
55+
$table = new Table();
56+
$table->setName('SalesData');
57+
$table->setShowTotalsRow(true);
58+
$table->setRange('A1:D18'); // +1 row for totalsRow
59+
60+
$helper->log('Add Totals Row');
61+
// Table column label not implemented yet,
62+
$table->getColumn('A')->setTotalsRowLabel('Total');
63+
// So set the label directly to the cell
64+
$spreadsheet->getActiveSheet()->getCell('A18')->setValue('Total');
65+
66+
// Table column function not implemented yet,
67+
$table->getColumn('D')->setTotalsRowFunction('sum');
68+
// So set the formula directly to the cell
69+
$spreadsheet->getActiveSheet()->getCell('D18')->setValue('=SUBTOTAL(109,SalesData[Sales])');
70+
71+
// Add Table to Worksheet
72+
$helper->log('Add Table to Worksheet');
73+
$spreadsheet->getActiveSheet()->addTable($table);
74+
75+
// Save
76+
$path = $helper->getFilename(__FILE__);
77+
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
78+
79+
// Disable precalculation to add table's total row
80+
$writer->setPreCalculateFormulas(false);
81+
$callStartTime = microtime(true);
82+
$writer->save($path);
83+
$helper->logWrite($writer, $path, $callStartTime);
84+
$helper->logEndingNotes();

0 commit comments

Comments
 (0)