0
# Data Models
1
2
Core data model classes representing table structure and cell content with full type safety and comprehensive functionality for table manipulation and rendering.
3
4
## Capabilities
5
6
### Table Class
7
8
Primary table model representing the complete table structure with settings, styling, content, and rendering state.
9
10
```typescript { .api }
11
class Table {
12
/** Optional table identifier */
13
readonly id?: string | number;
14
/** Table configuration settings */
15
readonly settings: Settings;
16
/** Table styling configuration */
17
readonly styles: StylesProps;
18
/** Hook functions for customization */
19
readonly hooks: HookProps;
20
/** Column definitions */
21
readonly columns: Column[];
22
/** Header rows */
23
readonly head: Row[];
24
/** Body rows */
25
readonly body: Row[];
26
/** Footer rows */
27
readonly foot: Row[];
28
/** Current page number during rendering */
29
pageNumber: number;
30
/** Final Y position after table is drawn */
31
finalY?: number;
32
/** Starting page number */
33
startPageNumber?: number;
34
35
constructor(input: TableInput, content: ContentSettings);
36
37
/** Calculate total height of header rows */
38
getHeadHeight(columns: Column[]): number;
39
/** Calculate total height of footer rows */
40
getFootHeight(columns: Column[]): number;
41
/** Get all rows (head + body + foot) */
42
allRows(): Row[];
43
/** Execute cell-level hooks */
44
callCellHooks(
45
doc: DocHandler,
46
handlers: CellHook[],
47
cell: Cell,
48
row: Row,
49
column: Column,
50
cursor: { x: number; y: number } | null
51
): boolean;
52
/** Execute end-of-page hooks */
53
callEndPageHooks(doc: DocHandler, cursor: { x: number; y: number }): void;
54
/** Execute start-of-page hooks */
55
callWillDrawPageHooks(doc: DocHandler, cursor: { x: number; y: number }): void;
56
/** Calculate table width based on settings */
57
getWidth(pageWidth: number): number;
58
}
59
```
60
61
**Usage Example:**
62
63
```typescript
64
import { __createTable } from "jspdf-autotable";
65
66
const table = __createTable(doc, {
67
head: [['Name', 'Score']],
68
body: [['Alice', 95], ['Bob', 87]],
69
});
70
71
// Access table properties
72
console.log(table.columns.length); // 2
73
console.log(table.head.length); // 1
74
console.log(table.body.length); // 2
75
76
// Calculate dimensions
77
const headHeight = table.getHeadHeight(table.columns);
78
const totalWidth = table.getWidth(doc.internal.pageSize.width);
79
```
80
81
### Row Class
82
83
Represents a single table row with cells and layout information.
84
85
```typescript { .api }
86
class Row {
87
/** Original row input data */
88
readonly raw: HTMLTableRowElement | RowInput;
89
/** Reference to HTML element if created from HTML */
90
readonly element?: HTMLTableRowElement;
91
/** Row index within its section */
92
readonly index: number;
93
/** Section type: 'head', 'body', or 'foot' */
94
readonly section: Section;
95
/** Cell objects keyed by column index */
96
readonly cells: { [key: string]: Cell };
97
/** Whether this row spans multiple pages */
98
spansMultiplePages: boolean;
99
/** Calculated row height */
100
height: number;
101
102
constructor(
103
raw: RowInput | HTMLTableRowElement,
104
index: number,
105
section: Section,
106
cells: { [key: string]: Cell },
107
spansMultiplePages?: boolean
108
);
109
110
/** Get maximum cell height in this row */
111
getMaxCellHeight(columns: Column[]): number;
112
/** Check if row has cells with rowSpan > 1 */
113
hasRowSpan(columns: Column[]): boolean;
114
/** Check if entire row can fit in given height */
115
canEntireRowFit(height: number, columns: Column[]): boolean;
116
/** Calculate minimum height needed for this row */
117
getMinimumRowHeight(columns: Column[], doc: DocHandler): number;
118
}
119
```
120
121
**Usage Example:**
122
123
```typescript
124
// Row properties are typically accessed during hook execution
125
const didDrawCell = (data: CellHookData) => {
126
const row = data.row;
127
128
console.log(`Row ${row.index} in ${row.section} section`);
129
console.log(`Row height: ${row.height}`);
130
console.log(`Row spans pages: ${row.spansMultiplePages}`);
131
132
// Access specific cells
133
const firstCell = row.cells[0];
134
if (firstCell) {
135
console.log(`First cell content: ${firstCell.text.join(' ')}`);
136
}
137
};
138
```
139
140
### Cell Class
141
142
Represents individual table cells with content, styling, and positioning information.
143
144
```typescript { .api }
145
class Cell {
146
/** Original cell input data */
147
raw: HTMLTableCellElement | CellInput;
148
/** Cell styling configuration */
149
styles: Styles;
150
/** Text content as array of lines */
151
text: string[];
152
/** Section type: 'head', 'body', or 'foot' */
153
section: Section;
154
/** Number of columns this cell spans */
155
colSpan: number;
156
/** Number of rows this cell spans */
157
rowSpan: number;
158
/** Height of cell content */
159
contentHeight: number;
160
/** Width of cell content */
161
contentWidth: number;
162
/** Width after text wrapping */
163
wrappedWidth: number;
164
/** Minimum readable width */
165
minReadableWidth: number;
166
/** Minimum width */
167
minWidth: number;
168
/** Actual cell width */
169
width: number;
170
/** Actual cell height */
171
height: number;
172
/** X position on page */
173
x: number;
174
/** Y position on page */
175
y: number;
176
177
constructor(raw: CellInput, styles: Styles, section: Section);
178
179
/** Get text position based on alignment */
180
getTextPos(): Pos;
181
/** Calculate content height with line spacing */
182
getContentHeight(scaleFactor: number, lineHeightFactor?: number): number;
183
/** Get padding value for specific side */
184
padding(name: "vertical" | "horizontal" | "top" | "bottom" | "left" | "right"): number;
185
}
186
```
187
188
**Usage Example:**
189
190
```typescript
191
// Cell manipulation in hooks
192
const willDrawCell = (data: CellHookData) => {
193
const cell = data.cell;
194
195
// Modify cell content
196
if (cell.text[0] === 'URGENT') {
197
// Change styling for urgent items
198
cell.styles.fillColor = [255, 0, 0];
199
cell.styles.textColor = [255, 255, 255];
200
cell.styles.fontStyle = 'bold';
201
}
202
203
// Position information
204
console.log(`Cell at (${cell.x}, ${cell.y}) size ${cell.width}x${cell.height}`);
205
206
// Content information
207
console.log(`Cell spans ${cell.colSpan} columns, ${cell.rowSpan} rows`);
208
console.log(`Cell content: ${cell.text.join('\n')}`);
209
};
210
```
211
212
### Column Class
213
214
Represents table columns with width calculations and data mapping.
215
216
```typescript { .api }
217
class Column {
218
/** Original column input data */
219
raw: ColumnInput | null;
220
/** Data key for mapping object properties */
221
dataKey: string | number;
222
/** Column index */
223
index: number;
224
/** Width after content wrapping */
225
wrappedWidth: number;
226
/** Minimum readable width */
227
minReadableWidth: number;
228
/** Minimum width */
229
minWidth: number;
230
/** Actual column width */
231
width: number;
232
233
constructor(dataKey: string | number, raw: ColumnInput | null, index: number);
234
235
/** Get maximum custom cell width in this column */
236
getMaxCustomCellWidth(table: Table): number;
237
}
238
```
239
240
**Usage Example:**
241
242
```typescript
243
// Column information is typically accessed during table creation
244
const table = __createTable(doc, {
245
columns: [
246
{ header: 'Name', dataKey: 'name' },
247
{ header: 'Score', dataKey: 'score' },
248
],
249
body: [
250
{ name: 'Alice', score: 95 },
251
{ name: 'Bob', score: 87 },
252
],
253
});
254
255
table.columns.forEach((column, index) => {
256
console.log(`Column ${index}: ${column.dataKey}`);
257
console.log(`Width: ${column.width}`);
258
259
const maxCustomWidth = column.getMaxCustomCellWidth(table);
260
console.log(`Max custom width: ${maxCustomWidth}`);
261
});
262
```
263
264
### Supporting Types and Interfaces
265
266
#### Settings Interface
267
268
Table-level configuration settings processed from UserOptions.
269
270
```typescript { .api }
271
interface Settings {
272
includeHiddenHtml: boolean;
273
useCss: boolean;
274
theme: "striped" | "grid" | "plain";
275
startY: number;
276
margin: MarginPadding;
277
pageBreak: "auto" | "avoid" | "always";
278
rowPageBreak: "auto" | "avoid";
279
tableWidth: "auto" | "wrap" | number;
280
showHead: "everyPage" | "firstPage" | "never";
281
showFoot: "everyPage" | "lastPage" | "never";
282
tableLineWidth: number;
283
tableLineColor: Color;
284
horizontalPageBreak?: boolean;
285
horizontalPageBreakBehaviour?: "immediately" | "afterAllRows";
286
horizontalPageBreakRepeat?: string | number | string[] | number[] | null;
287
}
288
```
289
290
#### StylesProps Interface
291
292
Collection of style configurations for different table sections.
293
294
```typescript { .api }
295
interface StylesProps {
296
styles: Partial<Styles>;
297
headStyles: Partial<Styles>;
298
bodyStyles: Partial<Styles>;
299
footStyles: Partial<Styles>;
300
alternateRowStyles: Partial<Styles>;
301
columnStyles: { [key: string]: Partial<Styles> };
302
}
303
```
304
305
#### ContentSettings Type
306
307
Processed content data for table creation.
308
309
```typescript { .api }
310
type ContentSettings = {
311
body: Row[];
312
head: Row[];
313
foot: Row[];
314
columns: Column[];
315
};
316
```
317
318
### Data Model Usage Patterns
319
320
#### Accessing Table Structure
321
322
```typescript
323
const didDrawPage = (data: HookData) => {
324
const table = data.table;
325
326
// Table metadata
327
console.log(`Table ID: ${table.id}`);
328
console.log(`Page: ${table.pageNumber}`);
329
330
// Structure information
331
console.log(`Columns: ${table.columns.length}`);
332
console.log(`Header rows: ${table.head.length}`);
333
console.log(`Body rows: ${table.body.length}`);
334
console.log(`Footer rows: ${table.foot.length}`);
335
336
// Calculated dimensions
337
const headHeight = table.getHeadHeight(table.columns);
338
const footHeight = table.getFootHeight(table.columns);
339
console.log(`Header height: ${headHeight}`);
340
console.log(`Footer height: ${footHeight}`);
341
};
342
```
343
344
#### Cell Content Modification
345
346
```typescript
347
const didParseCell = (data: CellHookData) => {
348
const { cell, column, row } = data;
349
350
// Format currency values
351
if (column.dataKey === 'price') {
352
const price = parseFloat(cell.text[0]);
353
cell.text = [`$${price.toFixed(2)}`];
354
}
355
356
// Add status indicators
357
if (column.dataKey === 'status' && cell.text[0] === 'active') {
358
cell.text = ['✓ Active'];
359
cell.styles.textColor = [0, 128, 0];
360
}
361
};
362
```
363
364
#### Dynamic Row Styling
365
366
```typescript
367
const willDrawCell = (data: CellHookData) => {
368
const { cell, row, table } = data;
369
370
// Highlight every 5th row
371
if (row.index % 5 === 0) {
372
cell.styles.fillColor = [255, 255, 200];
373
}
374
375
// Add borders to last row
376
if (row.index === table.body.length - 1) {
377
cell.styles.lineWidth = { bottom: 2 };
378
cell.styles.lineColor = [0, 0, 0];
379
}
380
};
381
```