-
Notifications
You must be signed in to change notification settings - Fork 0
Tables
Page::table() renders a data grid from an array (or any iterable) of associative rows. Columns are defined with Column value objects that describe which row key to read, a header label, a width policy, and optional alignment overrides. The renderer reuses the cell and image pipeline, supports automatic page-break with repeated header rows, zebra striping, configurable borders, and per-cell conditional styling.
use DragonOfMercy\PhpPdf\Color;
use DragonOfMercy\PhpPdf\Document;
use DragonOfMercy\PhpPdf\Image;
use DragonOfMercy\PhpPdf\Table\Cell;
use DragonOfMercy\PhpPdf\Table\CellStyle;
use DragonOfMercy\PhpPdf\Table\Column;
use DragonOfMercy\PhpPdf\Table\TableBorders;
use DragonOfMercy\PhpPdf\Table\TableStyle;
use DragonOfMercy\PhpPdf\TextAlign;
$doc = new Document();
$doc->setAutoPageBreak(true, 15);
$page = $doc->addPage();
$page->setFont($doc->getFont('Helvetica'), 10);
// One fill column takes the remaining width; two fixed columns get exact mm.
$columns = [
Column::of('avatar', '')->width(14)->align(TextAlign::CENTER),
Column::of('name', 'Name')->fill(),
Column::of('role', 'Role')->width(40),
Column::of('salary', 'Salary')->width(32)->align(TextAlign::RIGHT),
];
// Scalars are shorthand for Cell::of($value). Cell::image() embeds a raster or SVG image.
$rows = [
['avatar' => Cell::image(Image::fromFile('avatar1.png'), w: 10), 'name' => 'Alice Martin', 'role' => 'Engineer', 'salary' => '95,000'],
['avatar' => Cell::image(Image::fromFile('avatar2.png'), w: 10), 'name' => 'Bob Nguyen', 'role' => 'Designer', 'salary' => '82,000'],
['avatar' => Cell::image(Image::fromFile('avatar3.png'), w: 10), 'name' => 'Carol Schmidt', 'role' => 'Manager', 'salary' => '110,000'],
];
$style = TableStyle::default()
->withHeader(fill: Color::gray(220), bold: true)
->withBorder(TableBorders::GRID)
->withZebra(Color::rgb(255, 255, 255), Color::gray(247))
->withCellStyle(function (mixed $value, array $row, Column $col): ?CellStyle {
if ($col->key === 'salary' && is_string($value) && (int) str_replace(',', '', $value) > 100000) {
return CellStyle::new()->withTextColor(Color::rgb(180, 0, 0))->withBold(true);
}
return null;
});
$result = $page->table($columns, $rows, x: 15, y: 30, width: 180, style: $style);
// $result->rowCount -- number of data rows rendered
// $result->pageCount -- number of pages the table spans
// $result->page -- last Page instance used (useful for further drawing)
// $result->x / ->y -- cursor position after the last row| Parameter | Type | Description |
|---|---|---|
$columns |
Column[] |
Column definitions (at least one required). |
$rows |
iterable |
Associative arrays. Scalar values become Cell::of() automatically. |
x |
float |
Left edge in the document unit (mm by default). |
y |
float |
Top edge in the document unit. |
width |
float |
Total table width. Fixed columns are subtracted first; fill columns share the remainder. |
style |
TableStyle |
Presentation and pagination config. Optional; defaults to TableStyle::default(). |
The method returns a TableResult with public properties rowCount, pageCount, page, x, and y.
Column::of(string $key, ?string $header = null) is the named constructor. Chain the following methods (each returns a new immutable Column):
| Method | Description |
|---|---|
->width(float $mm) |
Fixed width in the document unit. Mutually exclusive with ->fill(). |
->fill(int $weight = 1) |
Fill policy: takes a proportional share of the remaining width. Multiple fill columns divide by weight. Mutually exclusive with ->width(). |
->align(TextAlign $align) |
Default horizontal alignment for data cells in this column. |
->verticalAlign(VerticalAlign $v) |
Default vertical alignment for data cells. |
->padding(CellPadding $p) |
Default padding override for every cell in this column. |
The $key property is public and readable in callbacks (e.g. $col->key === 'salary').
A row value may be:
-
Scalar - converted implicitly to
Cell::of((string) $value). -
Cell::of(string|\Stringable $text)- text cell with optional style overrides:->bold(),->align(),->verticalAlign(),->textColor(),->fill(),->padding(). -
Cell::image(Image|string $src, ?float $w = null, ?float $h = null)- image cell. Aspect ratio is preserved and the image is clamped to the inner cell box. Defaults toTextAlign::CENTER/VerticalAlign::MIDDLE. A plain path string is accepted as$src(equivalent toImage::fromFile($path)).
Build from TableStyle::default() and chain with* methods. All methods return a new immutable TableStyle.
| Method | Description |
|---|---|
->withHeader(?Color $fill, bool $bold, ?Color $textColor) |
Header row appearance. |
->withBorder(TableBorders $borders) |
Border preset (see below). |
->withBorderStyle(Border $b) |
Line appearance (width, color, style) applied to all drawn borders. |
->withZebra(Color $even, Color $odd) |
Alternate row fills. Even rows (0, 2, ...) use $even; odd rows use $odd. |
->withRepeatHeader(bool $repeat) |
Whether the header row is re-drawn at the top of each continuation page. Default: true. |
->withCellStyle(callable $fn) |
Per-cell conditional styling callback (see below). |
->withRowPadding(CellPadding $p) |
Default padding applied to every data cell. |
| Case | Effect |
|---|---|
GRID |
All cell edges drawn (default). |
HORIZONTAL |
Horizontal rules between rows only. |
HEADER_UNDERLINE |
Single rule under the header row only. |
NONE |
No borders. |
The callable receives (mixed $value, array $row, Column $col) and must return CellStyle|null. A non-null return overrides style for that cell only:
->withCellStyle(function (mixed $value, array $row, Column $col): ?CellStyle {
if ($col->key === 'status' && $value === 'overdue') {
return CellStyle::new()->withFill(Color::rgb(255, 220, 220))->withBold(true);
}
return null;
})CellStyle::new() is immutable and supports ->withTextColor(Color), ->withFill(Color), ->withBold(bool), and ->withAlign(TextAlign).
When Document::setAutoPageBreak(true) is active, a new page is started automatically whenever a row does not fit the remaining space. The header row is re-drawn on the new page unless ->withRepeatHeader(false) is set.
- No cell spanning:
colspanandrowspanare not supported. - No content-derived auto-width: every column must have an explicit
->width()or->fill()policy.
MIT licensed. Source on GitHub - if phppdf helps you, you can buy me a coffee.