@flowaccount/pdfmake 1.0.5 → 1.0.6-staging.2
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/LICENSE +21 -21
- package/README.md +297 -297
- package/build/pdfmake.js +49968 -50213
- package/build/pdfmake.min.js +2 -2
- package/build/pdfmake.min.js.map +1 -1
- package/build/vfs_fonts.js +6 -6
- package/package.json +110 -110
- package/src/3rd-party/svg-to-pdfkit.js +3 -3
- package/src/browser-extensions/URLBrowserResolver.js +96 -96
- package/src/browser-extensions/pdfMake.js +361 -361
- package/src/browser-extensions/tokenizer-shim.js +15 -15
- package/src/browser-extensions/virtual-fs.js +55 -55
- package/src/columnCalculator.js +157 -157
- package/src/docMeasure.js +831 -831
- package/src/docPreprocessor.js +277 -277
- package/src/documentContext.js +383 -383
- package/src/elementWriter.js +442 -434
- package/src/fontProvider.js +68 -68
- package/src/helpers.js +138 -138
- package/src/imageMeasure.js +70 -70
- package/src/layoutBuilder.js +1998 -1770
- package/src/line.js +91 -91
- package/src/pageElementWriter.js +362 -362
- package/src/pdfKitEngine.js +21 -21
- package/src/printer.js +1191 -1191
- package/src/qrEnc.js +790 -790
- package/src/standardPageSizes.js +54 -54
- package/src/styleContextStack.js +138 -138
- package/src/svgMeasure.js +70 -70
- package/src/tableProcessor.js +791 -789
- package/src/textDecorator.js +157 -157
- package/src/textTools.js +442 -442
- package/src/traversalTracker.js +47 -47
package/src/tableProcessor.js
CHANGED
|
@@ -1,789 +1,791 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var ColumnCalculator = require('./columnCalculator');
|
|
4
|
-
var isFunction = require('./helpers').isFunction;
|
|
5
|
-
var isNumber = require('./helpers').isNumber;
|
|
6
|
-
var isPositiveInteger = require('./helpers').isPositiveInteger;
|
|
7
|
-
|
|
8
|
-
function TableProcessor(tableNode) {
|
|
9
|
-
this.tableNode = tableNode;
|
|
10
|
-
this.collectFooterColumns = Boolean(tableNode.footerGapCollect === 'product-items');
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
TableProcessor.prototype.beginTable = function (writer) {
|
|
14
|
-
var tableNode;
|
|
15
|
-
var availableWidth;
|
|
16
|
-
var self = this;
|
|
17
|
-
|
|
18
|
-
tableNode = this.tableNode;
|
|
19
|
-
this.offsets = tableNode._offsets;
|
|
20
|
-
this.layout = tableNode._layout;
|
|
21
|
-
this.beginNewPage = false;
|
|
22
|
-
|
|
23
|
-
if (tableNode.remark && writer.context().availableHeight) {
|
|
24
|
-
if (writer.context().availableHeight < 50) {
|
|
25
|
-
writer.context().moveDown(writer.context().availableHeight);
|
|
26
|
-
this.beginNewPage = true;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
availableWidth = writer.context().availableWidth - this.offsets.total;
|
|
31
|
-
ColumnCalculator.buildColumnWidths(tableNode.table.widths, availableWidth, this.offsets.total, tableNode);
|
|
32
|
-
|
|
33
|
-
const offsets = this.offsets || { left: 0 };
|
|
34
|
-
const leftOffset = offsets.left || 0;
|
|
35
|
-
|
|
36
|
-
this.tableWidth = tableNode._offsets.total + getTableInnerContentWidth();
|
|
37
|
-
this.rowSpanData = prepareRowSpanData();
|
|
38
|
-
this.cleanUpRepeatables = false;
|
|
39
|
-
|
|
40
|
-
// headersRows and rowsWithoutPageBreak (headerRows + keepWithHeaderRows)
|
|
41
|
-
this.headerRows = 0;
|
|
42
|
-
this.rowsWithoutPageBreak = 0;
|
|
43
|
-
|
|
44
|
-
var headerRows = tableNode.table.headerRows;
|
|
45
|
-
|
|
46
|
-
if (isPositiveInteger(headerRows)) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
var
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
rsd.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
cell
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
this.
|
|
177
|
-
this.
|
|
178
|
-
|
|
179
|
-
this.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
writer.context().
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
var
|
|
217
|
-
var
|
|
218
|
-
var
|
|
219
|
-
var
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
var
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
* @param {number}
|
|
328
|
-
* @param {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
var
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
if
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
// Store the
|
|
408
|
-
content.
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
var
|
|
422
|
-
var
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
var
|
|
490
|
-
var
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
writer.
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
var
|
|
505
|
-
|
|
506
|
-
var
|
|
507
|
-
|
|
508
|
-
var
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
ys.
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
var
|
|
541
|
-
var
|
|
542
|
-
var
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
var
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
var
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
widthRightBorder = this.layout.vLineWidth(colIndex + 1, this.tableNode)
|
|
621
|
-
} else {
|
|
622
|
-
widthRightBorder =
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
var
|
|
628
|
-
var
|
|
629
|
-
var
|
|
630
|
-
var
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
//
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
//
|
|
721
|
-
//
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
this.headerRepeatable
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var ColumnCalculator = require('./columnCalculator');
|
|
4
|
+
var isFunction = require('./helpers').isFunction;
|
|
5
|
+
var isNumber = require('./helpers').isNumber;
|
|
6
|
+
var isPositiveInteger = require('./helpers').isPositiveInteger;
|
|
7
|
+
|
|
8
|
+
function TableProcessor(tableNode) {
|
|
9
|
+
this.tableNode = tableNode;
|
|
10
|
+
this.collectFooterColumns = Boolean(tableNode.footerGapCollect === 'product-items');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
TableProcessor.prototype.beginTable = function (writer) {
|
|
14
|
+
var tableNode;
|
|
15
|
+
var availableWidth;
|
|
16
|
+
var self = this;
|
|
17
|
+
|
|
18
|
+
tableNode = this.tableNode;
|
|
19
|
+
this.offsets = tableNode._offsets;
|
|
20
|
+
this.layout = tableNode._layout;
|
|
21
|
+
this.beginNewPage = false;
|
|
22
|
+
|
|
23
|
+
if (tableNode.remark && writer.context().availableHeight) {
|
|
24
|
+
if (writer.context().availableHeight < 50) {
|
|
25
|
+
writer.context().moveDown(writer.context().availableHeight);
|
|
26
|
+
this.beginNewPage = true;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
availableWidth = writer.context().availableWidth - this.offsets.total;
|
|
31
|
+
ColumnCalculator.buildColumnWidths(tableNode.table.widths, availableWidth, this.offsets.total, tableNode);
|
|
32
|
+
|
|
33
|
+
const offsets = this.offsets || { left: 0 };
|
|
34
|
+
const leftOffset = offsets.left || 0;
|
|
35
|
+
|
|
36
|
+
this.tableWidth = tableNode._offsets.total + getTableInnerContentWidth();
|
|
37
|
+
this.rowSpanData = prepareRowSpanData();
|
|
38
|
+
this.cleanUpRepeatables = false;
|
|
39
|
+
|
|
40
|
+
// headersRows and rowsWithoutPageBreak (headerRows + keepWithHeaderRows)
|
|
41
|
+
this.headerRows = 0;
|
|
42
|
+
this.rowsWithoutPageBreak = 0;
|
|
43
|
+
|
|
44
|
+
var headerRows = tableNode.table.headerRows;
|
|
45
|
+
|
|
46
|
+
if (isPositiveInteger(headerRows)) {
|
|
47
|
+
// Fix: If headerRows exceeds available rows, adjust to match body length
|
|
48
|
+
// This prevents errors when tables have empty bodies
|
|
49
|
+
if (headerRows > tableNode.table.body.length) {
|
|
50
|
+
this.headerRows = tableNode.table.body.length;
|
|
51
|
+
} else {
|
|
52
|
+
this.headerRows = headerRows;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this.rowsWithoutPageBreak = this.headerRows;
|
|
56
|
+
|
|
57
|
+
const keepWithHeaderRows = tableNode.table.keepWithHeaderRows;
|
|
58
|
+
|
|
59
|
+
if (isPositiveInteger(keepWithHeaderRows)) {
|
|
60
|
+
this.rowsWithoutPageBreak += keepWithHeaderRows;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.dontBreakRows = tableNode.table.dontBreakRows || false;
|
|
65
|
+
|
|
66
|
+
if (this.rowsWithoutPageBreak || this.dontBreakRows) {
|
|
67
|
+
writer.beginUnbreakableBlock();
|
|
68
|
+
// Draw the top border of the table
|
|
69
|
+
this.drawHorizontalLine(0, writer);
|
|
70
|
+
if (this.rowsWithoutPageBreak && this.dontBreakRows) {
|
|
71
|
+
writer.beginUnbreakableBlock();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// update the border properties of all cells before drawing any lines
|
|
76
|
+
prepareCellBorders(this.tableNode.table.body);
|
|
77
|
+
|
|
78
|
+
function getTableInnerContentWidth() {
|
|
79
|
+
var width = 0;
|
|
80
|
+
|
|
81
|
+
tableNode.table.widths.forEach(function (w) {
|
|
82
|
+
width += w._calcWidth;
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return width;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function prepareRowSpanData() {
|
|
89
|
+
var rsd = [];
|
|
90
|
+
var x = 0;
|
|
91
|
+
var lastWidth = 0;
|
|
92
|
+
|
|
93
|
+
rsd.push({ left: 0, rowSpan: 0 });
|
|
94
|
+
|
|
95
|
+
if (!self.tableNode.table.body[0]) {
|
|
96
|
+
return rsd;
|
|
97
|
+
}
|
|
98
|
+
for (var i = 0, l = self.tableNode.table.body[0].length; i < l; i++) {
|
|
99
|
+
var paddings = self.layout.paddingLeft(i, self.tableNode) + self.layout.paddingRight(i, self.tableNode);
|
|
100
|
+
var lBorder = self.layout.vLineWidth(i, self.tableNode);
|
|
101
|
+
lastWidth = paddings + lBorder + self.tableNode.table.widths[i]._calcWidth;
|
|
102
|
+
rsd[rsd.length - 1].width = lastWidth;
|
|
103
|
+
x += lastWidth;
|
|
104
|
+
rsd.push({ left: x, rowSpan: 0, width: 0 });
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return rsd;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Iterate through all cells. If the current cell is the start of a
|
|
111
|
+
// rowSpan/colSpan, update the border property of the cells on its
|
|
112
|
+
// bottom/right accordingly. This is needed since each iteration of the
|
|
113
|
+
// line-drawing loops draws lines for a single cell, not for an entire
|
|
114
|
+
// rowSpan/colSpan.
|
|
115
|
+
function prepareCellBorders(body) {
|
|
116
|
+
for (var rowIndex = 0; rowIndex < body.length; rowIndex++) {
|
|
117
|
+
var row = body[rowIndex];
|
|
118
|
+
|
|
119
|
+
for (var colIndex = 0; colIndex < row.length; colIndex++) {
|
|
120
|
+
var cell = row[colIndex];
|
|
121
|
+
|
|
122
|
+
if (cell.border) {
|
|
123
|
+
var rowSpan = cell.rowSpan || 1;
|
|
124
|
+
var colSpan = cell.colSpan || 1;
|
|
125
|
+
|
|
126
|
+
for (var rowOffset = 0; rowOffset < rowSpan; rowOffset++) {
|
|
127
|
+
// set left border
|
|
128
|
+
if (cell.border[0] !== undefined && rowOffset > 0) {
|
|
129
|
+
setBorder(rowIndex + rowOffset, colIndex, 0, cell.border[0]);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// set right border
|
|
133
|
+
if (cell.border[2] !== undefined) {
|
|
134
|
+
setBorder(rowIndex + rowOffset, colIndex + colSpan - 1, 2, cell.border[2]);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
for (var colOffset = 0; colOffset < colSpan; colOffset++) {
|
|
139
|
+
// set top border
|
|
140
|
+
if (cell.border[1] !== undefined && colOffset > 0) {
|
|
141
|
+
setBorder(rowIndex, colIndex + colOffset, 1, cell.border[1]);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// set bottom border
|
|
145
|
+
if (cell.border[3] !== undefined) {
|
|
146
|
+
setBorder(rowIndex + rowSpan - 1, colIndex + colOffset, 3, cell.border[3]);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// helper function to set the border for a given cell
|
|
154
|
+
function setBorder(rowIndex, colIndex, borderIndex, borderValue) {
|
|
155
|
+
var cell = body[rowIndex][colIndex];
|
|
156
|
+
cell.border = cell.border || {};
|
|
157
|
+
cell.border[borderIndex] = borderValue;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
TableProcessor.prototype.onRowBreak = function (rowIndex, writer) {
|
|
163
|
+
var self = this;
|
|
164
|
+
return function () {
|
|
165
|
+
var offset = self.rowPaddingTop + (!self.headerRows ? self.topLineWidth : 0);
|
|
166
|
+
var currentPage = writer.context().getCurrentPage && writer.context().getCurrentPage();
|
|
167
|
+
if (currentPage && currentPage.items[0] && currentPage.items[0].item.remark) {
|
|
168
|
+
currentPage.items[0].item.lineColor = '#d5d5d5';
|
|
169
|
+
}
|
|
170
|
+
writer.context().availableHeight -= self.reservedAtBottom;
|
|
171
|
+
writer.context().moveDown(offset);
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
TableProcessor.prototype.beginRow = function (rowIndex, writer) {
|
|
176
|
+
this.topLineWidth = this.layout.hLineWidth(rowIndex, this.tableNode, writer);
|
|
177
|
+
this.rowPaddingTop = this.layout.paddingTop(rowIndex, this.tableNode);
|
|
178
|
+
this.bottomLineWidth = this.layout.hLineWidth(rowIndex + 1, this.tableNode, writer);
|
|
179
|
+
this.rowPaddingBottom = this.layout.paddingBottom(rowIndex, this.tableNode);
|
|
180
|
+
|
|
181
|
+
this.rowCallback = this.onRowBreak(rowIndex, writer);
|
|
182
|
+
|
|
183
|
+
if(this.tableNode.eventHandle && this.tableNode.eventHandle.beforePageChanged)
|
|
184
|
+
{
|
|
185
|
+
|
|
186
|
+
this.beforePageChanged = this.tableNode.eventHandle.beforePageChanged(this, rowIndex, writer);
|
|
187
|
+
writer.tracker.startTracking('beforePageChanged', this.beforePageChanged);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
writer.tracker.startTracking('pageChanged', this.rowCallback);
|
|
191
|
+
if (rowIndex == 0 && !this.dontBreakRows && !this.rowsWithoutPageBreak) {
|
|
192
|
+
// We store the 'y' to draw later and if necessary the top border of the table
|
|
193
|
+
this._tableTopBorderY = writer.context().y;
|
|
194
|
+
writer.context().moveDown(this.topLineWidth);
|
|
195
|
+
}
|
|
196
|
+
if (this.dontBreakRows && rowIndex > 0) {
|
|
197
|
+
writer.beginUnbreakableBlock();
|
|
198
|
+
}
|
|
199
|
+
this.rowTopY = writer.context().y;
|
|
200
|
+
this.reservedAtBottom = this.bottomLineWidth + this.rowPaddingBottom;
|
|
201
|
+
|
|
202
|
+
writer.context().availableHeight -= this.reservedAtBottom;
|
|
203
|
+
|
|
204
|
+
writer.context().moveDown(this.rowPaddingTop);
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
TableProcessor.prototype.drawHorizontalLine = function (lineIndex, writer, overrideY, moveDown = true, forcePage, isPageBreak = false) {
|
|
208
|
+
var lineWidth = this.layout.hLineWidth(lineIndex, this.tableNode, writer, isPageBreak);
|
|
209
|
+
if (lineWidth) {
|
|
210
|
+
var style = this.layout.hLineStyle(lineIndex, this.tableNode);
|
|
211
|
+
var dash;
|
|
212
|
+
if (style && style.dash) {
|
|
213
|
+
dash = style.dash;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
var offset = lineWidth / 2;
|
|
217
|
+
var currentLine = null;
|
|
218
|
+
var body = this.tableNode.table.body;
|
|
219
|
+
var cellAbove;
|
|
220
|
+
var currentCell;
|
|
221
|
+
var rowCellAbove;
|
|
222
|
+
|
|
223
|
+
for (var i = 0, l = this.rowSpanData.length; i < l; i++) {
|
|
224
|
+
var data = this.rowSpanData[i];
|
|
225
|
+
var shouldDrawLine = !data.rowSpan;
|
|
226
|
+
var borderColor = null;
|
|
227
|
+
|
|
228
|
+
// draw only if the current cell requires a top border or the cell in the
|
|
229
|
+
// row above requires a bottom border
|
|
230
|
+
if (shouldDrawLine && i < l - 1) {
|
|
231
|
+
var topBorder = false, bottomBorder = false, rowBottomBorder = false;
|
|
232
|
+
|
|
233
|
+
// the cell in the row above
|
|
234
|
+
if (lineIndex > 0) {
|
|
235
|
+
cellAbove = body[lineIndex - 1][i];
|
|
236
|
+
bottomBorder = cellAbove.border ? cellAbove.border[3] : this.layout.defaultBorder;
|
|
237
|
+
if (bottomBorder && cellAbove.borderColor) {
|
|
238
|
+
borderColor = cellAbove.borderColor[3];
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// the current cell
|
|
243
|
+
if (lineIndex < body.length) {
|
|
244
|
+
currentCell = body[lineIndex][i];
|
|
245
|
+
topBorder = currentCell.border ? currentCell.border[1] : this.layout.defaultBorder;
|
|
246
|
+
if (topBorder && borderColor == null && currentCell.borderColor) {
|
|
247
|
+
borderColor = currentCell.borderColor[1];
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
shouldDrawLine = topBorder || bottomBorder;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (cellAbove && cellAbove._rowSpanCurrentOffset) {
|
|
255
|
+
rowCellAbove = body[lineIndex - 1 - cellAbove._rowSpanCurrentOffset][i];
|
|
256
|
+
rowBottomBorder = rowCellAbove && rowCellAbove.border ? rowCellAbove.border[3] : this.layout.defaultBorder;
|
|
257
|
+
if (rowBottomBorder && rowCellAbove && rowCellAbove.borderColor) {
|
|
258
|
+
borderColor = rowCellAbove.borderColor[3];
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (borderColor == null) {
|
|
263
|
+
borderColor = isFunction(this.layout.hLineColor) ? this.layout.hLineColor(lineIndex, this.tableNode, i, this.beginNewPage) : this.layout.hLineColor;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (!currentLine && shouldDrawLine) {
|
|
267
|
+
currentLine = { left: data.left, width: 0 };
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (shouldDrawLine) {
|
|
271
|
+
var colSpanIndex = 0;
|
|
272
|
+
if (rowCellAbove && rowCellAbove.colSpan && rowBottomBorder) {
|
|
273
|
+
while (rowCellAbove.colSpan > colSpanIndex) {
|
|
274
|
+
currentLine.width += (this.rowSpanData[i + colSpanIndex++].width || 0);
|
|
275
|
+
}
|
|
276
|
+
i += colSpanIndex - 1;
|
|
277
|
+
} else if (cellAbove && cellAbove.colSpan && bottomBorder) {
|
|
278
|
+
while (cellAbove.colSpan > colSpanIndex) {
|
|
279
|
+
currentLine.width += (this.rowSpanData[i + colSpanIndex++].width || 0);
|
|
280
|
+
}
|
|
281
|
+
i += colSpanIndex - 1;
|
|
282
|
+
} else if (currentCell && currentCell.colSpan && topBorder) {
|
|
283
|
+
while (currentCell.colSpan > colSpanIndex) {
|
|
284
|
+
currentLine.width += (this.rowSpanData[i + colSpanIndex++].width || 0);
|
|
285
|
+
}
|
|
286
|
+
i += colSpanIndex - 1;
|
|
287
|
+
} else {
|
|
288
|
+
currentLine.width += (this.rowSpanData[i].width || 0);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
var y = (overrideY || 0) + offset;
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
if (shouldDrawLine) {
|
|
296
|
+
if (currentLine && currentLine.width) {
|
|
297
|
+
writer.addVector({
|
|
298
|
+
type: 'line',
|
|
299
|
+
remark: this.tableNode.remark,
|
|
300
|
+
x1: currentLine.left,
|
|
301
|
+
x2: currentLine.left + currentLine.width,
|
|
302
|
+
y1: y,
|
|
303
|
+
y2: y,
|
|
304
|
+
lineWidth: lineWidth,
|
|
305
|
+
dash: dash,
|
|
306
|
+
lineColor: borderColor
|
|
307
|
+
}, false, isNumber(overrideY), null, forcePage);
|
|
308
|
+
currentLine = null;
|
|
309
|
+
borderColor = null;
|
|
310
|
+
cellAbove = null;
|
|
311
|
+
currentCell = null;
|
|
312
|
+
rowCellAbove = null;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (moveDown) {
|
|
318
|
+
writer.context().moveDown(lineWidth);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Draws vertical lines to fill the gap when a row is forced to the next page.
|
|
326
|
+
* This prevents missing vertical lines at the bottom of the page.
|
|
327
|
+
* @param {number} rowIndex - The index of the row being forced to next page
|
|
328
|
+
* @param {object} writer - The document writer
|
|
329
|
+
* @param {number} y0 - Starting Y position
|
|
330
|
+
* @param {number} y1 - Ending Y position (page break point)
|
|
331
|
+
*/
|
|
332
|
+
TableProcessor.prototype.drawVerticalLinesForForcedPageBreak = function (rowIndex, writer, y0, y1) {
|
|
333
|
+
if (!this.rowSpanData || rowIndex <= 0) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
var body = this.tableNode.table.body;
|
|
338
|
+
var prevRowIndex = rowIndex - 1; // Use previous row for cell border detection
|
|
339
|
+
|
|
340
|
+
// Get X positions for vertical lines (similar logic to endRow's getLineXs)
|
|
341
|
+
var xs = [];
|
|
342
|
+
var cols = 0;
|
|
343
|
+
|
|
344
|
+
for (var i = 0, l = body[prevRowIndex].length; i < l; i++) {
|
|
345
|
+
if (!cols) {
|
|
346
|
+
xs.push({ x: this.rowSpanData[i].left, index: i });
|
|
347
|
+
var item = body[prevRowIndex][i];
|
|
348
|
+
cols = (item._colSpan || item.colSpan || 0);
|
|
349
|
+
}
|
|
350
|
+
if (cols > 0) {
|
|
351
|
+
cols--;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
xs.push({ x: this.rowSpanData[this.rowSpanData.length - 1].left, index: this.rowSpanData.length - 1 });
|
|
355
|
+
|
|
356
|
+
// Draw vertical lines for each column position
|
|
357
|
+
for (var xi = 0, xl = xs.length; xi < xl; xi++) {
|
|
358
|
+
var leftCellBorder = false;
|
|
359
|
+
var colIndex = xs[xi].index;
|
|
360
|
+
|
|
361
|
+
// Check if we need to draw a vertical line at this position
|
|
362
|
+
// based on cell borders from the previous row
|
|
363
|
+
var cell;
|
|
364
|
+
if (colIndex < body[prevRowIndex].length) {
|
|
365
|
+
cell = body[prevRowIndex][colIndex];
|
|
366
|
+
leftCellBorder = cell.border ? cell.border[0] : this.layout.defaultBorder;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Check cell before
|
|
370
|
+
if (colIndex > 0 && !leftCellBorder) {
|
|
371
|
+
cell = body[prevRowIndex][colIndex - 1];
|
|
372
|
+
leftCellBorder = cell.border ? cell.border[2] : this.layout.defaultBorder;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (leftCellBorder) {
|
|
376
|
+
this.drawVerticalLine(
|
|
377
|
+
xs[xi].x,
|
|
378
|
+
y0,
|
|
379
|
+
y1,
|
|
380
|
+
xs[xi].index,
|
|
381
|
+
writer,
|
|
382
|
+
prevRowIndex,
|
|
383
|
+
xi > 0 ? xs[xi - 1].index : null
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
TableProcessor.prototype.drawVerticalLine = function (x, y0, y1, vLineColIndex, writer, vLineRowIndex, beforeVLineColIndex) {
|
|
390
|
+
var width = this.layout.vLineWidth(vLineColIndex, this.tableNode);
|
|
391
|
+
if (width === 0) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
var ctx = writer && typeof writer.context === 'function' ? writer.context() : null;
|
|
396
|
+
if (ctx && this.collectFooterColumns) {
|
|
397
|
+
var footerOpt = ctx._footerGapOption;
|
|
398
|
+
if (footerOpt && footerOpt.enabled) {
|
|
399
|
+
var columns = footerOpt.columns || (footerOpt.columns = {});
|
|
400
|
+
var content = columns.content || (columns.content = { vLines: [], vLineWidths: [] });
|
|
401
|
+
var contentVLinesLength = content.vLines.length || 0;
|
|
402
|
+
var widthLength = footerOpt.columns.widthLength || 0;
|
|
403
|
+
|
|
404
|
+
// Only collect if we haven't exceeded the width length
|
|
405
|
+
// Need widthLength + 1 lines to include both left and right borders
|
|
406
|
+
if(widthLength === 0 || contentVLinesLength <= widthLength){
|
|
407
|
+
// Store the base X position (without width offset)
|
|
408
|
+
content.vLines.push((ctx.x || 0) + x);
|
|
409
|
+
// Store the actual line width used by the table
|
|
410
|
+
content.vLineWidths.push(width);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
var style = this.layout.vLineStyle(vLineColIndex, this.tableNode);
|
|
416
|
+
var dash;
|
|
417
|
+
if (style && style.dash) {
|
|
418
|
+
dash = style.dash;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
var body = this.tableNode.table.body;
|
|
422
|
+
var cellBefore;
|
|
423
|
+
var currentCell;
|
|
424
|
+
var borderColor;
|
|
425
|
+
|
|
426
|
+
// the cell in the col before
|
|
427
|
+
if (vLineColIndex > 0) {
|
|
428
|
+
cellBefore = body[vLineRowIndex][beforeVLineColIndex];
|
|
429
|
+
if (cellBefore && cellBefore.borderColor) {
|
|
430
|
+
if (cellBefore.border ? cellBefore.border[2] : this.layout.defaultBorder) {
|
|
431
|
+
borderColor = cellBefore.borderColor[2];
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// the current cell
|
|
437
|
+
if (borderColor == null && vLineColIndex < body.length) {
|
|
438
|
+
currentCell = body[vLineRowIndex][vLineColIndex];
|
|
439
|
+
if (currentCell && currentCell.borderColor) {
|
|
440
|
+
if (currentCell.border ? currentCell.border[0] : this.layout.defaultBorder) {
|
|
441
|
+
borderColor = currentCell.borderColor[0];
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
if (borderColor == null && cellBefore && cellBefore._rowSpanCurrentOffset) {
|
|
447
|
+
var rowCellBeforeAbove = body[vLineRowIndex - cellBefore._rowSpanCurrentOffset][beforeVLineColIndex];
|
|
448
|
+
if (rowCellBeforeAbove.borderColor) {
|
|
449
|
+
if (rowCellBeforeAbove.border ? rowCellBeforeAbove.border[2] : this.layout.defaultBorder) {
|
|
450
|
+
borderColor = rowCellBeforeAbove.borderColor[2];
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (borderColor == null && currentCell && currentCell._rowSpanCurrentOffset) {
|
|
456
|
+
var rowCurrentCellAbove = body[vLineRowIndex - currentCell._rowSpanCurrentOffset][vLineColIndex];
|
|
457
|
+
if (rowCurrentCellAbove.borderColor) {
|
|
458
|
+
if (rowCurrentCellAbove.border ? rowCurrentCellAbove.border[2] : this.layout.defaultBorder) {
|
|
459
|
+
borderColor = rowCurrentCellAbove.borderColor[2];
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
if (borderColor == null) {
|
|
465
|
+
borderColor = isFunction(this.layout.vLineColor) ? this.layout.vLineColor(vLineColIndex, this.tableNode, vLineRowIndex) : this.layout.vLineColor;
|
|
466
|
+
}
|
|
467
|
+
writer.addVector({
|
|
468
|
+
type: 'line',
|
|
469
|
+
x1: x + width / 2,
|
|
470
|
+
x2: x + width / 2,
|
|
471
|
+
y1: y0,
|
|
472
|
+
y2: y1,
|
|
473
|
+
lineWidth: width,
|
|
474
|
+
dash: dash,
|
|
475
|
+
lineColor: borderColor
|
|
476
|
+
}, false, true);
|
|
477
|
+
cellBefore = null;
|
|
478
|
+
currentCell = null;
|
|
479
|
+
borderColor = null;
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
TableProcessor.prototype.endTable = function (writer) {
|
|
483
|
+
if (this.cleanUpRepeatables) {
|
|
484
|
+
writer.popFromRepeatables();
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
TableProcessor.prototype.endRow = function (rowIndex, writer, pageBreaks, nextRowCells, layoutBuilder) {
|
|
489
|
+
var l, i;
|
|
490
|
+
var self = this;
|
|
491
|
+
var tableLayout = this.tableNode && this.tableNode._layout;
|
|
492
|
+
var nearBottomThreshold = (tableLayout && tableLayout.nearBottomThreshold) || 20;
|
|
493
|
+
|
|
494
|
+
if(this.tableNode.eventHandle && this.tableNode.eventHandle.beforePageChanged)
|
|
495
|
+
{
|
|
496
|
+
writer.tracker.stopTracking('beforePageChanged', this.beforePageChanged);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
writer.tracker.stopTracking('pageChanged', this.rowCallback);
|
|
500
|
+
writer.context().moveDown(this.layout.paddingBottom(rowIndex, this.tableNode));
|
|
501
|
+
writer.context().availableHeight += this.reservedAtBottom;
|
|
502
|
+
|
|
503
|
+
var endingPage = writer.context().page;
|
|
504
|
+
var endingY = writer.context().y;
|
|
505
|
+
|
|
506
|
+
var xs = getLineXs();
|
|
507
|
+
|
|
508
|
+
var ys = [];
|
|
509
|
+
|
|
510
|
+
var hasBreaks = pageBreaks && pageBreaks.length > 0;
|
|
511
|
+
var body = this.tableNode.table.body;
|
|
512
|
+
|
|
513
|
+
ys.push({
|
|
514
|
+
y0: this.rowTopY,
|
|
515
|
+
page: hasBreaks ? pageBreaks[0].prevPage : endingPage
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
if (hasBreaks) {
|
|
519
|
+
for (i = 0, l = pageBreaks.length; i < l; i++) {
|
|
520
|
+
var pageBreak = pageBreaks[i];
|
|
521
|
+
ys[ys.length - 1].y1 = pageBreak.prevY;
|
|
522
|
+
|
|
523
|
+
ys.push({ y0: pageBreak.y, page: pageBreak.prevPage + 1, forced: pageBreak.forced });
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
ys[ys.length - 1].y1 = endingY;
|
|
528
|
+
|
|
529
|
+
var skipOrphanePadding = this.rowPaddingTop > 0 && (ys[0].y1 - ys[0].y0 === this.rowPaddingTop);
|
|
530
|
+
if (rowIndex === 0 && !skipOrphanePadding && !this.rowsWithoutPageBreak && !this.dontBreakRows) {
|
|
531
|
+
// Draw the top border of the table
|
|
532
|
+
var pageTableStartedAt = null;
|
|
533
|
+
if (pageBreaks && pageBreaks.length > 0) {
|
|
534
|
+
// Get the page where table started at
|
|
535
|
+
pageTableStartedAt = pageBreaks[0].prevPage;
|
|
536
|
+
}
|
|
537
|
+
this.drawHorizontalLine(0, writer, this._tableTopBorderY, false, pageTableStartedAt);
|
|
538
|
+
}
|
|
539
|
+
for (var yi = (skipOrphanePadding ? 1 : 0), yl = ys.length; yi < yl; yi++) {
|
|
540
|
+
var willBreak = yi < ys.length - 1;
|
|
541
|
+
var rowBreakWithoutHeader = (yi > 0 && !this.headerRows);
|
|
542
|
+
var hzLineOffset = rowBreakWithoutHeader ? 0 : this.topLineWidth;
|
|
543
|
+
var y1 = ys[yi].y0;
|
|
544
|
+
var y2 = ys[yi].y1;
|
|
545
|
+
|
|
546
|
+
if (willBreak) {
|
|
547
|
+
y2 = y2 + this.rowPaddingBottom;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
if (writer.context().page != ys[yi].page) {
|
|
551
|
+
writer.context().page = ys[yi].page;
|
|
552
|
+
|
|
553
|
+
//TODO: buggy, availableHeight should be updated on every pageChanged event
|
|
554
|
+
// TableProcessor should be pageChanged listener, instead of processRow
|
|
555
|
+
this.reservedAtBottom = 0;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// Draw horizontal lines before the vertical lines so they are not overridden
|
|
559
|
+
// Only set isPageBreak=true when at TRUE page bottom (not just forced breaks)
|
|
560
|
+
var ctx = writer.context();
|
|
561
|
+
var currentPage = ctx.getCurrentPage && ctx.getCurrentPage();
|
|
562
|
+
var pageHeight = currentPage ? (currentPage.pageSize.height - ctx.pageMargins.bottom) : 0;
|
|
563
|
+
|
|
564
|
+
if (willBreak && this.layout.hLineWhenBroken !== false) {
|
|
565
|
+
// Check if we're at the true page bottom
|
|
566
|
+
var isAtTruePageBottom = (pageHeight - y2) <= nearBottomThreshold;
|
|
567
|
+
this.drawHorizontalLine(rowIndex + 1, writer, y2, true, null, isAtTruePageBottom);
|
|
568
|
+
}
|
|
569
|
+
if (rowBreakWithoutHeader && this.layout.hLineWhenBroken !== false) {
|
|
570
|
+
// Check if previous segment ended at true page bottom
|
|
571
|
+
var prevSegmentY = (yi > 0) ? ys[yi - 1].y1 : 0;
|
|
572
|
+
var prevWasAtPageBottom = (pageHeight - prevSegmentY) <= nearBottomThreshold;
|
|
573
|
+
this.drawHorizontalLine(rowIndex, writer, y1, true, null, prevWasAtPageBottom);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
for (i = 0, l = xs.length; i < l; i++) {
|
|
577
|
+
var leftCellBorder = false;
|
|
578
|
+
var rightCellBorder = false;
|
|
579
|
+
var colIndex = xs[i].index;
|
|
580
|
+
|
|
581
|
+
// current cell
|
|
582
|
+
var cell;
|
|
583
|
+
if (colIndex < body[rowIndex].length) {
|
|
584
|
+
cell = body[rowIndex][colIndex];
|
|
585
|
+
leftCellBorder = cell.border ? cell.border[0] : this.layout.defaultBorder;
|
|
586
|
+
rightCellBorder = cell.border ? cell.border[2] : this.layout.defaultBorder;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// before cell
|
|
590
|
+
if (colIndex > 0 && !leftCellBorder) {
|
|
591
|
+
cell = body[rowIndex][colIndex - 1];
|
|
592
|
+
leftCellBorder = cell.border ? cell.border[2] : this.layout.defaultBorder;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// after cell
|
|
596
|
+
if (colIndex + 1 < body[rowIndex].length && !rightCellBorder) {
|
|
597
|
+
cell = body[rowIndex][colIndex + 1];
|
|
598
|
+
rightCellBorder = cell.border ? cell.border[0] : this.layout.defaultBorder;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
if (leftCellBorder) {
|
|
602
|
+
this.drawVerticalLine(xs[i].x, y1 - hzLineOffset, y2 + this.bottomLineWidth, xs[i].index, writer, rowIndex, xs[i - 1] ? xs[i - 1].index : null);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
if (i < l - 1) {
|
|
606
|
+
var fillColor = body[rowIndex][colIndex].fillColor;
|
|
607
|
+
var fillOpacity = body[rowIndex][colIndex].fillOpacity;
|
|
608
|
+
if (!fillColor) {
|
|
609
|
+
fillColor = isFunction(this.layout.fillColor) ? this.layout.fillColor(rowIndex, this.tableNode, colIndex) : this.layout.fillColor;
|
|
610
|
+
}
|
|
611
|
+
if (!isNumber(fillOpacity)) {
|
|
612
|
+
fillOpacity = isFunction(this.layout.fillOpacity) ? this.layout.fillOpacity(rowIndex, this.tableNode, colIndex) : this.layout.fillOpacity;
|
|
613
|
+
}
|
|
614
|
+
var overlayPattern = body[rowIndex][colIndex].overlayPattern;
|
|
615
|
+
var overlayOpacity = body[rowIndex][colIndex].overlayOpacity;
|
|
616
|
+
if (fillColor || overlayPattern) {
|
|
617
|
+
var widthLeftBorder = leftCellBorder ? this.layout.vLineWidth(colIndex, this.tableNode) : 0;
|
|
618
|
+
var widthRightBorder;
|
|
619
|
+
if ((colIndex === 0 || colIndex + 1 == body[rowIndex].length) && !rightCellBorder) {
|
|
620
|
+
widthRightBorder = this.layout.vLineWidth(colIndex + 1, this.tableNode);
|
|
621
|
+
} else if (rightCellBorder) {
|
|
622
|
+
widthRightBorder = this.layout.vLineWidth(colIndex + 1, this.tableNode) / 2;
|
|
623
|
+
} else {
|
|
624
|
+
widthRightBorder = 0;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
var x1f = this.dontBreakRows ? xs[i].x + widthLeftBorder : xs[i].x + (widthLeftBorder / 2);
|
|
628
|
+
var y1f = this.dontBreakRows ? y1 : y1 - (hzLineOffset / 2);
|
|
629
|
+
var x2f = xs[i + 1].x + widthRightBorder;
|
|
630
|
+
var y2f = this.dontBreakRows ? y2 + this.bottomLineWidth : y2 + (this.bottomLineWidth / 2);
|
|
631
|
+
var bgWidth = x2f - x1f;
|
|
632
|
+
var bgHeight = y2f - y1f;
|
|
633
|
+
if (fillColor) {
|
|
634
|
+
writer.addVector({
|
|
635
|
+
type: 'rect',
|
|
636
|
+
x: x1f,
|
|
637
|
+
y: y1f,
|
|
638
|
+
w: bgWidth,
|
|
639
|
+
h: bgHeight,
|
|
640
|
+
lineWidth: 0,
|
|
641
|
+
color: fillColor,
|
|
642
|
+
fillOpacity: fillOpacity,
|
|
643
|
+
// mark if we are in an unbreakable block
|
|
644
|
+
_isFillColorFromUnbreakable: !!writer.transactionLevel
|
|
645
|
+
}, false, true, writer.context().backgroundLength[writer.context().page]);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
if (overlayPattern) {
|
|
649
|
+
writer.addVector({
|
|
650
|
+
type: 'rect',
|
|
651
|
+
x: x1f,
|
|
652
|
+
y: y1f,
|
|
653
|
+
w: bgWidth,
|
|
654
|
+
h: bgHeight,
|
|
655
|
+
lineWidth: 0,
|
|
656
|
+
color: overlayPattern,
|
|
657
|
+
fillOpacity: overlayOpacity
|
|
658
|
+
}, false, true);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
writer.context().page = endingPage;
|
|
666
|
+
writer.context().y = endingY;
|
|
667
|
+
|
|
668
|
+
var row = this.tableNode.table.body[rowIndex];
|
|
669
|
+
for (i = 0, l = row.length; i < l; i++) {
|
|
670
|
+
if (row[i].rowSpan) {
|
|
671
|
+
this.rowSpanData[i].rowSpan = row[i].rowSpan;
|
|
672
|
+
|
|
673
|
+
// fix colSpans
|
|
674
|
+
if (row[i].colSpan && row[i].colSpan > 1) {
|
|
675
|
+
for (var rowSpanIndex = 1; rowSpanIndex < row[i].rowSpan; rowSpanIndex++) {
|
|
676
|
+
this.tableNode.table.body[rowIndex + rowSpanIndex][i]._colSpan = row[i].colSpan;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
// fix rowSpans
|
|
680
|
+
if (row[i].rowSpan && row[i].rowSpan > 1) {
|
|
681
|
+
for (var spanOffset = 1; spanOffset < row[i].rowSpan; spanOffset++) {
|
|
682
|
+
this.tableNode.table.body[rowIndex + spanOffset][i]._rowSpanCurrentOffset = spanOffset;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
if (this.rowSpanData[i].rowSpan > 0) {
|
|
688
|
+
this.rowSpanData[i].rowSpan--;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// Look ahead: Check if next row will cause a page break
|
|
693
|
+
// If yes, skip drawing the horizontal line at the end of current row
|
|
694
|
+
// This feature is OPT-IN: only enabled when forcePageBreakForAllRows === true
|
|
695
|
+
var shouldSkipHorizontalLine = false;
|
|
696
|
+
|
|
697
|
+
if (nextRowCells && layoutBuilder) {
|
|
698
|
+
// Only perform look-ahead if forcePageBreakForAllRows is explicitly enabled
|
|
699
|
+
// This prevents affecting existing PDFs that don't use this feature
|
|
700
|
+
if (tableLayout && tableLayout.forcePageBreakForAllRows === true) {
|
|
701
|
+
var nextRowEstimatedHeight = 0;
|
|
702
|
+
|
|
703
|
+
// Try to get maximum cell height from next row's measured content
|
|
704
|
+
if (layoutBuilder._getMaxCellHeight) {
|
|
705
|
+
var maxNextCellHeight = layoutBuilder._getMaxCellHeight(nextRowCells);
|
|
706
|
+
if (maxNextCellHeight > 0) {
|
|
707
|
+
nextRowEstimatedHeight = maxNextCellHeight + 10; // Add padding
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// Fallback: use minRowHeight from table layout
|
|
712
|
+
if (nextRowEstimatedHeight === 0) {
|
|
713
|
+
var footerGapOpt = writer.context()._footerGapOption;
|
|
714
|
+
nextRowEstimatedHeight = (tableLayout && tableLayout.minRowHeight) || (footerGapOpt && footerGapOpt.minRowHeight) || 80;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// Check current available height (after current row has been processed)
|
|
718
|
+
var currentAvailableHeight = writer.context().availableHeight;
|
|
719
|
+
|
|
720
|
+
// Skip drawing the horizontal line if EITHER:
|
|
721
|
+
// 1. Next row won't fit (will cause page break), OR
|
|
722
|
+
// 2. We're very close to page bottom (remaining space <= threshold)
|
|
723
|
+
// This prevents duplicate/orphaned lines at page boundaries
|
|
724
|
+
if (nextRowEstimatedHeight > currentAvailableHeight || currentAvailableHeight <= nearBottomThreshold) {
|
|
725
|
+
// Exception: Check if this line should always be drawn (critical boundary)
|
|
726
|
+
// Allow layout to specify via alwaysDrawHLine callback
|
|
727
|
+
var shouldAlwaysDrawLine = false;
|
|
728
|
+
if (typeof tableLayout.alwaysDrawHLine === 'function') {
|
|
729
|
+
shouldAlwaysDrawLine = tableLayout.alwaysDrawHLine(rowIndex + 1, this.tableNode, writer);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
if (!shouldAlwaysDrawLine) {
|
|
733
|
+
shouldSkipHorizontalLine = true;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// Draw horizontal line at the end of the row, unless next row will cause a page break
|
|
740
|
+
if (!shouldSkipHorizontalLine) {
|
|
741
|
+
this.drawHorizontalLine(rowIndex + 1, writer);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
if (this.headerRows && rowIndex === this.headerRows - 1) {
|
|
745
|
+
this.headerRepeatable = writer.currentBlockToRepeatable();
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
if (this.dontBreakRows) {
|
|
749
|
+
writer.tracker.auto('pageChanged',
|
|
750
|
+
function () {
|
|
751
|
+
if (rowIndex > 0 && !self.headerRows && self.layout.hLineWhenBroken !== false) {
|
|
752
|
+
// Draw the top border of the row after a page break
|
|
753
|
+
self.drawHorizontalLine(rowIndex, writer);
|
|
754
|
+
}
|
|
755
|
+
},
|
|
756
|
+
function () {
|
|
757
|
+
writer.commitUnbreakableBlock();
|
|
758
|
+
}
|
|
759
|
+
);
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
if (this.headerRepeatable && (rowIndex === (this.rowsWithoutPageBreak - 1) || rowIndex === this.tableNode.table.body.length - 1)) {
|
|
763
|
+
writer.commitUnbreakableBlock();
|
|
764
|
+
writer.pushToRepeatables(this.headerRepeatable);
|
|
765
|
+
this.cleanUpRepeatables = true;
|
|
766
|
+
this.headerRepeatable = null;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
function getLineXs() {
|
|
770
|
+
var result = [];
|
|
771
|
+
var cols = 0;
|
|
772
|
+
|
|
773
|
+
for (var i = 0, l = self.tableNode.table.body[rowIndex].length; i < l; i++) {
|
|
774
|
+
if (!cols) {
|
|
775
|
+
result.push({ x: self.rowSpanData[i].left, index: i });
|
|
776
|
+
|
|
777
|
+
var item = self.tableNode.table.body[rowIndex][i];
|
|
778
|
+
cols = (item._colSpan || item.colSpan || 0);
|
|
779
|
+
}
|
|
780
|
+
if (cols > 0) {
|
|
781
|
+
cols--;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
result.push({ x: self.rowSpanData[self.rowSpanData.length - 1].left, index: self.rowSpanData.length - 1 });
|
|
786
|
+
|
|
787
|
+
return result;
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
|
|
791
|
+
module.exports = TableProcessor;
|