@pdfme/schemas 6.0.3 → 6.0.4-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/barcodes/constants.d.ts +4 -0
- package/dist/barcodes/helper.d.ts +21 -0
- package/dist/barcodes/index.d.ts +4 -0
- package/dist/barcodes/pdfRender.d.ts +3 -0
- package/dist/barcodes/propPanel.d.ts +3 -0
- package/{src/barcodes/types.ts → dist/barcodes/types.d.ts} +5 -7
- package/dist/barcodes/uiRender.d.ts +3 -0
- package/dist/builtins-CgaZ0UX3.js +613 -0
- package/dist/builtins-CgaZ0UX3.js.map +1 -0
- package/dist/builtins.d.ts +4 -0
- package/dist/builtins.js +2 -0
- package/dist/checkbox/index.d.ts +6 -0
- package/dist/constants.d.ts +2 -0
- package/dist/date/date.d.ts +2 -0
- package/dist/date/dateTime.d.ts +2 -0
- package/dist/date/helper.d.ts +20 -0
- package/dist/date/time.d.ts +2 -0
- package/dist/date/types.d.ts +17 -0
- package/dist/dynamicTemplate-D_DHR3-X.js +1128 -0
- package/dist/dynamicTemplate-D_DHR3-X.js.map +1 -0
- package/dist/graphics/image.d.ts +5 -0
- package/dist/graphics/imagehelper.d.ts +4 -0
- package/dist/graphics/signature.d.ts +4 -0
- package/dist/graphics/svg.d.ts +4 -0
- package/{src/index.ts → dist/index.d.ts} +1 -22
- package/dist/index.js +5383 -0
- package/dist/index.js.map +1 -0
- package/dist/multiVariableText/helper.d.ts +3 -0
- package/dist/multiVariableText/index.d.ts +4 -0
- package/dist/multiVariableText/pdfRender.d.ts +3 -0
- package/dist/multiVariableText/propPanel.d.ts +3 -0
- package/{src/multiVariableText/types.ts → dist/multiVariableText/types.d.ts} +2 -3
- package/dist/multiVariableText/uiRender.d.ts +3 -0
- package/dist/multiVariableText/variables.d.ts +10 -0
- package/dist/radioGroup/index.d.ts +7 -0
- package/dist/sanitize.d.ts +1 -0
- package/dist/select/index.d.ts +7 -0
- package/dist/shapes/line.d.ts +6 -0
- package/dist/shapes/rectAndEllipse.d.ts +11 -0
- package/dist/tables/cell.d.ts +4 -0
- package/dist/tables/classes.d.ts +69 -0
- package/dist/tables/dynamicTemplate.d.ts +7 -0
- package/dist/tables/helper.d.ts +265 -0
- package/dist/tables/index.d.ts +4 -0
- package/dist/tables/pdfRender.d.ts +3 -0
- package/dist/tables/propPanel.d.ts +3 -0
- package/dist/tables/tableHelper.d.ts +10 -0
- package/dist/tables/types.d.ts +88 -0
- package/dist/tables/uiRender.d.ts +3 -0
- package/dist/tables.js +2 -0
- package/dist/text/constants.d.ts +23 -0
- package/dist/text/extraFormatter.d.ts +25 -0
- package/dist/text/helper.d.ts +40 -0
- package/dist/text/icons/index.d.ts +9 -0
- package/dist/text/index.d.ts +4 -0
- package/dist/text/pdfRender.d.ts +3 -0
- package/dist/text/propPanel.d.ts +3 -0
- package/dist/text/types.d.ts +28 -0
- package/dist/text/uiRender.d.ts +11 -0
- package/dist/utils.d.ts +40 -0
- package/dist/utils.js +215 -0
- package/dist/utils.js.map +1 -0
- package/package.json +5 -1
- package/src/barcodes/constants.ts +0 -20
- package/src/barcodes/helper.ts +0 -187
- package/src/barcodes/index.ts +0 -23
- package/src/barcodes/pdfRender.ts +0 -37
- package/src/barcodes/propPanel.ts +0 -249
- package/src/barcodes/uiRender.ts +0 -94
- package/src/builtins.ts +0 -8
- package/src/checkbox/index.ts +0 -70
- package/src/constants.ts +0 -2
- package/src/date/date.ts +0 -9
- package/src/date/dateTime.ts +0 -9
- package/src/date/helper.ts +0 -544
- package/src/date/time.ts +0 -9
- package/src/date/types.ts +0 -19
- package/src/graphics/image.ts +0 -201
- package/src/graphics/imagehelper.ts +0 -156
- package/src/graphics/signature.ts +0 -136
- package/src/graphics/svg.ts +0 -121
- package/src/multiVariableText/helper.ts +0 -65
- package/src/multiVariableText/index.ts +0 -16
- package/src/multiVariableText/pdfRender.ts +0 -21
- package/src/multiVariableText/propPanel.ts +0 -169
- package/src/multiVariableText/uiRender.ts +0 -157
- package/src/multiVariableText/variables.ts +0 -63
- package/src/radioGroup/index.ts +0 -115
- package/src/sanitize.ts +0 -50
- package/src/select/index.ts +0 -205
- package/src/shapes/line.ts +0 -94
- package/src/shapes/rectAndEllipse.ts +0 -152
- package/src/tables/cell.ts +0 -152
- package/src/tables/classes.ts +0 -402
- package/src/tables/dynamicTemplate.ts +0 -88
- package/src/tables/helper.ts +0 -216
- package/src/tables/index.ts +0 -15
- package/src/tables/pdfRender.ts +0 -144
- package/src/tables/propPanel.ts +0 -111
- package/src/tables/tableHelper.ts +0 -289
- package/src/tables/types.ts +0 -87
- package/src/tables/uiRender.ts +0 -436
- package/src/text/constants.ts +0 -104
- package/src/text/extraFormatter.ts +0 -83
- package/src/text/helper.ts +0 -573
- package/src/text/icons/index.ts +0 -30
- package/src/text/index.ts +0 -16
- package/src/text/pdfRender.ts +0 -240
- package/src/text/propPanel.ts +0 -184
- package/src/text/types.ts +0 -30
- package/src/text/uiRender.ts +0 -292
- package/src/utils.ts +0 -354
- package/tsconfig.build.json +0 -14
- package/tsconfig.json +0 -16
- package/vite.config.mts +0 -51
- /package/{src/tables.ts → dist/tables.d.ts} +0 -0
package/src/tables/classes.ts
DELETED
|
@@ -1,402 +0,0 @@
|
|
|
1
|
-
import { Font, mm2pt, pt2mm } from '@pdfme/common';
|
|
2
|
-
import type { Font as FontKitFont } from 'fontkit';
|
|
3
|
-
import { splitTextToSize, getFontKitFont, widthOfTextAtSize } from '../text/helper.js';
|
|
4
|
-
import type { Styles, TableInput, Settings, Section, StylesProps } from './types.js';
|
|
5
|
-
|
|
6
|
-
type ContentSettings = { body: Row[]; head: Row[]; columns: Column[] };
|
|
7
|
-
|
|
8
|
-
export class Cell {
|
|
9
|
-
raw: string;
|
|
10
|
-
text: string[];
|
|
11
|
-
styles: Styles;
|
|
12
|
-
section: Section;
|
|
13
|
-
contentHeight = 0;
|
|
14
|
-
contentWidth = 0;
|
|
15
|
-
wrappedWidth = 0;
|
|
16
|
-
minReadableWidth = 0;
|
|
17
|
-
minWidth = 0;
|
|
18
|
-
|
|
19
|
-
width = 0;
|
|
20
|
-
height = 0;
|
|
21
|
-
x = 0;
|
|
22
|
-
y = 0;
|
|
23
|
-
|
|
24
|
-
constructor(raw: string, styles: Styles, section: Section) {
|
|
25
|
-
this.styles = styles;
|
|
26
|
-
this.section = section;
|
|
27
|
-
this.raw = raw;
|
|
28
|
-
const splitRegex = /\r\n|\r|\n/g;
|
|
29
|
-
this.text = raw.split(splitRegex);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
getContentHeight() {
|
|
33
|
-
const lineCount = Array.isArray(this.text) ? this.text.length : 1;
|
|
34
|
-
const lineHeight = pt2mm(this.styles.fontSize) * this.styles.lineHeight;
|
|
35
|
-
const vPadding = this.padding('top') + this.padding('bottom');
|
|
36
|
-
const height = lineCount * lineHeight + vPadding;
|
|
37
|
-
return Math.max(height, this.styles.minCellHeight);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
padding(name: 'top' | 'bottom' | 'left' | 'right') {
|
|
41
|
-
return this.styles.cellPadding[name];
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export class Column {
|
|
46
|
-
index: number;
|
|
47
|
-
wrappedWidth = 0;
|
|
48
|
-
minReadableWidth = 0;
|
|
49
|
-
minWidth = 0;
|
|
50
|
-
width = 0;
|
|
51
|
-
|
|
52
|
-
constructor(index: number) {
|
|
53
|
-
this.index = index;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
getMaxCustomCellWidth(table: Table) {
|
|
57
|
-
let max = 0;
|
|
58
|
-
for (const row of table.allRows()) {
|
|
59
|
-
const cell: Cell = row.cells[this.index];
|
|
60
|
-
max = Math.max(max, cell.styles.cellWidth);
|
|
61
|
-
}
|
|
62
|
-
return max;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export class Row {
|
|
67
|
-
readonly raw: string[];
|
|
68
|
-
readonly index: number;
|
|
69
|
-
readonly section: Section;
|
|
70
|
-
readonly cells: { [key: string]: Cell };
|
|
71
|
-
|
|
72
|
-
height = 0;
|
|
73
|
-
|
|
74
|
-
constructor(raw: string[], index: number, section: Section, cells: { [key: string]: Cell }) {
|
|
75
|
-
this.raw = raw;
|
|
76
|
-
this.index = index;
|
|
77
|
-
this.section = section;
|
|
78
|
-
this.cells = cells;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
getMaxCellHeight(columns: Column[]) {
|
|
82
|
-
return columns.reduce((acc, column) => Math.max(acc, this.cells[column.index]?.height || 0), 0);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
getMinimumRowHeight(columns: Column[]) {
|
|
86
|
-
return columns.reduce((acc: number, column: Column) => {
|
|
87
|
-
const cell = this.cells[column.index];
|
|
88
|
-
if (!cell) return 0;
|
|
89
|
-
const vPadding = cell.padding('top') + cell.padding('bottom');
|
|
90
|
-
const oneRowHeight = vPadding + cell.styles.lineHeight;
|
|
91
|
-
return oneRowHeight > acc ? oneRowHeight : acc;
|
|
92
|
-
}, 0);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export class Table {
|
|
97
|
-
readonly settings: Settings;
|
|
98
|
-
readonly styles: StylesProps;
|
|
99
|
-
|
|
100
|
-
readonly columns: Column[];
|
|
101
|
-
readonly head: Row[];
|
|
102
|
-
readonly body: Row[];
|
|
103
|
-
|
|
104
|
-
constructor(input: TableInput, content: ContentSettings) {
|
|
105
|
-
this.settings = input.settings;
|
|
106
|
-
this.styles = input.styles;
|
|
107
|
-
|
|
108
|
-
this.columns = content.columns;
|
|
109
|
-
this.head = content.head;
|
|
110
|
-
this.body = content.body;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
static async create(arg: {
|
|
114
|
-
input: TableInput;
|
|
115
|
-
content: ContentSettings;
|
|
116
|
-
font: Font;
|
|
117
|
-
_cache: Map<string | number, FontKitFont>;
|
|
118
|
-
}) {
|
|
119
|
-
const { input, content, font, _cache } = arg;
|
|
120
|
-
const table = new Table(input, content);
|
|
121
|
-
|
|
122
|
-
await calculateWidths({ table, font, _cache });
|
|
123
|
-
|
|
124
|
-
return table;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
getHeadHeight() {
|
|
128
|
-
return this.head.reduce((acc, row) => acc + row.getMaxCellHeight(this.columns), 0);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
getBodyHeight() {
|
|
132
|
-
return this.body.reduce((acc, row) => acc + row.getMaxCellHeight(this.columns), 0);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
allRows() {
|
|
136
|
-
return this.head.concat(this.body);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
getWidth() {
|
|
140
|
-
return this.settings.tableWidth;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
getHeight() {
|
|
144
|
-
return (this.settings.showHead ? this.getHeadHeight() : 0) + this.getBodyHeight();
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
async function calculateWidths(arg: {
|
|
149
|
-
table: Table;
|
|
150
|
-
font: Font;
|
|
151
|
-
_cache: Map<string | number, FontKitFont>;
|
|
152
|
-
}) {
|
|
153
|
-
const { table, font, _cache } = arg;
|
|
154
|
-
|
|
155
|
-
const getFontKitFontByFontName = (fontName: string | undefined) =>
|
|
156
|
-
getFontKitFont(fontName, font, _cache);
|
|
157
|
-
|
|
158
|
-
await calculate(table, getFontKitFontByFontName);
|
|
159
|
-
|
|
160
|
-
const resizableColumns: Column[] = [];
|
|
161
|
-
let initialTableWidth = 0;
|
|
162
|
-
|
|
163
|
-
table.columns.forEach((column) => {
|
|
164
|
-
const customWidth = column.getMaxCustomCellWidth(table);
|
|
165
|
-
if (customWidth) {
|
|
166
|
-
// final column width
|
|
167
|
-
column.width = customWidth;
|
|
168
|
-
} else {
|
|
169
|
-
// initial column width (will be resized)
|
|
170
|
-
column.width = column.wrappedWidth;
|
|
171
|
-
resizableColumns.push(column);
|
|
172
|
-
}
|
|
173
|
-
initialTableWidth += column.width;
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
// width difference that needs to be distributed
|
|
177
|
-
let resizeWidth = table.getWidth() - initialTableWidth;
|
|
178
|
-
|
|
179
|
-
// first resize attempt: with respect to minReadableWidth and minWidth
|
|
180
|
-
if (resizeWidth) {
|
|
181
|
-
resizeWidth = resizeColumns(resizableColumns, resizeWidth, (column) =>
|
|
182
|
-
Math.max(column.minReadableWidth, column.minWidth),
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// second resize attempt: ignore minReadableWidth but respect minWidth
|
|
187
|
-
if (resizeWidth) {
|
|
188
|
-
resizeWidth = resizeColumns(resizableColumns, resizeWidth, (column) => column.minWidth);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
resizeWidth = Math.abs(resizeWidth);
|
|
192
|
-
|
|
193
|
-
applyColSpans(table);
|
|
194
|
-
await fitContent(table, getFontKitFontByFontName);
|
|
195
|
-
applyRowSpans(table);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
function applyRowSpans(table: Table) {
|
|
199
|
-
const rowSpanCells: {
|
|
200
|
-
[key: string]: { cell: Cell; left: number; row: Row };
|
|
201
|
-
} = {};
|
|
202
|
-
let colRowSpansLeft = 1;
|
|
203
|
-
const all = table.allRows();
|
|
204
|
-
for (let rowIndex = 0; rowIndex < all.length; rowIndex++) {
|
|
205
|
-
const row = all[rowIndex];
|
|
206
|
-
for (const column of table.columns) {
|
|
207
|
-
const data = rowSpanCells[column.index];
|
|
208
|
-
if (colRowSpansLeft > 1) {
|
|
209
|
-
colRowSpansLeft--;
|
|
210
|
-
delete row.cells[column.index];
|
|
211
|
-
} else if (data) {
|
|
212
|
-
data.cell.height += row.height;
|
|
213
|
-
colRowSpansLeft = 1;
|
|
214
|
-
delete row.cells[column.index];
|
|
215
|
-
data.left--;
|
|
216
|
-
if (data.left <= 1) {
|
|
217
|
-
delete rowSpanCells[column.index];
|
|
218
|
-
}
|
|
219
|
-
} else {
|
|
220
|
-
const cell = row.cells[column.index];
|
|
221
|
-
if (!cell) {
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
224
|
-
cell.height = row.height;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
function applyColSpans(table: Table) {
|
|
231
|
-
const all = table.allRows();
|
|
232
|
-
for (let rowIndex = 0; rowIndex < all.length; rowIndex++) {
|
|
233
|
-
const row = all[rowIndex];
|
|
234
|
-
|
|
235
|
-
let colSpanCell = null;
|
|
236
|
-
let combinedColSpanWidth = 0;
|
|
237
|
-
let colSpansLeft = 0;
|
|
238
|
-
for (let columnIndex = 0; columnIndex < table.columns.length; columnIndex++) {
|
|
239
|
-
const column = table.columns[columnIndex];
|
|
240
|
-
|
|
241
|
-
// Width and colspan
|
|
242
|
-
colSpansLeft -= 1;
|
|
243
|
-
if (colSpansLeft > 1 && table.columns[columnIndex + 1]) {
|
|
244
|
-
combinedColSpanWidth += column.width;
|
|
245
|
-
delete row.cells[column.index];
|
|
246
|
-
} else if (colSpanCell) {
|
|
247
|
-
const cell: Cell = colSpanCell;
|
|
248
|
-
delete row.cells[column.index];
|
|
249
|
-
colSpanCell = null;
|
|
250
|
-
cell.width = column.width + combinedColSpanWidth;
|
|
251
|
-
} else {
|
|
252
|
-
const cell = row.cells[column.index];
|
|
253
|
-
if (!cell) continue;
|
|
254
|
-
colSpansLeft = 1;
|
|
255
|
-
combinedColSpanWidth = 0;
|
|
256
|
-
cell.width = column.width + combinedColSpanWidth;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
async function fitContent(
|
|
263
|
-
table: Table,
|
|
264
|
-
getFontKitFontByFontName: (fontName: string | undefined) => Promise<FontKitFont>,
|
|
265
|
-
) {
|
|
266
|
-
const rowSpanHeight = { count: 0, height: 0 };
|
|
267
|
-
for (const row of table.allRows()) {
|
|
268
|
-
for (const column of table.columns) {
|
|
269
|
-
const cell: Cell = row.cells[column.index];
|
|
270
|
-
if (!cell) continue;
|
|
271
|
-
|
|
272
|
-
const fontKitFont = await getFontKitFontByFontName(cell.styles.fontName);
|
|
273
|
-
cell.text = splitTextToSize({
|
|
274
|
-
value: cell.raw,
|
|
275
|
-
characterSpacing: cell.styles.characterSpacing,
|
|
276
|
-
boxWidthInPt: mm2pt(cell.width),
|
|
277
|
-
fontSize: cell.styles.fontSize,
|
|
278
|
-
fontKitFont,
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
cell.contentHeight = cell.getContentHeight();
|
|
282
|
-
|
|
283
|
-
let realContentHeight = cell.contentHeight;
|
|
284
|
-
if (rowSpanHeight && rowSpanHeight.count > 0) {
|
|
285
|
-
if (rowSpanHeight.height > realContentHeight) {
|
|
286
|
-
realContentHeight = rowSpanHeight.height;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
if (realContentHeight > row.height) {
|
|
290
|
-
row.height = realContentHeight;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
rowSpanHeight.count--;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
function resizeColumns(
|
|
298
|
-
columns: Column[],
|
|
299
|
-
resizeWidth: number,
|
|
300
|
-
getMinWidth: (column: Column) => number,
|
|
301
|
-
) {
|
|
302
|
-
const initialResizeWidth = resizeWidth;
|
|
303
|
-
const sumWrappedWidth = columns.reduce((acc, column) => acc + column.wrappedWidth, 0);
|
|
304
|
-
|
|
305
|
-
for (let i = 0; i < columns.length; i++) {
|
|
306
|
-
const column = columns[i];
|
|
307
|
-
|
|
308
|
-
const ratio = column.wrappedWidth / sumWrappedWidth;
|
|
309
|
-
const suggestedChange = initialResizeWidth * ratio;
|
|
310
|
-
const suggestedWidth = column.width + suggestedChange;
|
|
311
|
-
|
|
312
|
-
const minWidth = getMinWidth(column);
|
|
313
|
-
const newWidth = suggestedWidth < minWidth ? minWidth : suggestedWidth;
|
|
314
|
-
|
|
315
|
-
resizeWidth -= newWidth - column.width;
|
|
316
|
-
column.width = newWidth;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
resizeWidth = Math.round(resizeWidth * 1e10) / 1e10;
|
|
320
|
-
|
|
321
|
-
// Run the resizer again if there's remaining width needs
|
|
322
|
-
// to be distributed and there're columns that can be resized
|
|
323
|
-
if (resizeWidth) {
|
|
324
|
-
const resizableColumns = columns.filter((column) => {
|
|
325
|
-
return resizeWidth < 0
|
|
326
|
-
? column.width > getMinWidth(column) // check if column can shrink
|
|
327
|
-
: true; // check if column can grow
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
if (resizableColumns.length) {
|
|
331
|
-
resizeWidth = resizeColumns(resizableColumns, resizeWidth, getMinWidth);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
return resizeWidth;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
async function calculate(
|
|
339
|
-
table: Table,
|
|
340
|
-
getFontKitFontByFontName: (fontName: string | undefined) => Promise<FontKitFont>,
|
|
341
|
-
) {
|
|
342
|
-
for (const row of table.allRows()) {
|
|
343
|
-
for (const column of table.columns) {
|
|
344
|
-
const cell = row.cells[column.index];
|
|
345
|
-
if (!cell) continue;
|
|
346
|
-
|
|
347
|
-
const hPadding = cell.padding('right') + cell.padding('left');
|
|
348
|
-
const fontKitFont = await getFontKitFontByFontName(cell.styles.fontName);
|
|
349
|
-
|
|
350
|
-
cell.contentWidth = getStringWidth(cell, fontKitFont) + hPadding;
|
|
351
|
-
|
|
352
|
-
const longestWordWidth = getStringWidth(
|
|
353
|
-
Object.assign(cell, { text: cell.text.join(' ').split(/\s+/) }),
|
|
354
|
-
fontKitFont,
|
|
355
|
-
);
|
|
356
|
-
cell.minReadableWidth = longestWordWidth + hPadding;
|
|
357
|
-
|
|
358
|
-
cell.minWidth = cell.styles.cellWidth;
|
|
359
|
-
cell.wrappedWidth = cell.styles.cellWidth;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
for (const row of table.allRows()) {
|
|
364
|
-
for (const column of table.columns) {
|
|
365
|
-
const cell = row.cells[column.index];
|
|
366
|
-
|
|
367
|
-
// For now we ignore the minWidth and wrappedWidth of colspan cells when calculating colspan widths.
|
|
368
|
-
// Could probably be improved upon however.
|
|
369
|
-
if (cell) {
|
|
370
|
-
column.wrappedWidth = Math.max(column.wrappedWidth, cell.wrappedWidth);
|
|
371
|
-
column.minWidth = Math.max(column.minWidth, cell.minWidth);
|
|
372
|
-
column.minReadableWidth = Math.max(column.minReadableWidth, cell.minReadableWidth);
|
|
373
|
-
} else {
|
|
374
|
-
// Respect cellWidth set in columnStyles even if there is no cells for this column
|
|
375
|
-
// or if the column only have colspan cells. Since the width of colspan cells
|
|
376
|
-
// does not affect the width of columns, setting columnStyles cellWidth enables the
|
|
377
|
-
// user to at least do it manually.
|
|
378
|
-
|
|
379
|
-
// Note that this is not perfect for now since for example row and table styles are
|
|
380
|
-
// not accounted for
|
|
381
|
-
const columnStyles = table.styles.columnStyles[column.index] || {};
|
|
382
|
-
const cellWidth = columnStyles.cellWidth || columnStyles.minCellWidth;
|
|
383
|
-
if (cellWidth) {
|
|
384
|
-
column.minWidth = cellWidth;
|
|
385
|
-
column.wrappedWidth = cellWidth;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
function getStringWidth(cell: Cell, fontKitFont: FontKitFont) {
|
|
393
|
-
const text = cell.text;
|
|
394
|
-
const textArr: string[] = Array.isArray(text) ? text : [text];
|
|
395
|
-
const fontSize = cell.styles.fontSize;
|
|
396
|
-
const characterSpacing = cell.styles.characterSpacing;
|
|
397
|
-
const widestLineWidth = textArr
|
|
398
|
-
.map((text) => widthOfTextAtSize(text, fontKitFont, fontSize, characterSpacing))
|
|
399
|
-
.reduce((a, b) => Math.max(a, b), 0);
|
|
400
|
-
|
|
401
|
-
return widestLineWidth;
|
|
402
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { Schema, BasePdf, BlankPdf, CommonOptions, isBlankPdf } from '@pdfme/common';
|
|
2
|
-
import { createSingleTable } from './tableHelper.js';
|
|
3
|
-
import { getBodyWithRange, getBody } from './helper.js';
|
|
4
|
-
import { TableSchema } from './types.js';
|
|
5
|
-
|
|
6
|
-
export const getDynamicHeightsForTable = async (
|
|
7
|
-
value: string,
|
|
8
|
-
args: {
|
|
9
|
-
schema: Schema;
|
|
10
|
-
basePdf: BasePdf;
|
|
11
|
-
options: CommonOptions;
|
|
12
|
-
_cache: Map<string | number, unknown>;
|
|
13
|
-
},
|
|
14
|
-
): Promise<number[]> => {
|
|
15
|
-
if (args.schema.type !== 'table') return Promise.resolve([args.schema.height]);
|
|
16
|
-
const schema = args.schema as TableSchema;
|
|
17
|
-
const body =
|
|
18
|
-
schema.__bodyRange?.start === 0 ? getBody(value) : getBodyWithRange(value, schema.__bodyRange);
|
|
19
|
-
const table = await createSingleTable(body, args);
|
|
20
|
-
|
|
21
|
-
const baseHeights = schema.showHead
|
|
22
|
-
? table.allRows().map((row) => row.height)
|
|
23
|
-
: [0].concat(table.body.map((row) => row.height));
|
|
24
|
-
|
|
25
|
-
const headerHeight = schema.showHead ? table.getHeadHeight() : 0;
|
|
26
|
-
const shouldRepeatHeader = schema.repeatHead && isBlankPdf(args.basePdf) && headerHeight > 0;
|
|
27
|
-
|
|
28
|
-
if (!shouldRepeatHeader) {
|
|
29
|
-
return baseHeights;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const basePdf = args.basePdf as BlankPdf;
|
|
33
|
-
const [paddingTop, , paddingBottom] = basePdf.padding;
|
|
34
|
-
const pageContentHeight = basePdf.height - paddingTop - paddingBottom;
|
|
35
|
-
const getPageStartY = (pageIndex: number) => pageIndex * pageContentHeight + paddingTop;
|
|
36
|
-
|
|
37
|
-
const initialPageIndex = Math.max(
|
|
38
|
-
0,
|
|
39
|
-
Math.floor((schema.position.y - paddingTop) / pageContentHeight),
|
|
40
|
-
);
|
|
41
|
-
const headRowCount = schema.showHead ? table.head.length : 0;
|
|
42
|
-
const SAFETY_MARGIN = 0.5;
|
|
43
|
-
|
|
44
|
-
let currentPageIndex = initialPageIndex;
|
|
45
|
-
let currentPageY = schema.position.y;
|
|
46
|
-
let rowsOnCurrentPage = 0;
|
|
47
|
-
|
|
48
|
-
const result: number[] = [];
|
|
49
|
-
|
|
50
|
-
for (let i = 0; i < baseHeights.length; i++) {
|
|
51
|
-
const isBodyRow = i >= headRowCount;
|
|
52
|
-
const rowHeight = baseHeights[i];
|
|
53
|
-
|
|
54
|
-
while (true) {
|
|
55
|
-
const currentPageStartY = getPageStartY(currentPageIndex);
|
|
56
|
-
const remainingHeight = currentPageStartY + pageContentHeight - currentPageY;
|
|
57
|
-
const needsHeader =
|
|
58
|
-
isBodyRow && rowsOnCurrentPage === 0 && currentPageIndex > initialPageIndex;
|
|
59
|
-
const totalRowHeight = rowHeight + (needsHeader ? headerHeight : 0);
|
|
60
|
-
|
|
61
|
-
if (totalRowHeight > remainingHeight - SAFETY_MARGIN) {
|
|
62
|
-
if (rowsOnCurrentPage === 0 && Math.abs(currentPageY - currentPageStartY) < SAFETY_MARGIN) {
|
|
63
|
-
result.push(totalRowHeight);
|
|
64
|
-
currentPageY += totalRowHeight;
|
|
65
|
-
rowsOnCurrentPage++;
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
currentPageIndex++;
|
|
69
|
-
currentPageY = getPageStartY(currentPageIndex);
|
|
70
|
-
rowsOnCurrentPage = 0;
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
result.push(totalRowHeight);
|
|
75
|
-
currentPageY += totalRowHeight;
|
|
76
|
-
rowsOnCurrentPage++;
|
|
77
|
-
|
|
78
|
-
if (currentPageY >= currentPageStartY + pageContentHeight - SAFETY_MARGIN) {
|
|
79
|
-
currentPageIndex++;
|
|
80
|
-
currentPageY = getPageStartY(currentPageIndex);
|
|
81
|
-
rowsOnCurrentPage = 0;
|
|
82
|
-
}
|
|
83
|
-
break;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return result;
|
|
88
|
-
};
|
package/src/tables/helper.ts
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DEFAULT_ALIGNMENT,
|
|
3
|
-
DEFAULT_FONT_SIZE,
|
|
4
|
-
DEFAULT_LINE_HEIGHT,
|
|
5
|
-
DEFAULT_CHARACTER_SPACING,
|
|
6
|
-
DEFAULT_FONT_COLOR,
|
|
7
|
-
ALIGN_RIGHT,
|
|
8
|
-
ALIGN_CENTER,
|
|
9
|
-
ALIGN_LEFT,
|
|
10
|
-
VERTICAL_ALIGN_TOP,
|
|
11
|
-
VERTICAL_ALIGN_MIDDLE,
|
|
12
|
-
VERTICAL_ALIGN_BOTTOM,
|
|
13
|
-
} from '../text/constants.js';
|
|
14
|
-
import { HEX_COLOR_PATTERN } from '../constants.js';
|
|
15
|
-
|
|
16
|
-
export const getDefaultCellStyles = () => ({
|
|
17
|
-
fontName: undefined,
|
|
18
|
-
alignment: DEFAULT_ALIGNMENT,
|
|
19
|
-
verticalAlignment: VERTICAL_ALIGN_MIDDLE,
|
|
20
|
-
fontSize: DEFAULT_FONT_SIZE,
|
|
21
|
-
lineHeight: DEFAULT_LINE_HEIGHT,
|
|
22
|
-
characterSpacing: DEFAULT_CHARACTER_SPACING,
|
|
23
|
-
fontColor: DEFAULT_FONT_COLOR,
|
|
24
|
-
backgroundColor: '',
|
|
25
|
-
borderColor: '#888888',
|
|
26
|
-
borderWidth: { top: 0.1, bottom: 0.1, left: 0.1, right: 0.1 },
|
|
27
|
-
padding: { top: 5, bottom: 5, left: 5, right: 5 },
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const getBoxDimensionProp = (step = 1) => {
|
|
31
|
-
const getCommonProp = () => ({
|
|
32
|
-
type: 'number',
|
|
33
|
-
widget: 'inputNumber',
|
|
34
|
-
props: { min: 0, step },
|
|
35
|
-
span: 6,
|
|
36
|
-
});
|
|
37
|
-
return {
|
|
38
|
-
top: { title: 'Top', ...getCommonProp() },
|
|
39
|
-
right: { title: 'Right', ...getCommonProp() },
|
|
40
|
-
bottom: { title: 'Bottom', ...getCommonProp() },
|
|
41
|
-
left: { title: 'Left', ...getCommonProp() },
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const getCellPropPanelSchema = (arg: {
|
|
46
|
-
i18n: (key: string) => string;
|
|
47
|
-
fallbackFontName: string;
|
|
48
|
-
fontNames: string[];
|
|
49
|
-
isBody?: boolean;
|
|
50
|
-
}) => {
|
|
51
|
-
const { i18n, fallbackFontName, fontNames, isBody } = arg;
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
fontName: {
|
|
55
|
-
title: i18n('schemas.text.fontName'),
|
|
56
|
-
type: 'string',
|
|
57
|
-
widget: 'select',
|
|
58
|
-
default: fallbackFontName,
|
|
59
|
-
placeholder: fallbackFontName,
|
|
60
|
-
props: { options: fontNames.map((name) => ({ label: name, value: name })) },
|
|
61
|
-
span: 12,
|
|
62
|
-
},
|
|
63
|
-
fontSize: {
|
|
64
|
-
title: i18n('schemas.text.size'),
|
|
65
|
-
type: 'number',
|
|
66
|
-
widget: 'inputNumber',
|
|
67
|
-
props: { min: 0 },
|
|
68
|
-
span: 6,
|
|
69
|
-
},
|
|
70
|
-
characterSpacing: {
|
|
71
|
-
title: i18n('schemas.text.spacing'),
|
|
72
|
-
type: 'number',
|
|
73
|
-
widget: 'inputNumber',
|
|
74
|
-
props: { min: 0 },
|
|
75
|
-
span: 6,
|
|
76
|
-
},
|
|
77
|
-
alignment: {
|
|
78
|
-
title: i18n('schemas.text.textAlign'),
|
|
79
|
-
type: 'string',
|
|
80
|
-
widget: 'select',
|
|
81
|
-
props: {
|
|
82
|
-
options: [
|
|
83
|
-
{ label: i18n('schemas.left'), value: ALIGN_LEFT },
|
|
84
|
-
{ label: i18n('schemas.center'), value: ALIGN_CENTER },
|
|
85
|
-
{ label: i18n('schemas.right'), value: ALIGN_RIGHT },
|
|
86
|
-
],
|
|
87
|
-
},
|
|
88
|
-
span: 8,
|
|
89
|
-
},
|
|
90
|
-
verticalAlignment: {
|
|
91
|
-
title: i18n('schemas.text.verticalAlign'),
|
|
92
|
-
type: 'string',
|
|
93
|
-
widget: 'select',
|
|
94
|
-
props: {
|
|
95
|
-
options: [
|
|
96
|
-
{ label: i18n('schemas.top'), value: VERTICAL_ALIGN_TOP },
|
|
97
|
-
{ label: i18n('schemas.middle'), value: VERTICAL_ALIGN_MIDDLE },
|
|
98
|
-
{ label: i18n('schemas.bottom'), value: VERTICAL_ALIGN_BOTTOM },
|
|
99
|
-
],
|
|
100
|
-
},
|
|
101
|
-
span: 8,
|
|
102
|
-
},
|
|
103
|
-
lineHeight: {
|
|
104
|
-
title: i18n('schemas.text.lineHeight'),
|
|
105
|
-
type: 'number',
|
|
106
|
-
widget: 'inputNumber',
|
|
107
|
-
props: { step: 0.1, min: 0 },
|
|
108
|
-
span: 8,
|
|
109
|
-
},
|
|
110
|
-
fontColor: {
|
|
111
|
-
title: i18n('schemas.textColor'),
|
|
112
|
-
type: 'string',
|
|
113
|
-
widget: 'color',
|
|
114
|
-
props: {
|
|
115
|
-
disabledAlpha: true,
|
|
116
|
-
},
|
|
117
|
-
rules: [{ pattern: HEX_COLOR_PATTERN, message: i18n('validation.hexColor') }],
|
|
118
|
-
},
|
|
119
|
-
borderColor: {
|
|
120
|
-
title: i18n('schemas.borderColor'),
|
|
121
|
-
type: 'string',
|
|
122
|
-
widget: 'color',
|
|
123
|
-
props: {
|
|
124
|
-
disabledAlpha: true,
|
|
125
|
-
},
|
|
126
|
-
rules: [{ pattern: HEX_COLOR_PATTERN, message: i18n('validation.hexColor') }],
|
|
127
|
-
},
|
|
128
|
-
backgroundColor: {
|
|
129
|
-
title: i18n('schemas.backgroundColor'),
|
|
130
|
-
type: 'string',
|
|
131
|
-
widget: 'color',
|
|
132
|
-
props: {
|
|
133
|
-
disabledAlpha: true,
|
|
134
|
-
},
|
|
135
|
-
rules: [{ pattern: HEX_COLOR_PATTERN, message: i18n('validation.hexColor') }],
|
|
136
|
-
},
|
|
137
|
-
...(isBody
|
|
138
|
-
? {
|
|
139
|
-
alternateBackgroundColor: {
|
|
140
|
-
title: i18n('schemas.table.alternateBackgroundColor'),
|
|
141
|
-
type: 'string',
|
|
142
|
-
widget: 'color',
|
|
143
|
-
props: {
|
|
144
|
-
disabledAlpha: true,
|
|
145
|
-
},
|
|
146
|
-
rules: [{ pattern: HEX_COLOR_PATTERN, message: i18n('validation.hexColor') }],
|
|
147
|
-
},
|
|
148
|
-
}
|
|
149
|
-
: {}),
|
|
150
|
-
'-': { type: 'void', widget: 'Divider' },
|
|
151
|
-
borderWidth: {
|
|
152
|
-
title: i18n('schemas.borderWidth'),
|
|
153
|
-
type: 'object',
|
|
154
|
-
widget: 'lineTitle',
|
|
155
|
-
span: 24,
|
|
156
|
-
properties: getBoxDimensionProp(0.1),
|
|
157
|
-
},
|
|
158
|
-
'--': { type: 'void', widget: 'Divider' },
|
|
159
|
-
padding: {
|
|
160
|
-
title: i18n('schemas.padding'),
|
|
161
|
-
type: 'object',
|
|
162
|
-
widget: 'lineTitle',
|
|
163
|
-
span: 24,
|
|
164
|
-
properties: getBoxDimensionProp(),
|
|
165
|
-
},
|
|
166
|
-
};
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
export const getColumnStylesPropPanelSchema = ({
|
|
170
|
-
head,
|
|
171
|
-
i18n,
|
|
172
|
-
}: {
|
|
173
|
-
head: string[];
|
|
174
|
-
i18n: (key: string) => string;
|
|
175
|
-
}) => ({
|
|
176
|
-
alignment: {
|
|
177
|
-
type: 'object',
|
|
178
|
-
widget: 'lineTitle',
|
|
179
|
-
title: i18n('schemas.text.textAlign'),
|
|
180
|
-
column: 3,
|
|
181
|
-
properties: head.reduce(
|
|
182
|
-
(acc, cur, i) =>
|
|
183
|
-
Object.assign(acc, {
|
|
184
|
-
[i]: {
|
|
185
|
-
title: cur || 'Column ' + String(i + 1),
|
|
186
|
-
type: 'string',
|
|
187
|
-
widget: 'select',
|
|
188
|
-
props: {
|
|
189
|
-
options: [
|
|
190
|
-
{ label: i18n('schemas.left'), value: ALIGN_LEFT },
|
|
191
|
-
{ label: i18n('schemas.center'), value: ALIGN_CENTER },
|
|
192
|
-
{ label: i18n('schemas.right'), value: ALIGN_RIGHT },
|
|
193
|
-
],
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
}),
|
|
197
|
-
{},
|
|
198
|
-
),
|
|
199
|
-
},
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
export const getBody = (value: string | string[][]): string[][] => {
|
|
203
|
-
if (typeof value === 'string') {
|
|
204
|
-
return JSON.parse(value || '[]') as string[][];
|
|
205
|
-
}
|
|
206
|
-
return value || [];
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
export const getBodyWithRange = (
|
|
210
|
-
value: string | string[][],
|
|
211
|
-
range?: { start: number; end?: number | undefined },
|
|
212
|
-
) => {
|
|
213
|
-
const body = getBody(value);
|
|
214
|
-
if (!range) return body;
|
|
215
|
-
return body.slice(range.start, range.end);
|
|
216
|
-
};
|