Components
Blocks
- Event Agenda
- Event Ticket
- Gift Certificate
- Invoice Classic
- Invoice Consultant
- Invoice Corporate
- Invoice Creative
- Invoice Minimal
- Invoice Modern
- Lesson Plan
- Medical Intake Form
- Meeting Minutes
- Packing Slip
- Press Release
- Report Financial
- Report Marketing
- Report Operations
- Report Security
- Shipping Label
- Work Order
Rendering PDF…
Installation
$ pnpm dlx shadcn@latest add @angular-pdfcn/forme/data-tableUsage
import { Component } from "@angular/core";
import { PdfDataTable } from "@/components/pdf/data-table/data-table";
import type { DataTableColumn } from "@/components/pdf/data-table/data-table.types";
import { PdfHeading } from "@/components/pdf/heading/heading";
import { PdfSection } from "@/components/pdf/section/section";
import {
FormeDocument,
FormePage,
} from "@/lib/pdf-primitives";
const data = [
{ dept: "Engineering", id: 1, name: "Alice Johnson", status: "Active" },
{ dept: "Marketing", id: 2, name: "Bob Smith", status: "Active" },
{ dept: "Design", id: 3, name: "Carol Lee", status: "Inactive" },
{ dept: "Engineering", id: 4, name: "Dan Wilson", status: "Active" },
{ dept: "Sales", id: 5, name: "Eve Brown", status: "Active" },
{ dept: "Support", id: 6, name: "Frank Chen", status: "Active" },
{ dept: "Product", id: 7, name: "Grace Kim", status: "Active" },
{ dept: "Marketing", id: 8, name: "Hank Davis", status: "Inactive" },
];
const columns: DataTableColumn<(typeof data)[number]>[] = [
{ align: "center", header: "ID", key: "id" },
{ header: "Name", key: "name" },
{ header: "Department", key: "dept" },
{ align: "center", header: "Status", key: "status" },
];
@Component({
imports: [FormeDocument, FormePage, PdfDataTable, PdfHeading, PdfSection],
template: `
<forme-document>
<forme-page size="A4" [margin]="40">
<pdf-section spacing="none">
<pdf-heading [level]="3">Team Directory</pdf-heading>
<pdf-data-table
size="compact"
variant="striped"
[columns]="columns"
[data]="data"
/>
</pdf-section>
</forme-page>
</forme-document>
`,
})
export class DataTableDemo {
protected readonly columns = columns;
protected readonly data = data;
}Variants
Use any TableVariant for the table treatment and size="compact" for denser reports.
<pdf-data-table
[columns]="columns"
[data]="rows"
variant="striped"
size="compact"
/>API Reference
PdfDataTable
| Input | Type | Default |
|---|---|---|
columns |
DataTableColumn<T>[] |
- |
data |
T[] |
- |
variant |
'line' | 'grid' | 'minimal' | 'striped' | 'compact' | 'bordered' | 'primary-header' |
'grid' |
footer |
Partial<Record<keyof T, string | number>> |
- |
stripe |
boolean |
false |
size |
'default' | 'compact' |
'default' |
noWrap |
boolean |
false |
style |
Style |
- |
DataTableColumn
key is the row-field accessor. For example, key: "name" reads row.name.
render and renderFooter take a TemplateRef. A cell template gets the value as $implicit and the row as row. A footer template gets the footer value as $implicit.
@Component({
selector: "app-totals",
imports: [PdfDataTable],
template: `
<ng-template #amount let-value let-row="row"
>{{ row.currency }} {{ value }}</ng-template
>
<pdf-data-table [columns]="columns()" [data]="rows" />
`,
})
export class Totals {
protected readonly rows: Row[] = [
{ amount: 120, currency: "USD", item: "Design" },
];
private readonly amount =
viewChild<TemplateRef<DataTableCellContext<Row>>>("amount");
protected readonly columns = computed((): DataTableColumn<Row>[] => [
{ header: "Item", key: "item" },
{ align: "right", header: "Amount", key: "amount", render: this.amount() },
]);
}| Field | Type | Default |
|---|---|---|
key |
keyof T & string |
- |
header |
string |
- |
align |
'left' | 'center' | 'right' |
'left' |
width |
string | number |
- |
render |
TemplateRef<DataTableCellContext<T>> |
- |
renderFooter |
TemplateRef<DataTableFooterContext> |
- |