UNPKG

88.8 kBJavaScriptView Raw
1function getStringWidth(text, styles, doc) {
2 doc.applyStyles(styles, true);
3 var textArr = Array.isArray(text) ? text : [text];
4 var widestLineWidth = textArr
5 .map(function (text) { return doc.getTextWidth(text); })
6 .reduce(function (a, b) { return Math.max(a, b); }, 0);
7 return widestLineWidth;
8}
9function addTableBorder(doc, table, startPos, cursor) {
10 var lineWidth = table.settings.tableLineWidth;
11 var lineColor = table.settings.tableLineColor;
12 doc.applyStyles({ lineWidth: lineWidth, lineColor: lineColor });
13 var fillStyle = getFillStyle(lineWidth, false);
14 if (fillStyle) {
15 doc.rect(startPos.x, startPos.y, table.getWidth(doc.pageSize().width), cursor.y - startPos.y, fillStyle);
16 }
17}
18function getFillStyle(lineWidth, fillColor) {
19 var drawLine = lineWidth > 0;
20 var drawBackground = fillColor || fillColor === 0;
21 if (drawLine && drawBackground) {
22 return 'DF'; // Fill then stroke
23 }
24 else if (drawLine) {
25 return 'S'; // Only stroke (transparent background)
26 }
27 else if (drawBackground) {
28 return 'F'; // Only fill, no stroke
29 }
30 else {
31 return null;
32 }
33}
34function parseSpacing(value, defaultValue) {
35 var _a, _b, _c, _d;
36 value = value || defaultValue;
37 if (Array.isArray(value)) {
38 if (value.length >= 4) {
39 return {
40 top: value[0],
41 right: value[1],
42 bottom: value[2],
43 left: value[3],
44 };
45 }
46 else if (value.length === 3) {
47 return {
48 top: value[0],
49 right: value[1],
50 bottom: value[2],
51 left: value[1],
52 };
53 }
54 else if (value.length === 2) {
55 return {
56 top: value[0],
57 right: value[1],
58 bottom: value[0],
59 left: value[1],
60 };
61 }
62 else if (value.length === 1) {
63 value = value[0];
64 }
65 else {
66 value = defaultValue;
67 }
68 }
69 if (typeof value === 'object') {
70 if (typeof value.vertical === 'number') {
71 value.top = value.vertical;
72 value.bottom = value.vertical;
73 }
74 if (typeof value.horizontal === 'number') {
75 value.right = value.horizontal;
76 value.left = value.horizontal;
77 }
78 return {
79 left: (_a = value.left) !== null && _a !== void 0 ? _a : defaultValue,
80 top: (_b = value.top) !== null && _b !== void 0 ? _b : defaultValue,
81 right: (_c = value.right) !== null && _c !== void 0 ? _c : defaultValue,
82 bottom: (_d = value.bottom) !== null && _d !== void 0 ? _d : defaultValue,
83 };
84 }
85 if (typeof value !== 'number') {
86 value = defaultValue;
87 }
88 return { top: value, right: value, bottom: value, left: value };
89}
90function getPageAvailableWidth(doc, table) {
91 var margins = parseSpacing(table.settings.margin, 0);
92 return doc.pageSize().width - (margins.left + margins.right);
93}
94
95// Limitations
96// - No support for border spacing
97// - No support for transparency
98function parseCss(supportedFonts, element, scaleFactor, style, window) {
99 var result = {};
100 var pxScaleFactor = 96 / 72;
101 var backgroundColor = parseColor(element, function (elem) {
102 return window.getComputedStyle(elem)['backgroundColor'];
103 });
104 if (backgroundColor != null)
105 result.fillColor = backgroundColor;
106 var textColor = parseColor(element, function (elem) {
107 return window.getComputedStyle(elem)['color'];
108 });
109 if (textColor != null)
110 result.textColor = textColor;
111 var padding = parsePadding(style, scaleFactor);
112 if (padding)
113 result.cellPadding = padding;
114 var borderColorSide = 'borderTopColor';
115 var finalScaleFactor = pxScaleFactor * scaleFactor;
116 var btw = style.borderTopWidth;
117 if (style.borderBottomWidth === btw &&
118 style.borderRightWidth === btw &&
119 style.borderLeftWidth === btw) {
120 var borderWidth = (parseFloat(btw) || 0) / finalScaleFactor;
121 if (borderWidth)
122 result.lineWidth = borderWidth;
123 }
124 else {
125 result.lineWidth = {
126 top: (parseFloat(style.borderTopWidth) || 0) / finalScaleFactor,
127 right: (parseFloat(style.borderRightWidth) || 0) / finalScaleFactor,
128 bottom: (parseFloat(style.borderBottomWidth) || 0) / finalScaleFactor,
129 left: (parseFloat(style.borderLeftWidth) || 0) / finalScaleFactor,
130 };
131 // Choose border color of first available side
132 // could be improved by supporting object as lineColor
133 if (!result.lineWidth.top) {
134 if (result.lineWidth.right) {
135 borderColorSide = 'borderRightColor';
136 }
137 else if (result.lineWidth.bottom) {
138 borderColorSide = 'borderBottomColor';
139 }
140 else if (result.lineWidth.left) {
141 borderColorSide = 'borderLeftColor';
142 }
143 }
144 }
145 var borderColor = parseColor(element, function (elem) {
146 return window.getComputedStyle(elem)[borderColorSide];
147 });
148 if (borderColor != null)
149 result.lineColor = borderColor;
150 var accepted = ['left', 'right', 'center', 'justify'];
151 if (accepted.indexOf(style.textAlign) !== -1) {
152 result.halign = style.textAlign;
153 }
154 accepted = ['middle', 'bottom', 'top'];
155 if (accepted.indexOf(style.verticalAlign) !== -1) {
156 result.valign = style.verticalAlign;
157 }
158 var res = parseInt(style.fontSize || '');
159 if (!isNaN(res))
160 result.fontSize = res / pxScaleFactor;
161 var fontStyle = parseFontStyle(style);
162 if (fontStyle)
163 result.fontStyle = fontStyle;
164 var font = (style.fontFamily || '').toLowerCase();
165 if (supportedFonts.indexOf(font) !== -1) {
166 result.font = font;
167 }
168 return result;
169}
170function parseFontStyle(style) {
171 var res = '';
172 if (style.fontWeight === 'bold' ||
173 style.fontWeight === 'bolder' ||
174 parseInt(style.fontWeight) >= 700) {
175 res = 'bold';
176 }
177 if (style.fontStyle === 'italic' || style.fontStyle === 'oblique') {
178 res += 'italic';
179 }
180 return res;
181}
182function parseColor(element, styleGetter) {
183 var cssColor = realColor(element, styleGetter);
184 if (!cssColor)
185 return null;
186 var rgba = cssColor.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d*\.?\d*))?\)$/);
187 if (!rgba || !Array.isArray(rgba)) {
188 return null;
189 }
190 var color = [
191 parseInt(rgba[1]),
192 parseInt(rgba[2]),
193 parseInt(rgba[3]),
194 ];
195 var alpha = parseInt(rgba[4]);
196 if (alpha === 0 || isNaN(color[0]) || isNaN(color[1]) || isNaN(color[2])) {
197 return null;
198 }
199 return color;
200}
201function realColor(elem, styleGetter) {
202 var bg = styleGetter(elem);
203 if (bg === 'rgba(0, 0, 0, 0)' ||
204 bg === 'transparent' ||
205 bg === 'initial' ||
206 bg === 'inherit') {
207 if (elem.parentElement == null) {
208 return null;
209 }
210 return realColor(elem.parentElement, styleGetter);
211 }
212 else {
213 return bg;
214 }
215}
216function parsePadding(style, scaleFactor) {
217 var val = [
218 style.paddingTop,
219 style.paddingRight,
220 style.paddingBottom,
221 style.paddingLeft,
222 ];
223 var pxScaleFactor = 96 / (72 / scaleFactor);
224 var linePadding = (parseInt(style.lineHeight) - parseInt(style.fontSize)) / scaleFactor / 2;
225 var inputPadding = val.map(function (n) {
226 return parseInt(n || '0') / pxScaleFactor;
227 });
228 var padding = parseSpacing(inputPadding, 0);
229 if (linePadding > padding.top) {
230 padding.top = linePadding;
231 }
232 if (linePadding > padding.bottom) {
233 padding.bottom = linePadding;
234 }
235 return padding;
236}
237
238/******************************************************************************
239Copyright (c) Microsoft Corporation.
240
241Permission to use, copy, modify, and/or distribute this software for any
242purpose with or without fee is hereby granted.
243
244THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
245REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
246AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
247INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
248LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
249OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
250PERFORMANCE OF THIS SOFTWARE.
251***************************************************************************** */
252/* global Reflect, Promise, SuppressedError, Symbol */
253
254var extendStatics = function(d, b) {
255 extendStatics = Object.setPrototypeOf ||
256 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
257 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
258 return extendStatics(d, b);
259};
260
261function __extends(d, b) {
262 if (typeof b !== "function" && b !== null)
263 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
264 extendStatics(d, b);
265 function __() { this.constructor = d; }
266 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
267}
268
269typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
270 var e = new Error(message);
271 return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
272};
273
274var HtmlRowInput = /** @class */ (function (_super) {
275 __extends(HtmlRowInput, _super);
276 function HtmlRowInput(element) {
277 var _this = _super.call(this) || this;
278 _this._element = element;
279 return _this;
280 }
281 return HtmlRowInput;
282}(Array));
283// Base style for all themes
284function defaultStyles(scaleFactor) {
285 return {
286 font: 'helvetica', // helvetica, times, courier
287 fontStyle: 'normal', // normal, bold, italic, bolditalic
288 overflow: 'linebreak', // linebreak, ellipsize, visible or hidden
289 fillColor: false, // Either false for transparent, rbg array e.g. [255, 255, 255] or gray level e.g 200
290 textColor: 20,
291 halign: 'left', // left, center, right, justify
292 valign: 'top', // top, middle, bottom
293 fontSize: 10,
294 cellPadding: 5 / scaleFactor, // number or {top,left,right,left,vertical,horizontal}
295 lineColor: 200,
296 lineWidth: 0,
297 cellWidth: 'auto', // 'auto'|'wrap'|number
298 minCellHeight: 0,
299 minCellWidth: 0,
300 };
301}
302function getTheme(name) {
303 var themes = {
304 striped: {
305 table: { fillColor: 255, textColor: 80, fontStyle: 'normal' },
306 head: { textColor: 255, fillColor: [41, 128, 185], fontStyle: 'bold' },
307 body: {},
308 foot: { textColor: 255, fillColor: [41, 128, 185], fontStyle: 'bold' },
309 alternateRow: { fillColor: 245 },
310 },
311 grid: {
312 table: {
313 fillColor: 255,
314 textColor: 80,
315 fontStyle: 'normal',
316 lineWidth: 0.1,
317 },
318 head: {
319 textColor: 255,
320 fillColor: [26, 188, 156],
321 fontStyle: 'bold',
322 lineWidth: 0,
323 },
324 body: {},
325 foot: {
326 textColor: 255,
327 fillColor: [26, 188, 156],
328 fontStyle: 'bold',
329 lineWidth: 0,
330 },
331 alternateRow: {},
332 },
333 plain: {
334 head: { fontStyle: 'bold' },
335 foot: { fontStyle: 'bold' },
336 },
337 };
338 return themes[name];
339}
340
341function parseHtml(doc, input, window, includeHiddenHtml, useCss) {
342 var _a, _b;
343 if (includeHiddenHtml === void 0) { includeHiddenHtml = false; }
344 if (useCss === void 0) { useCss = false; }
345 var tableElement;
346 if (typeof input === 'string') {
347 tableElement = window.document.querySelector(input);
348 }
349 else {
350 tableElement = input;
351 }
352 var supportedFonts = Object.keys(doc.getFontList());
353 var scaleFactor = doc.scaleFactor();
354 var head = [], body = [], foot = [];
355 if (!tableElement) {
356 console.error('Html table could not be found with input: ', input);
357 return { head: head, body: body, foot: foot };
358 }
359 for (var i = 0; i < tableElement.rows.length; i++) {
360 var element = tableElement.rows[i];
361 var tagName = (_b = (_a = element === null || element === void 0 ? void 0 : element.parentElement) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase();
362 var row = parseRowContent(supportedFonts, scaleFactor, window, element, includeHiddenHtml, useCss);
363 if (!row)
364 continue;
365 if (tagName === 'thead') {
366 head.push(row);
367 }
368 else if (tagName === 'tfoot') {
369 foot.push(row);
370 }
371 else {
372 // Add to body both if parent is tbody or table
373 body.push(row);
374 }
375 }
376 return { head: head, body: body, foot: foot };
377}
378function parseRowContent(supportedFonts, scaleFactor, window, row, includeHidden, useCss) {
379 var resultRow = new HtmlRowInput(row);
380 for (var i = 0; i < row.cells.length; i++) {
381 var cell = row.cells[i];
382 var style_1 = window.getComputedStyle(cell);
383 if (includeHidden || style_1.display !== 'none') {
384 var cellStyles = void 0;
385 if (useCss) {
386 cellStyles = parseCss(supportedFonts, cell, scaleFactor, style_1, window);
387 }
388 resultRow.push({
389 rowSpan: cell.rowSpan,
390 colSpan: cell.colSpan,
391 styles: cellStyles,
392 _element: cell,
393 content: parseCellContent(cell),
394 });
395 }
396 }
397 var style = window.getComputedStyle(row);
398 if (resultRow.length > 0 && (includeHidden || style.display !== 'none')) {
399 return resultRow;
400 }
401}
402function parseCellContent(orgCell) {
403 // Work on cloned node to make sure no changes are applied to html table
404 var cell = orgCell.cloneNode(true);
405 // Remove extra space and line breaks in markup to make it more similar to
406 // what would be shown in html
407 cell.innerHTML = cell.innerHTML.replace(/\n/g, '').replace(/ +/g, ' ');
408 // Preserve <br> tags as line breaks in the pdf
409 cell.innerHTML = cell.innerHTML
410 .split(/<br.*?>/) //start with '<br' and ends with '>'.
411 .map(function (part) { return part.trim(); })
412 .join('\n');
413 // innerText for ie
414 return cell.innerText || cell.textContent || '';
415}
416
417/**
418 * Improved text function with halign and valign support
419 * Inspiration from: http://stackoverflow.com/questions/28327510/align-text-right-using-jspdf/28433113#28433113
420 */
421function autoTableText (text, x, y, styles, doc) {
422 styles = styles || {};
423 var PHYSICAL_LINE_HEIGHT = 1.15;
424 var k = doc.internal.scaleFactor;
425 var fontSize = doc.internal.getFontSize() / k;
426 var lineHeightFactor = doc.getLineHeightFactor
427 ? doc.getLineHeightFactor()
428 : PHYSICAL_LINE_HEIGHT;
429 var lineHeight = fontSize * lineHeightFactor;
430 var splitRegex = /\r\n|\r|\n/g;
431 var splitText = '';
432 var lineCount = 1;
433 if (styles.valign === 'middle' ||
434 styles.valign === 'bottom' ||
435 styles.halign === 'center' ||
436 styles.halign === 'right') {
437 splitText = typeof text === 'string' ? text.split(splitRegex) : text;
438 lineCount = splitText.length || 1;
439 }
440 // Align the top
441 y += fontSize * (2 - PHYSICAL_LINE_HEIGHT);
442 if (styles.valign === 'middle')
443 y -= (lineCount / 2) * lineHeight;
444 else if (styles.valign === 'bottom')
445 y -= lineCount * lineHeight;
446 if (styles.halign === 'center' || styles.halign === 'right') {
447 var alignSize = fontSize;
448 if (styles.halign === 'center')
449 alignSize *= 0.5;
450 if (splitText && lineCount >= 1) {
451 for (var iLine = 0; iLine < splitText.length; iLine++) {
452 doc.text(splitText[iLine], x - doc.getStringUnitWidth(splitText[iLine]) * alignSize, y);
453 y += lineHeight;
454 }
455 return doc;
456 }
457 x -= doc.getStringUnitWidth(text) * alignSize;
458 }
459 if (styles.halign === 'justify') {
460 doc.text(text, x, y, {
461 maxWidth: styles.maxWidth || 100,
462 align: 'justify',
463 });
464 }
465 else {
466 doc.text(text, x, y);
467 }
468 return doc;
469}
470
471var globalDefaults = {};
472var DocHandler = /** @class */ (function () {
473 function DocHandler(jsPDFDocument) {
474 this.jsPDFDocument = jsPDFDocument;
475 this.userStyles = {
476 // Black for versions of jspdf without getTextColor
477 textColor: jsPDFDocument.getTextColor
478 ? this.jsPDFDocument.getTextColor()
479 : 0,
480 fontSize: jsPDFDocument.internal.getFontSize(),
481 fontStyle: jsPDFDocument.internal.getFont().fontStyle,
482 font: jsPDFDocument.internal.getFont().fontName,
483 // 0 for versions of jspdf without getLineWidth
484 lineWidth: jsPDFDocument.getLineWidth
485 ? this.jsPDFDocument.getLineWidth()
486 : 0,
487 // Black for versions of jspdf without getDrawColor
488 lineColor: jsPDFDocument.getDrawColor
489 ? this.jsPDFDocument.getDrawColor()
490 : 0,
491 };
492 }
493 DocHandler.setDefaults = function (defaults, doc) {
494 if (doc === void 0) { doc = null; }
495 if (doc) {
496 doc.__autoTableDocumentDefaults = defaults;
497 }
498 else {
499 globalDefaults = defaults;
500 }
501 };
502 DocHandler.unifyColor = function (c) {
503 if (Array.isArray(c)) {
504 return c;
505 }
506 else if (typeof c === 'number') {
507 return [c, c, c];
508 }
509 else if (typeof c === 'string') {
510 return [c];
511 }
512 else {
513 return null;
514 }
515 };
516 DocHandler.prototype.applyStyles = function (styles, fontOnly) {
517 // Font style needs to be applied before font
518 // https://github.com/simonbengtsson/jsPDF-AutoTable/issues/632
519 var _a, _b, _c;
520 if (fontOnly === void 0) { fontOnly = false; }
521 if (styles.fontStyle)
522 this.jsPDFDocument.setFontStyle &&
523 this.jsPDFDocument.setFontStyle(styles.fontStyle);
524 var _d = this.jsPDFDocument.internal.getFont(), fontStyle = _d.fontStyle, fontName = _d.fontName;
525 if (styles.font)
526 fontName = styles.font;
527 if (styles.fontStyle) {
528 fontStyle = styles.fontStyle;
529 var availableFontStyles = this.getFontList()[fontName];
530 if (availableFontStyles &&
531 availableFontStyles.indexOf(fontStyle) === -1) {
532 // Common issue was that the default bold in headers
533 // made custom fonts not work. For example:
534 // https://github.com/simonbengtsson/jsPDF-AutoTable/issues/653
535 this.jsPDFDocument.setFontStyle &&
536 this.jsPDFDocument.setFontStyle(availableFontStyles[0]);
537 fontStyle = availableFontStyles[0];
538 }
539 }
540 this.jsPDFDocument.setFont(fontName, fontStyle);
541 if (styles.fontSize)
542 this.jsPDFDocument.setFontSize(styles.fontSize);
543 if (fontOnly) {
544 return; // Performance improvement
545 }
546 var color = DocHandler.unifyColor(styles.fillColor);
547 if (color)
548 (_a = this.jsPDFDocument).setFillColor.apply(_a, color);
549 color = DocHandler.unifyColor(styles.textColor);
550 if (color)
551 (_b = this.jsPDFDocument).setTextColor.apply(_b, color);
552 color = DocHandler.unifyColor(styles.lineColor);
553 if (color)
554 (_c = this.jsPDFDocument).setDrawColor.apply(_c, color);
555 if (typeof styles.lineWidth === 'number') {
556 this.jsPDFDocument.setLineWidth(styles.lineWidth);
557 }
558 };
559 DocHandler.prototype.splitTextToSize = function (text, size, opts) {
560 return this.jsPDFDocument.splitTextToSize(text, size, opts);
561 };
562 /**
563 * Adds a rectangle to the PDF
564 * @param x Coordinate (in units declared at inception of PDF document) against left edge of the page
565 * @param y Coordinate (in units declared at inception of PDF document) against upper edge of the page
566 * @param width Width (in units declared at inception of PDF document)
567 * @param height Height (in units declared at inception of PDF document)
568 * @param fillStyle A string specifying the painting style or null. Valid styles include: 'S' [default] - stroke, 'F' - fill, and 'DF' (or 'FD') - fill then stroke.
569 */
570 DocHandler.prototype.rect = function (x, y, width, height, fillStyle) {
571 // null is excluded from fillStyle possible values because it isn't needed
572 // and is prone to bugs as it's used to postpone setting the style
573 // https://rawgit.com/MrRio/jsPDF/master/docs/jsPDF.html#rect
574 return this.jsPDFDocument.rect(x, y, width, height, fillStyle);
575 };
576 DocHandler.prototype.getLastAutoTable = function () {
577 return this.jsPDFDocument.lastAutoTable || null;
578 };
579 DocHandler.prototype.getTextWidth = function (text) {
580 return this.jsPDFDocument.getTextWidth(text);
581 };
582 DocHandler.prototype.getDocument = function () {
583 return this.jsPDFDocument;
584 };
585 DocHandler.prototype.setPage = function (page) {
586 this.jsPDFDocument.setPage(page);
587 };
588 DocHandler.prototype.addPage = function () {
589 return this.jsPDFDocument.addPage();
590 };
591 DocHandler.prototype.getFontList = function () {
592 return this.jsPDFDocument.getFontList();
593 };
594 DocHandler.prototype.getGlobalOptions = function () {
595 return globalDefaults || {};
596 };
597 DocHandler.prototype.getDocumentOptions = function () {
598 return this.jsPDFDocument.__autoTableDocumentDefaults || {};
599 };
600 DocHandler.prototype.pageSize = function () {
601 var pageSize = this.jsPDFDocument.internal.pageSize;
602 // JSPDF 1.4 uses get functions instead of properties on pageSize
603 if (pageSize.width == null) {
604 pageSize = {
605 width: pageSize.getWidth(),
606 height: pageSize.getHeight(),
607 };
608 }
609 return pageSize;
610 };
611 DocHandler.prototype.scaleFactor = function () {
612 return this.jsPDFDocument.internal.scaleFactor;
613 };
614 DocHandler.prototype.getLineHeightFactor = function () {
615 var doc = this.jsPDFDocument;
616 return doc.getLineHeightFactor ? doc.getLineHeightFactor() : 1.15;
617 };
618 DocHandler.prototype.getLineHeight = function (fontSize) {
619 return (fontSize / this.scaleFactor()) * this.getLineHeightFactor();
620 };
621 DocHandler.prototype.pageNumber = function () {
622 var pageInfo = this.jsPDFDocument.internal.getCurrentPageInfo();
623 if (!pageInfo) {
624 // Only recent versions of jspdf has pageInfo
625 return this.jsPDFDocument.internal.getNumberOfPages();
626 }
627 return pageInfo.pageNumber;
628 };
629 return DocHandler;
630}());
631
632/* eslint-disable @typescript-eslint/no-unused-vars */
633// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
634function assign(target, s, s1, s2, s3) {
635 if (target == null) {
636 throw new TypeError('Cannot convert undefined or null to object');
637 }
638 var to = Object(target);
639 for (var index = 1; index < arguments.length; index++) {
640 // eslint-disable-next-line prefer-rest-params
641 var nextSource = arguments[index];
642 if (nextSource != null) {
643 // Skip over if undefined or null
644 for (var nextKey in nextSource) {
645 // Avoid bugs when hasOwnProperty is shadowed
646 if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
647 to[nextKey] = nextSource[nextKey];
648 }
649 }
650 }
651 }
652 return to;
653}
654
655function validateOptions (doc, global, document, current) {
656 var _loop_1 = function (options) {
657 if (options && typeof options !== 'object') {
658 console.error('The options parameter should be of type object, is: ' + typeof options);
659 }
660 if (typeof options.extendWidth !== 'undefined') {
661 options.tableWidth = options.extendWidth ? 'auto' : 'wrap';
662 console.error('Use of deprecated option: extendWidth, use tableWidth instead.');
663 }
664 if (typeof options.margins !== 'undefined') {
665 if (typeof options.margin === 'undefined')
666 options.margin = options.margins;
667 console.error('Use of deprecated option: margins, use margin instead.');
668 }
669 if (options.startY && typeof options.startY !== 'number') {
670 console.error('Invalid value for startY option', options.startY);
671 delete options.startY;
672 }
673 if (!options.didDrawPage &&
674 (options.afterPageContent ||
675 options.beforePageContent ||
676 options.afterPageAdd)) {
677 console.error('The afterPageContent, beforePageContent and afterPageAdd hooks are deprecated. Use didDrawPage instead');
678 options.didDrawPage = function (data) {
679 doc.applyStyles(doc.userStyles);
680 if (options.beforePageContent)
681 options.beforePageContent(data);
682 doc.applyStyles(doc.userStyles);
683 if (options.afterPageContent)
684 options.afterPageContent(data);
685 doc.applyStyles(doc.userStyles);
686 if (options.afterPageAdd && data.pageNumber > 1) {
687 data.afterPageAdd(data);
688 }
689 doc.applyStyles(doc.userStyles);
690 };
691 }
692 [
693 'createdHeaderCell',
694 'drawHeaderRow',
695 'drawRow',
696 'drawHeaderCell',
697 ].forEach(function (name) {
698 if (options[name]) {
699 console.error("The \"".concat(name, "\" hook has changed in version 3.0, check the changelog for how to migrate."));
700 }
701 });
702 [
703 ['showFoot', 'showFooter'],
704 ['showHead', 'showHeader'],
705 ['didDrawPage', 'addPageContent'],
706 ['didParseCell', 'createdCell'],
707 ['headStyles', 'headerStyles'],
708 ].forEach(function (_a) {
709 var current = _a[0], deprecated = _a[1];
710 if (options[deprecated]) {
711 console.error("Use of deprecated option ".concat(deprecated, ". Use ").concat(current, " instead"));
712 options[current] = options[deprecated];
713 }
714 });
715 [
716 ['padding', 'cellPadding'],
717 ['lineHeight', 'rowHeight'],
718 'fontSize',
719 'overflow',
720 ].forEach(function (o) {
721 var deprecatedOption = typeof o === 'string' ? o : o[0];
722 var style = typeof o === 'string' ? o : o[1];
723 if (typeof options[deprecatedOption] !== 'undefined') {
724 if (typeof options.styles[style] === 'undefined') {
725 options.styles[style] = options[deprecatedOption];
726 }
727 console.error('Use of deprecated option: ' +
728 deprecatedOption +
729 ', use the style ' +
730 style +
731 ' instead.');
732 }
733 });
734 for (var _b = 0, _c = [
735 'styles',
736 'bodyStyles',
737 'headStyles',
738 'footStyles',
739 ]; _b < _c.length; _b++) {
740 var styleProp = _c[_b];
741 checkStyles(options[styleProp] || {});
742 }
743 var columnStyles = options['columnStyles'] || {};
744 for (var _d = 0, _e = Object.keys(columnStyles); _d < _e.length; _d++) {
745 var key = _e[_d];
746 checkStyles(columnStyles[key] || {});
747 }
748 };
749 for (var _i = 0, _a = [global, document, current]; _i < _a.length; _i++) {
750 var options = _a[_i];
751 _loop_1(options);
752 }
753}
754function checkStyles(styles) {
755 if (styles.rowHeight) {
756 console.error('Use of deprecated style rowHeight. It is renamed to minCellHeight.');
757 if (!styles.minCellHeight) {
758 styles.minCellHeight = styles.rowHeight;
759 }
760 }
761 else if (styles.columnWidth) {
762 console.error('Use of deprecated style columnWidth. It is renamed to cellWidth.');
763 if (!styles.cellWidth) {
764 styles.cellWidth = styles.columnWidth;
765 }
766 }
767}
768
769function parseInput(d, current) {
770 var doc = new DocHandler(d);
771 var document = doc.getDocumentOptions();
772 var global = doc.getGlobalOptions();
773 validateOptions(doc, global, document, current);
774 var options = assign({}, global, document, current);
775 var win;
776 if (typeof window !== 'undefined') {
777 win = window;
778 }
779 var styles = parseStyles(global, document, current);
780 var hooks = parseHooks(global, document, current);
781 var settings = parseSettings(doc, options);
782 var content = parseContent$1(doc, options, win);
783 return {
784 id: current.tableId,
785 content: content,
786 hooks: hooks,
787 styles: styles,
788 settings: settings,
789 };
790}
791function parseStyles(gInput, dInput, cInput) {
792 var styleOptions = {
793 styles: {},
794 headStyles: {},
795 bodyStyles: {},
796 footStyles: {},
797 alternateRowStyles: {},
798 columnStyles: {},
799 };
800 var _loop_1 = function (prop) {
801 if (prop === 'columnStyles') {
802 var global_1 = gInput[prop];
803 var document_1 = dInput[prop];
804 var current = cInput[prop];
805 styleOptions.columnStyles = assign({}, global_1, document_1, current);
806 }
807 else {
808 var allOptions = [gInput, dInput, cInput];
809 var styles = allOptions.map(function (opts) { return opts[prop] || {}; });
810 styleOptions[prop] = assign({}, styles[0], styles[1], styles[2]);
811 }
812 };
813 for (var _i = 0, _a = Object.keys(styleOptions); _i < _a.length; _i++) {
814 var prop = _a[_i];
815 _loop_1(prop);
816 }
817 return styleOptions;
818}
819function parseHooks(global, document, current) {
820 var allOptions = [global, document, current];
821 var result = {
822 didParseCell: [],
823 willDrawCell: [],
824 didDrawCell: [],
825 willDrawPage: [],
826 didDrawPage: [],
827 };
828 for (var _i = 0, allOptions_1 = allOptions; _i < allOptions_1.length; _i++) {
829 var options = allOptions_1[_i];
830 if (options.didParseCell)
831 result.didParseCell.push(options.didParseCell);
832 if (options.willDrawCell)
833 result.willDrawCell.push(options.willDrawCell);
834 if (options.didDrawCell)
835 result.didDrawCell.push(options.didDrawCell);
836 if (options.willDrawPage)
837 result.willDrawPage.push(options.willDrawPage);
838 if (options.didDrawPage)
839 result.didDrawPage.push(options.didDrawPage);
840 }
841 return result;
842}
843function parseSettings(doc, options) {
844 var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
845 var margin = parseSpacing(options.margin, 40 / doc.scaleFactor());
846 var startY = (_a = getStartY(doc, options.startY)) !== null && _a !== void 0 ? _a : margin.top;
847 var showFoot;
848 if (options.showFoot === true) {
849 showFoot = 'everyPage';
850 }
851 else if (options.showFoot === false) {
852 showFoot = 'never';
853 }
854 else {
855 showFoot = (_b = options.showFoot) !== null && _b !== void 0 ? _b : 'everyPage';
856 }
857 var showHead;
858 if (options.showHead === true) {
859 showHead = 'everyPage';
860 }
861 else if (options.showHead === false) {
862 showHead = 'never';
863 }
864 else {
865 showHead = (_c = options.showHead) !== null && _c !== void 0 ? _c : 'everyPage';
866 }
867 var useCss = (_d = options.useCss) !== null && _d !== void 0 ? _d : false;
868 var theme = options.theme || (useCss ? 'plain' : 'striped');
869 var horizontalPageBreak = !!options.horizontalPageBreak;
870 var horizontalPageBreakRepeat = (_e = options.horizontalPageBreakRepeat) !== null && _e !== void 0 ? _e : null;
871 return {
872 includeHiddenHtml: (_f = options.includeHiddenHtml) !== null && _f !== void 0 ? _f : false,
873 useCss: useCss,
874 theme: theme,
875 startY: startY,
876 margin: margin,
877 pageBreak: (_g = options.pageBreak) !== null && _g !== void 0 ? _g : 'auto',
878 rowPageBreak: (_h = options.rowPageBreak) !== null && _h !== void 0 ? _h : 'auto',
879 tableWidth: (_j = options.tableWidth) !== null && _j !== void 0 ? _j : 'auto',
880 showHead: showHead,
881 showFoot: showFoot,
882 tableLineWidth: (_k = options.tableLineWidth) !== null && _k !== void 0 ? _k : 0,
883 tableLineColor: (_l = options.tableLineColor) !== null && _l !== void 0 ? _l : 200,
884 horizontalPageBreak: horizontalPageBreak,
885 horizontalPageBreakRepeat: horizontalPageBreakRepeat,
886 horizontalPageBreakBehaviour: (_m = options.horizontalPageBreakBehaviour) !== null && _m !== void 0 ? _m : 'afterAllRows',
887 };
888}
889function getStartY(doc, userStartY) {
890 var previous = doc.getLastAutoTable();
891 var sf = doc.scaleFactor();
892 var currentPage = doc.pageNumber();
893 var isSamePageAsPreviousTable = false;
894 if (previous && previous.startPageNumber) {
895 var endingPage = previous.startPageNumber + previous.pageNumber - 1;
896 isSamePageAsPreviousTable = endingPage === currentPage;
897 }
898 if (typeof userStartY === 'number') {
899 return userStartY;
900 }
901 else if (userStartY == null || userStartY === false) {
902 if (isSamePageAsPreviousTable && (previous === null || previous === void 0 ? void 0 : previous.finalY) != null) {
903 // Some users had issues with overlapping tables when they used multiple
904 // tables without setting startY so setting it here to a sensible default.
905 return previous.finalY + 20 / sf;
906 }
907 }
908 return null;
909}
910function parseContent$1(doc, options, window) {
911 var head = options.head || [];
912 var body = options.body || [];
913 var foot = options.foot || [];
914 if (options.html) {
915 var hidden = options.includeHiddenHtml;
916 if (window) {
917 var htmlContent = parseHtml(doc, options.html, window, hidden, options.useCss) || {};
918 head = htmlContent.head || head;
919 body = htmlContent.body || head;
920 foot = htmlContent.foot || head;
921 }
922 else {
923 console.error('Cannot parse html in non browser environment');
924 }
925 }
926 var columns = options.columns || parseColumns(head, body, foot);
927 return {
928 columns: columns,
929 head: head,
930 body: body,
931 foot: foot,
932 };
933}
934function parseColumns(head, body, foot) {
935 var firstRow = head[0] || body[0] || foot[0] || [];
936 var result = [];
937 Object.keys(firstRow)
938 .filter(function (key) { return key !== '_element'; })
939 .forEach(function (key) {
940 var colSpan = 1;
941 var input;
942 if (Array.isArray(firstRow)) {
943 input = firstRow[parseInt(key)];
944 }
945 else {
946 input = firstRow[key];
947 }
948 if (typeof input === 'object' && !Array.isArray(input)) {
949 colSpan = (input === null || input === void 0 ? void 0 : input.colSpan) || 1;
950 }
951 for (var i = 0; i < colSpan; i++) {
952 var id = void 0;
953 if (Array.isArray(firstRow)) {
954 id = result.length;
955 }
956 else {
957 id = key + (i > 0 ? "_".concat(i) : '');
958 }
959 var rowResult = { dataKey: id };
960 result.push(rowResult);
961 }
962 });
963 return result;
964}
965
966var HookData = /** @class */ (function () {
967 function HookData(doc, table, cursor) {
968 this.table = table;
969 this.pageNumber = table.pageNumber;
970 this.pageCount = this.pageNumber;
971 this.settings = table.settings;
972 this.cursor = cursor;
973 this.doc = doc.getDocument();
974 }
975 return HookData;
976}());
977var CellHookData = /** @class */ (function (_super) {
978 __extends(CellHookData, _super);
979 function CellHookData(doc, table, cell, row, column, cursor) {
980 var _this = _super.call(this, doc, table, cursor) || this;
981 _this.cell = cell;
982 _this.row = row;
983 _this.column = column;
984 _this.section = row.section;
985 return _this;
986 }
987 return CellHookData;
988}(HookData));
989
990var Table = /** @class */ (function () {
991 function Table(input, content) {
992 this.pageNumber = 1;
993 // Deprecated, use pageNumber instead
994 // Not using getter since:
995 // https://github.com/simonbengtsson/jsPDF-AutoTable/issues/596
996 this.pageCount = 1;
997 this.id = input.id;
998 this.settings = input.settings;
999 this.styles = input.styles;
1000 this.hooks = input.hooks;
1001 this.columns = content.columns;
1002 this.head = content.head;
1003 this.body = content.body;
1004 this.foot = content.foot;
1005 }
1006 Table.prototype.getHeadHeight = function (columns) {
1007 return this.head.reduce(function (acc, row) { return acc + row.getMaxCellHeight(columns); }, 0);
1008 };
1009 Table.prototype.getFootHeight = function (columns) {
1010 return this.foot.reduce(function (acc, row) { return acc + row.getMaxCellHeight(columns); }, 0);
1011 };
1012 Table.prototype.allRows = function () {
1013 return this.head.concat(this.body).concat(this.foot);
1014 };
1015 Table.prototype.callCellHooks = function (doc, handlers, cell, row, column, cursor) {
1016 for (var _i = 0, handlers_1 = handlers; _i < handlers_1.length; _i++) {
1017 var handler = handlers_1[_i];
1018 var data = new CellHookData(doc, this, cell, row, column, cursor);
1019 var result = handler(data) === false;
1020 // Make sure text is always string[] since user can assign string
1021 cell.text = Array.isArray(cell.text) ? cell.text : [cell.text];
1022 if (result) {
1023 return false;
1024 }
1025 }
1026 return true;
1027 };
1028 Table.prototype.callEndPageHooks = function (doc, cursor) {
1029 doc.applyStyles(doc.userStyles);
1030 for (var _i = 0, _a = this.hooks.didDrawPage; _i < _a.length; _i++) {
1031 var handler = _a[_i];
1032 handler(new HookData(doc, this, cursor));
1033 }
1034 };
1035 Table.prototype.callWillDrawPageHooks = function (doc, cursor) {
1036 for (var _i = 0, _a = this.hooks.willDrawPage; _i < _a.length; _i++) {
1037 var handler = _a[_i];
1038 handler(new HookData(doc, this, cursor));
1039 }
1040 };
1041 Table.prototype.getWidth = function (pageWidth) {
1042 if (typeof this.settings.tableWidth === 'number') {
1043 return this.settings.tableWidth;
1044 }
1045 else if (this.settings.tableWidth === 'wrap') {
1046 var wrappedWidth = this.columns.reduce(function (total, col) { return total + col.wrappedWidth; }, 0);
1047 return wrappedWidth;
1048 }
1049 else {
1050 var margin = this.settings.margin;
1051 return pageWidth - margin.left - margin.right;
1052 }
1053 };
1054 return Table;
1055}());
1056var Row = /** @class */ (function () {
1057 function Row(raw, index, section, cells, spansMultiplePages) {
1058 if (spansMultiplePages === void 0) { spansMultiplePages = false; }
1059 this.height = 0;
1060 this.raw = raw;
1061 if (raw instanceof HtmlRowInput) {
1062 this.raw = raw._element;
1063 this.element = raw._element;
1064 }
1065 this.index = index;
1066 this.section = section;
1067 this.cells = cells;
1068 this.spansMultiplePages = spansMultiplePages;
1069 }
1070 Row.prototype.getMaxCellHeight = function (columns) {
1071 var _this = this;
1072 return columns.reduce(function (acc, column) { var _a; return Math.max(acc, ((_a = _this.cells[column.index]) === null || _a === void 0 ? void 0 : _a.height) || 0); }, 0);
1073 };
1074 Row.prototype.hasRowSpan = function (columns) {
1075 var _this = this;
1076 return (columns.filter(function (column) {
1077 var cell = _this.cells[column.index];
1078 if (!cell)
1079 return false;
1080 return cell.rowSpan > 1;
1081 }).length > 0);
1082 };
1083 Row.prototype.canEntireRowFit = function (height, columns) {
1084 return this.getMaxCellHeight(columns) <= height;
1085 };
1086 Row.prototype.getMinimumRowHeight = function (columns, doc) {
1087 var _this = this;
1088 return columns.reduce(function (acc, column) {
1089 var cell = _this.cells[column.index];
1090 if (!cell)
1091 return 0;
1092 var lineHeight = doc.getLineHeight(cell.styles.fontSize);
1093 var vPadding = cell.padding('vertical');
1094 var oneRowHeight = vPadding + lineHeight;
1095 return oneRowHeight > acc ? oneRowHeight : acc;
1096 }, 0);
1097 };
1098 return Row;
1099}());
1100var Cell = /** @class */ (function () {
1101 function Cell(raw, styles, section) {
1102 var _a, _b;
1103 this.contentHeight = 0;
1104 this.contentWidth = 0;
1105 this.wrappedWidth = 0;
1106 this.minReadableWidth = 0;
1107 this.minWidth = 0;
1108 this.width = 0;
1109 this.height = 0;
1110 this.x = 0;
1111 this.y = 0;
1112 this.styles = styles;
1113 this.section = section;
1114 this.raw = raw;
1115 var content = raw;
1116 if (raw != null && typeof raw === 'object' && !Array.isArray(raw)) {
1117 this.rowSpan = raw.rowSpan || 1;
1118 this.colSpan = raw.colSpan || 1;
1119 content = (_b = (_a = raw.content) !== null && _a !== void 0 ? _a : raw.title) !== null && _b !== void 0 ? _b : raw;
1120 if (raw._element) {
1121 this.raw = raw._element;
1122 }
1123 }
1124 else {
1125 this.rowSpan = 1;
1126 this.colSpan = 1;
1127 }
1128 // Stringify 0 and false, but not undefined or null
1129 var text = content != null ? '' + content : '';
1130 var splitRegex = /\r\n|\r|\n/g;
1131 this.text = text.split(splitRegex);
1132 }
1133 Cell.prototype.getTextPos = function () {
1134 var y;
1135 if (this.styles.valign === 'top') {
1136 y = this.y + this.padding('top');
1137 }
1138 else if (this.styles.valign === 'bottom') {
1139 y = this.y + this.height - this.padding('bottom');
1140 }
1141 else {
1142 var netHeight = this.height - this.padding('vertical');
1143 y = this.y + netHeight / 2 + this.padding('top');
1144 }
1145 var x;
1146 if (this.styles.halign === 'right') {
1147 x = this.x + this.width - this.padding('right');
1148 }
1149 else if (this.styles.halign === 'center') {
1150 var netWidth = this.width - this.padding('horizontal');
1151 x = this.x + netWidth / 2 + this.padding('left');
1152 }
1153 else {
1154 x = this.x + this.padding('left');
1155 }
1156 return { x: x, y: y };
1157 };
1158 // TODO (v4): replace parameters with only (lineHeight)
1159 Cell.prototype.getContentHeight = function (scaleFactor, lineHeightFactor) {
1160 if (lineHeightFactor === void 0) { lineHeightFactor = 1.15; }
1161 var lineCount = Array.isArray(this.text) ? this.text.length : 1;
1162 var lineHeight = (this.styles.fontSize / scaleFactor) * lineHeightFactor;
1163 var height = lineCount * lineHeight + this.padding('vertical');
1164 return Math.max(height, this.styles.minCellHeight);
1165 };
1166 Cell.prototype.padding = function (name) {
1167 var padding = parseSpacing(this.styles.cellPadding, 0);
1168 if (name === 'vertical') {
1169 return padding.top + padding.bottom;
1170 }
1171 else if (name === 'horizontal') {
1172 return padding.left + padding.right;
1173 }
1174 else {
1175 return padding[name];
1176 }
1177 };
1178 return Cell;
1179}());
1180var Column = /** @class */ (function () {
1181 function Column(dataKey, raw, index) {
1182 this.wrappedWidth = 0;
1183 this.minReadableWidth = 0;
1184 this.minWidth = 0;
1185 this.width = 0;
1186 this.dataKey = dataKey;
1187 this.raw = raw;
1188 this.index = index;
1189 }
1190 Column.prototype.getMaxCustomCellWidth = function (table) {
1191 var max = 0;
1192 for (var _i = 0, _a = table.allRows(); _i < _a.length; _i++) {
1193 var row = _a[_i];
1194 var cell = row.cells[this.index];
1195 if (cell && typeof cell.styles.cellWidth === 'number') {
1196 max = Math.max(max, cell.styles.cellWidth);
1197 }
1198 }
1199 return max;
1200 };
1201 return Column;
1202}());
1203
1204// get columns can be fit into page
1205function getColumnsCanFitInPage(doc, table, config) {
1206 var _a;
1207 if (config === void 0) { config = {}; }
1208 // Get page width
1209 var remainingWidth = getPageAvailableWidth(doc, table);
1210 // Get column data key to repeat
1211 var repeatColumnsMap = new Map();
1212 var colIndexes = [];
1213 var columns = [];
1214 var horizontalPageBreakRepeat = [];
1215 table.settings.horizontalPageBreakRepeat;
1216 if (Array.isArray(table.settings.horizontalPageBreakRepeat)) {
1217 horizontalPageBreakRepeat = table.settings.horizontalPageBreakRepeat;
1218 // It can be a single value of type string or number (even number: 0)
1219 }
1220 else if (typeof table.settings.horizontalPageBreakRepeat === 'string' ||
1221 typeof table.settings.horizontalPageBreakRepeat === 'number') {
1222 horizontalPageBreakRepeat = [table.settings.horizontalPageBreakRepeat];
1223 }
1224 // Code to repeat the given column in split pages
1225 horizontalPageBreakRepeat.forEach(function (field) {
1226 var col = table.columns.find(function (item) { return item.dataKey === field || item.index === field; });
1227 if (col && !repeatColumnsMap.has(col.index)) {
1228 repeatColumnsMap.set(col.index, true);
1229 colIndexes.push(col.index);
1230 columns.push(table.columns[col.index]);
1231 remainingWidth -= col.wrappedWidth;
1232 }
1233 });
1234 var first = true;
1235 var i = (_a = config === null || config === void 0 ? void 0 : config.start) !== null && _a !== void 0 ? _a : 0; // make sure couter is initiated outside the loop
1236 while (i < table.columns.length) {
1237 // Prevent duplicates
1238 if (repeatColumnsMap.has(i)) {
1239 i++;
1240 continue;
1241 }
1242 var colWidth = table.columns[i].wrappedWidth;
1243 // Take at least one column even if it doesn't fit
1244 if (first || remainingWidth >= colWidth) {
1245 first = false;
1246 colIndexes.push(i);
1247 columns.push(table.columns[i]);
1248 remainingWidth -= colWidth;
1249 }
1250 else {
1251 break;
1252 }
1253 i++;
1254 }
1255 return { colIndexes: colIndexes, columns: columns, lastIndex: i - 1 };
1256}
1257function calculateAllColumnsCanFitInPage(doc, table) {
1258 var allResults = [];
1259 for (var i = 0; i < table.columns.length; i++) {
1260 var result = getColumnsCanFitInPage(doc, table, { start: i });
1261 if (result.columns.length) {
1262 allResults.push(result);
1263 i = result.lastIndex;
1264 }
1265 }
1266 return allResults;
1267}
1268
1269function drawTable(jsPDFDoc, table) {
1270 var settings = table.settings;
1271 var startY = settings.startY;
1272 var margin = settings.margin;
1273 var cursor = {
1274 x: margin.left,
1275 y: startY,
1276 };
1277 var sectionsHeight = table.getHeadHeight(table.columns) + table.getFootHeight(table.columns);
1278 var minTableBottomPos = startY + margin.bottom + sectionsHeight;
1279 if (settings.pageBreak === 'avoid') {
1280 var rows = table.body;
1281 var tableHeight = rows.reduce(function (acc, row) { return acc + row.height; }, 0);
1282 minTableBottomPos += tableHeight;
1283 }
1284 var doc = new DocHandler(jsPDFDoc);
1285 if (settings.pageBreak === 'always' ||
1286 (settings.startY != null && minTableBottomPos > doc.pageSize().height)) {
1287 nextPage(doc);
1288 cursor.y = margin.top;
1289 }
1290 table.callWillDrawPageHooks(doc, cursor);
1291 var startPos = assign({}, cursor);
1292 table.startPageNumber = doc.pageNumber();
1293 if (settings.horizontalPageBreak) {
1294 // managed flow for split columns
1295 printTableWithHorizontalPageBreak(doc, table, startPos, cursor);
1296 }
1297 else {
1298 // normal flow
1299 doc.applyStyles(doc.userStyles);
1300 if (settings.showHead === 'firstPage' ||
1301 settings.showHead === 'everyPage') {
1302 table.head.forEach(function (row) {
1303 return printRow(doc, table, row, cursor, table.columns);
1304 });
1305 }
1306 doc.applyStyles(doc.userStyles);
1307 table.body.forEach(function (row, index) {
1308 var isLastRow = index === table.body.length - 1;
1309 printFullRow(doc, table, row, isLastRow, startPos, cursor, table.columns);
1310 });
1311 doc.applyStyles(doc.userStyles);
1312 if (settings.showFoot === 'lastPage' || settings.showFoot === 'everyPage') {
1313 table.foot.forEach(function (row) {
1314 return printRow(doc, table, row, cursor, table.columns);
1315 });
1316 }
1317 }
1318 addTableBorder(doc, table, startPos, cursor);
1319 table.callEndPageHooks(doc, cursor);
1320 table.finalY = cursor.y;
1321 jsPDFDoc.lastAutoTable = table;
1322 jsPDFDoc.previousAutoTable = table; // Deprecated
1323 if (jsPDFDoc.autoTable)
1324 jsPDFDoc.autoTable.previous = table; // Deprecated
1325 doc.applyStyles(doc.userStyles);
1326}
1327function printTableWithHorizontalPageBreak(doc, table, startPos, cursor) {
1328 // calculate width of columns and render only those which can fit into page
1329 var allColumnsCanFitResult = calculateAllColumnsCanFitInPage(doc, table);
1330 var settings = table.settings;
1331 if (settings.horizontalPageBreakBehaviour === 'afterAllRows') {
1332 allColumnsCanFitResult.forEach(function (colsAndIndexes, index) {
1333 doc.applyStyles(doc.userStyles);
1334 // add page to print next columns in new page
1335 if (index > 0) {
1336 // When adding a page here, make sure not to print the footers
1337 // because they were already printed before on this same loop
1338 addPage(doc, table, startPos, cursor, colsAndIndexes.columns, true);
1339 }
1340 else {
1341 // print head for selected columns
1342 printHead(doc, table, cursor, colsAndIndexes.columns);
1343 }
1344 // print body & footer for selected columns
1345 printBody(doc, table, startPos, cursor, colsAndIndexes.columns);
1346 printFoot(doc, table, cursor, colsAndIndexes.columns);
1347 });
1348 }
1349 else {
1350 var lastRowIndexOfLastPage_1 = -1;
1351 var firstColumnsToFitResult = allColumnsCanFitResult[0];
1352 var _loop_1 = function () {
1353 // Print the first columns, taking note of the last row printed
1354 var lastPrintedRowIndex = lastRowIndexOfLastPage_1;
1355 if (firstColumnsToFitResult) {
1356 doc.applyStyles(doc.userStyles);
1357 var firstColumnsToFit = firstColumnsToFitResult.columns;
1358 if (lastRowIndexOfLastPage_1 >= 0) {
1359 // When adding a page here, make sure not to print the footers
1360 // because they were already printed before on this same loop
1361 addPage(doc, table, startPos, cursor, firstColumnsToFit, true);
1362 }
1363 else {
1364 printHead(doc, table, cursor, firstColumnsToFit);
1365 }
1366 lastPrintedRowIndex = printBodyWithoutPageBreaks(doc, table, lastRowIndexOfLastPage_1 + 1, cursor, firstColumnsToFit);
1367 printFoot(doc, table, cursor, firstColumnsToFit);
1368 }
1369 // Check how many rows were printed, so that the next columns would not print more rows than that
1370 var maxNumberOfRows = lastPrintedRowIndex - lastRowIndexOfLastPage_1;
1371 // Print the next columns, never exceding maxNumberOfRows
1372 allColumnsCanFitResult.slice(1).forEach(function (colsAndIndexes) {
1373 doc.applyStyles(doc.userStyles);
1374 // When adding a page here, make sure not to print the footers
1375 // because they were already printed before on this same loop
1376 addPage(doc, table, startPos, cursor, colsAndIndexes.columns, true);
1377 printBodyWithoutPageBreaks(doc, table, lastRowIndexOfLastPage_1 + 1, cursor, colsAndIndexes.columns, maxNumberOfRows);
1378 printFoot(doc, table, cursor, colsAndIndexes.columns);
1379 });
1380 lastRowIndexOfLastPage_1 = lastPrintedRowIndex;
1381 };
1382 while (lastRowIndexOfLastPage_1 < table.body.length - 1) {
1383 _loop_1();
1384 }
1385 }
1386}
1387function printHead(doc, table, cursor, columns) {
1388 var settings = table.settings;
1389 doc.applyStyles(doc.userStyles);
1390 if (settings.showHead === 'firstPage' || settings.showHead === 'everyPage') {
1391 table.head.forEach(function (row) { return printRow(doc, table, row, cursor, columns); });
1392 }
1393}
1394function printBody(doc, table, startPos, cursor, columns) {
1395 doc.applyStyles(doc.userStyles);
1396 table.body.forEach(function (row, index) {
1397 var isLastRow = index === table.body.length - 1;
1398 printFullRow(doc, table, row, isLastRow, startPos, cursor, columns);
1399 });
1400}
1401function printBodyWithoutPageBreaks(doc, table, startRowIndex, cursor, columns, maxNumberOfRows) {
1402 doc.applyStyles(doc.userStyles);
1403 maxNumberOfRows = maxNumberOfRows !== null && maxNumberOfRows !== void 0 ? maxNumberOfRows : table.body.length;
1404 var endRowIndex = Math.min(startRowIndex + maxNumberOfRows, table.body.length);
1405 var lastPrintedRowIndex = -1;
1406 table.body.slice(startRowIndex, endRowIndex).forEach(function (row, index) {
1407 var isLastRow = startRowIndex + index === table.body.length - 1;
1408 var remainingSpace = getRemainingPageSpace(doc, table, isLastRow, cursor);
1409 if (row.canEntireRowFit(remainingSpace, columns)) {
1410 printRow(doc, table, row, cursor, columns);
1411 lastPrintedRowIndex = startRowIndex + index;
1412 }
1413 });
1414 return lastPrintedRowIndex;
1415}
1416function printFoot(doc, table, cursor, columns) {
1417 var settings = table.settings;
1418 doc.applyStyles(doc.userStyles);
1419 if (settings.showFoot === 'lastPage' || settings.showFoot === 'everyPage') {
1420 table.foot.forEach(function (row) { return printRow(doc, table, row, cursor, columns); });
1421 }
1422}
1423function getRemainingLineCount(cell, remainingPageSpace, doc) {
1424 var lineHeight = doc.getLineHeight(cell.styles.fontSize);
1425 var vPadding = cell.padding('vertical');
1426 var remainingLines = Math.floor((remainingPageSpace - vPadding) / lineHeight);
1427 return Math.max(0, remainingLines);
1428}
1429function modifyRowToFit(row, remainingPageSpace, table, doc) {
1430 var cells = {};
1431 row.spansMultiplePages = true;
1432 row.height = 0;
1433 var rowHeight = 0;
1434 for (var _i = 0, _a = table.columns; _i < _a.length; _i++) {
1435 var column = _a[_i];
1436 var cell = row.cells[column.index];
1437 if (!cell)
1438 continue;
1439 if (!Array.isArray(cell.text)) {
1440 cell.text = [cell.text];
1441 }
1442 var remainderCell = new Cell(cell.raw, cell.styles, cell.section);
1443 remainderCell = assign(remainderCell, cell);
1444 remainderCell.text = [];
1445 var remainingLineCount = getRemainingLineCount(cell, remainingPageSpace, doc);
1446 if (cell.text.length > remainingLineCount) {
1447 remainderCell.text = cell.text.splice(remainingLineCount, cell.text.length);
1448 }
1449 var scaleFactor = doc.scaleFactor();
1450 var lineHeightFactor = doc.getLineHeightFactor();
1451 cell.contentHeight = cell.getContentHeight(scaleFactor, lineHeightFactor);
1452 if (cell.contentHeight >= remainingPageSpace) {
1453 cell.contentHeight = remainingPageSpace;
1454 remainderCell.styles.minCellHeight -= remainingPageSpace;
1455 }
1456 if (cell.contentHeight > row.height) {
1457 row.height = cell.contentHeight;
1458 }
1459 remainderCell.contentHeight = remainderCell.getContentHeight(scaleFactor, lineHeightFactor);
1460 if (remainderCell.contentHeight > rowHeight) {
1461 rowHeight = remainderCell.contentHeight;
1462 }
1463 cells[column.index] = remainderCell;
1464 }
1465 var remainderRow = new Row(row.raw, -1, row.section, cells, true);
1466 remainderRow.height = rowHeight;
1467 for (var _b = 0, _c = table.columns; _b < _c.length; _b++) {
1468 var column = _c[_b];
1469 var remainderCell = remainderRow.cells[column.index];
1470 if (remainderCell) {
1471 remainderCell.height = remainderRow.height;
1472 }
1473 var cell = row.cells[column.index];
1474 if (cell) {
1475 cell.height = row.height;
1476 }
1477 }
1478 return remainderRow;
1479}
1480function shouldPrintOnCurrentPage(doc, row, remainingPageSpace, table) {
1481 var pageHeight = doc.pageSize().height;
1482 var margin = table.settings.margin;
1483 var marginHeight = margin.top + margin.bottom;
1484 var maxRowHeight = pageHeight - marginHeight;
1485 if (row.section === 'body') {
1486 // Should also take into account that head and foot is not
1487 // on every page with some settings
1488 maxRowHeight -=
1489 table.getHeadHeight(table.columns) + table.getFootHeight(table.columns);
1490 }
1491 var minRowHeight = row.getMinimumRowHeight(table.columns, doc);
1492 var minRowFits = minRowHeight < remainingPageSpace;
1493 if (minRowHeight > maxRowHeight) {
1494 console.error("Will not be able to print row ".concat(row.index, " correctly since it's minimum height is larger than page height"));
1495 return true;
1496 }
1497 if (!minRowFits) {
1498 return false;
1499 }
1500 var rowHasRowSpanCell = row.hasRowSpan(table.columns);
1501 var rowHigherThanPage = row.getMaxCellHeight(table.columns) > maxRowHeight;
1502 if (rowHigherThanPage) {
1503 if (rowHasRowSpanCell) {
1504 console.error("The content of row ".concat(row.index, " will not be drawn correctly since drawing rows with a height larger than the page height and has cells with rowspans is not supported."));
1505 }
1506 return true;
1507 }
1508 if (rowHasRowSpanCell) {
1509 // Currently a new page is required whenever a rowspan row don't fit a page.
1510 return false;
1511 }
1512 if (table.settings.rowPageBreak === 'avoid') {
1513 return false;
1514 }
1515 // In all other cases print the row on current page
1516 return true;
1517}
1518function printFullRow(doc, table, row, isLastRow, startPos, cursor, columns) {
1519 var remainingSpace = getRemainingPageSpace(doc, table, isLastRow, cursor);
1520 if (row.canEntireRowFit(remainingSpace, columns)) {
1521 // The row fits in the current page
1522 printRow(doc, table, row, cursor, columns);
1523 }
1524 else if (shouldPrintOnCurrentPage(doc, row, remainingSpace, table)) {
1525 // The row gets split in two here, each piece in one page
1526 var remainderRow = modifyRowToFit(row, remainingSpace, table, doc);
1527 printRow(doc, table, row, cursor, columns);
1528 addPage(doc, table, startPos, cursor, columns);
1529 printFullRow(doc, table, remainderRow, isLastRow, startPos, cursor, columns);
1530 }
1531 else {
1532 // The row get printed entirelly on the next page
1533 addPage(doc, table, startPos, cursor, columns);
1534 printFullRow(doc, table, row, isLastRow, startPos, cursor, columns);
1535 }
1536}
1537function printRow(doc, table, row, cursor, columns) {
1538 cursor.x = table.settings.margin.left;
1539 for (var _i = 0, columns_1 = columns; _i < columns_1.length; _i++) {
1540 var column = columns_1[_i];
1541 var cell = row.cells[column.index];
1542 if (!cell) {
1543 cursor.x += column.width;
1544 continue;
1545 }
1546 doc.applyStyles(cell.styles);
1547 cell.x = cursor.x;
1548 cell.y = cursor.y;
1549 var result = table.callCellHooks(doc, table.hooks.willDrawCell, cell, row, column, cursor);
1550 if (result === false) {
1551 cursor.x += column.width;
1552 continue;
1553 }
1554 drawCellRect(doc, cell, cursor);
1555 var textPos = cell.getTextPos();
1556 autoTableText(cell.text, textPos.x, textPos.y, {
1557 halign: cell.styles.halign,
1558 valign: cell.styles.valign,
1559 maxWidth: Math.ceil(cell.width - cell.padding('left') - cell.padding('right')),
1560 }, doc.getDocument());
1561 table.callCellHooks(doc, table.hooks.didDrawCell, cell, row, column, cursor);
1562 cursor.x += column.width;
1563 }
1564 cursor.y += row.height;
1565}
1566function drawCellRect(doc, cell, cursor) {
1567 var cellStyles = cell.styles;
1568 // https://github.com/simonbengtsson/jsPDF-AutoTable/issues/774
1569 // TODO (v4): better solution?
1570 doc.getDocument().setFillColor(doc.getDocument().getFillColor());
1571 if (typeof cellStyles.lineWidth === 'number') {
1572 // Draw cell background with normal borders
1573 var fillStyle = getFillStyle(cellStyles.lineWidth, cellStyles.fillColor);
1574 if (fillStyle) {
1575 doc.rect(cell.x, cursor.y, cell.width, cell.height, fillStyle);
1576 }
1577 }
1578 else if (typeof cellStyles.lineWidth === 'object') {
1579 // Draw cell background
1580 if (cellStyles.fillColor) {
1581 doc.rect(cell.x, cursor.y, cell.width, cell.height, 'F');
1582 }
1583 // Draw cell individual borders
1584 drawCellBorders(doc, cell, cursor, cellStyles.lineWidth);
1585 }
1586}
1587/**
1588 * Draw all specified borders. Borders are centered on cell's edge and lengthened
1589 * to overlap with neighbours to create sharp corners.
1590 * @param doc
1591 * @param cell
1592 * @param cursor
1593 * @param fillColor
1594 * @param lineWidth
1595 */
1596function drawCellBorders(doc, cell, cursor, lineWidth) {
1597 var x1, y1, x2, y2;
1598 if (lineWidth.top) {
1599 x1 = cursor.x;
1600 y1 = cursor.y;
1601 x2 = cursor.x + cell.width;
1602 y2 = cursor.y;
1603 if (lineWidth.right) {
1604 x2 += 0.5 * lineWidth.right;
1605 }
1606 if (lineWidth.left) {
1607 x1 -= 0.5 * lineWidth.left;
1608 }
1609 drawLine(lineWidth.top, x1, y1, x2, y2);
1610 }
1611 if (lineWidth.bottom) {
1612 x1 = cursor.x;
1613 y1 = cursor.y + cell.height;
1614 x2 = cursor.x + cell.width;
1615 y2 = cursor.y + cell.height;
1616 if (lineWidth.right) {
1617 x2 += 0.5 * lineWidth.right;
1618 }
1619 if (lineWidth.left) {
1620 x1 -= 0.5 * lineWidth.left;
1621 }
1622 drawLine(lineWidth.bottom, x1, y1, x2, y2);
1623 }
1624 if (lineWidth.left) {
1625 x1 = cursor.x;
1626 y1 = cursor.y;
1627 x2 = cursor.x;
1628 y2 = cursor.y + cell.height;
1629 if (lineWidth.top) {
1630 y1 -= 0.5 * lineWidth.top;
1631 }
1632 if (lineWidth.bottom) {
1633 y2 += 0.5 * lineWidth.bottom;
1634 }
1635 drawLine(lineWidth.left, x1, y1, x2, y2);
1636 }
1637 if (lineWidth.right) {
1638 x1 = cursor.x + cell.width;
1639 y1 = cursor.y;
1640 x2 = cursor.x + cell.width;
1641 y2 = cursor.y + cell.height;
1642 if (lineWidth.top) {
1643 y1 -= 0.5 * lineWidth.top;
1644 }
1645 if (lineWidth.bottom) {
1646 y2 += 0.5 * lineWidth.bottom;
1647 }
1648 drawLine(lineWidth.right, x1, y1, x2, y2);
1649 }
1650 function drawLine(width, x1, y1, x2, y2) {
1651 doc.getDocument().setLineWidth(width);
1652 doc.getDocument().line(x1, y1, x2, y2, 'S');
1653 }
1654}
1655function getRemainingPageSpace(doc, table, isLastRow, cursor) {
1656 var bottomContentHeight = table.settings.margin.bottom;
1657 var showFoot = table.settings.showFoot;
1658 if (showFoot === 'everyPage' || (showFoot === 'lastPage' && isLastRow)) {
1659 bottomContentHeight += table.getFootHeight(table.columns);
1660 }
1661 return doc.pageSize().height - cursor.y - bottomContentHeight;
1662}
1663function addPage(doc, table, startPos, cursor, columns, suppressFooter) {
1664 if (columns === void 0) { columns = []; }
1665 if (suppressFooter === void 0) { suppressFooter = false; }
1666 doc.applyStyles(doc.userStyles);
1667 if (table.settings.showFoot === 'everyPage' && !suppressFooter) {
1668 table.foot.forEach(function (row) { return printRow(doc, table, row, cursor, columns); });
1669 }
1670 // Add user content just before adding new page ensure it will
1671 // be drawn above other things on the page
1672 table.callEndPageHooks(doc, cursor);
1673 var margin = table.settings.margin;
1674 addTableBorder(doc, table, startPos, cursor);
1675 nextPage(doc);
1676 table.pageNumber++;
1677 table.pageCount++;
1678 cursor.x = margin.left;
1679 cursor.y = margin.top;
1680 startPos.y = margin.top;
1681 // call didAddPage hooks before any content is added to the page
1682 table.callWillDrawPageHooks(doc, cursor);
1683 if (table.settings.showHead === 'everyPage') {
1684 table.head.forEach(function (row) { return printRow(doc, table, row, cursor, columns); });
1685 doc.applyStyles(doc.userStyles);
1686 }
1687}
1688function nextPage(doc) {
1689 var current = doc.pageNumber();
1690 doc.setPage(current + 1);
1691 var newCurrent = doc.pageNumber();
1692 if (newCurrent === current) {
1693 doc.addPage();
1694 return true;
1695 }
1696 return false;
1697}
1698
1699/**
1700 * Calculate the column widths
1701 */
1702function calculateWidths(doc, table) {
1703 calculate(doc, table);
1704 var resizableColumns = [];
1705 var initialTableWidth = 0;
1706 table.columns.forEach(function (column) {
1707 var customWidth = column.getMaxCustomCellWidth(table);
1708 if (customWidth) {
1709 // final column width
1710 column.width = customWidth;
1711 }
1712 else {
1713 // initial column width (will be resized)
1714 column.width = column.wrappedWidth;
1715 resizableColumns.push(column);
1716 }
1717 initialTableWidth += column.width;
1718 });
1719 // width difference that needs to be distributed
1720 var resizeWidth = table.getWidth(doc.pageSize().width) - initialTableWidth;
1721 // first resize attempt: with respect to minReadableWidth and minWidth
1722 if (resizeWidth) {
1723 resizeWidth = resizeColumns(resizableColumns, resizeWidth, function (column) {
1724 return Math.max(column.minReadableWidth, column.minWidth);
1725 });
1726 }
1727 // second resize attempt: ignore minReadableWidth but respect minWidth
1728 if (resizeWidth) {
1729 resizeWidth = resizeColumns(resizableColumns, resizeWidth, function (column) { return column.minWidth; });
1730 }
1731 resizeWidth = Math.abs(resizeWidth);
1732 if (!table.settings.horizontalPageBreak &&
1733 resizeWidth > 0.1 / doc.scaleFactor()) {
1734 // Table can't get smaller due to custom-width or minWidth restrictions
1735 // We can't really do much here. Up to user to for example
1736 // reduce font size, increase page size or remove custom cell widths
1737 // to allow more columns to be reduced in size
1738 resizeWidth = resizeWidth < 1 ? resizeWidth : Math.round(resizeWidth);
1739 console.warn("Of the table content, ".concat(resizeWidth, " units width could not fit page"));
1740 }
1741 applyColSpans(table);
1742 fitContent(table, doc);
1743 applyRowSpans(table);
1744}
1745function calculate(doc, table) {
1746 var sf = doc.scaleFactor();
1747 var horizontalPageBreak = table.settings.horizontalPageBreak;
1748 var availablePageWidth = getPageAvailableWidth(doc, table);
1749 table.allRows().forEach(function (row) {
1750 for (var _i = 0, _a = table.columns; _i < _a.length; _i++) {
1751 var column = _a[_i];
1752 var cell = row.cells[column.index];
1753 if (!cell)
1754 continue;
1755 var hooks = table.hooks.didParseCell;
1756 table.callCellHooks(doc, hooks, cell, row, column, null);
1757 var padding = cell.padding('horizontal');
1758 cell.contentWidth = getStringWidth(cell.text, cell.styles, doc) + padding;
1759 // Using [^\S\u00A0] instead of \s ensures that we split the text on all
1760 // whitespace except non-breaking spaces (\u00A0). We need to preserve
1761 // them in the split process to ensure correct word separation and width
1762 // calculation.
1763 var longestWordWidth = getStringWidth(cell.text.join(' ').split(/[^\S\u00A0]+/), cell.styles, doc);
1764 cell.minReadableWidth = longestWordWidth + cell.padding('horizontal');
1765 if (typeof cell.styles.cellWidth === 'number') {
1766 cell.minWidth = cell.styles.cellWidth;
1767 cell.wrappedWidth = cell.styles.cellWidth;
1768 }
1769 else if (cell.styles.cellWidth === 'wrap' ||
1770 horizontalPageBreak === true) {
1771 // cell width should not be more than available page width
1772 if (cell.contentWidth > availablePageWidth) {
1773 cell.minWidth = availablePageWidth;
1774 cell.wrappedWidth = availablePageWidth;
1775 }
1776 else {
1777 cell.minWidth = cell.contentWidth;
1778 cell.wrappedWidth = cell.contentWidth;
1779 }
1780 }
1781 else {
1782 // auto
1783 var defaultMinWidth = 10 / sf;
1784 cell.minWidth = cell.styles.minCellWidth || defaultMinWidth;
1785 cell.wrappedWidth = cell.contentWidth;
1786 if (cell.minWidth > cell.wrappedWidth) {
1787 cell.wrappedWidth = cell.minWidth;
1788 }
1789 }
1790 }
1791 });
1792 table.allRows().forEach(function (row) {
1793 for (var _i = 0, _a = table.columns; _i < _a.length; _i++) {
1794 var column = _a[_i];
1795 var cell = row.cells[column.index];
1796 // For now we ignore the minWidth and wrappedWidth of colspan cells when calculating colspan widths.
1797 // Could probably be improved upon however.
1798 if (cell && cell.colSpan === 1) {
1799 column.wrappedWidth = Math.max(column.wrappedWidth, cell.wrappedWidth);
1800 column.minWidth = Math.max(column.minWidth, cell.minWidth);
1801 column.minReadableWidth = Math.max(column.minReadableWidth, cell.minReadableWidth);
1802 }
1803 else {
1804 // Respect cellWidth set in columnStyles even if there is no cells for this column
1805 // or if the column only have colspan cells. Since the width of colspan cells
1806 // does not affect the width of columns, setting columnStyles cellWidth enables the
1807 // user to at least do it manually.
1808 // Note that this is not perfect for now since for example row and table styles are
1809 // not accounted for
1810 var columnStyles = table.styles.columnStyles[column.dataKey] ||
1811 table.styles.columnStyles[column.index] ||
1812 {};
1813 var cellWidth = columnStyles.cellWidth || columnStyles.minCellWidth;
1814 if (cellWidth && typeof cellWidth === 'number') {
1815 column.minWidth = cellWidth;
1816 column.wrappedWidth = cellWidth;
1817 }
1818 }
1819 if (cell) {
1820 // Make sure all columns get at least min width even though width calculations are not based on them
1821 if (cell.colSpan > 1 && !column.minWidth) {
1822 column.minWidth = cell.minWidth;
1823 }
1824 if (cell.colSpan > 1 && !column.wrappedWidth) {
1825 column.wrappedWidth = cell.minWidth;
1826 }
1827 }
1828 }
1829 });
1830}
1831/**
1832 * Distribute resizeWidth on passed resizable columns
1833 */
1834function resizeColumns(columns, resizeWidth, getMinWidth) {
1835 var initialResizeWidth = resizeWidth;
1836 var sumWrappedWidth = columns.reduce(function (acc, column) { return acc + column.wrappedWidth; }, 0);
1837 for (var i = 0; i < columns.length; i++) {
1838 var column = columns[i];
1839 var ratio = column.wrappedWidth / sumWrappedWidth;
1840 var suggestedChange = initialResizeWidth * ratio;
1841 var suggestedWidth = column.width + suggestedChange;
1842 var minWidth = getMinWidth(column);
1843 var newWidth = suggestedWidth < minWidth ? minWidth : suggestedWidth;
1844 resizeWidth -= newWidth - column.width;
1845 column.width = newWidth;
1846 }
1847 resizeWidth = Math.round(resizeWidth * 1e10) / 1e10;
1848 // Run the resizer again if there's remaining width needs
1849 // to be distributed and there're columns that can be resized
1850 if (resizeWidth) {
1851 var resizableColumns = columns.filter(function (column) {
1852 return resizeWidth < 0
1853 ? column.width > getMinWidth(column) // check if column can shrink
1854 : true; // check if column can grow
1855 });
1856 if (resizableColumns.length) {
1857 resizeWidth = resizeColumns(resizableColumns, resizeWidth, getMinWidth);
1858 }
1859 }
1860 return resizeWidth;
1861}
1862function applyRowSpans(table) {
1863 var rowSpanCells = {};
1864 var colRowSpansLeft = 1;
1865 var all = table.allRows();
1866 for (var rowIndex = 0; rowIndex < all.length; rowIndex++) {
1867 var row = all[rowIndex];
1868 for (var _i = 0, _a = table.columns; _i < _a.length; _i++) {
1869 var column = _a[_i];
1870 var data = rowSpanCells[column.index];
1871 if (colRowSpansLeft > 1) {
1872 colRowSpansLeft--;
1873 delete row.cells[column.index];
1874 }
1875 else if (data) {
1876 data.cell.height += row.height;
1877 colRowSpansLeft = data.cell.colSpan;
1878 delete row.cells[column.index];
1879 data.left--;
1880 if (data.left <= 1) {
1881 delete rowSpanCells[column.index];
1882 }
1883 }
1884 else {
1885 var cell = row.cells[column.index];
1886 if (!cell) {
1887 continue;
1888 }
1889 cell.height = row.height;
1890 if (cell.rowSpan > 1) {
1891 var remaining = all.length - rowIndex;
1892 var left = cell.rowSpan > remaining ? remaining : cell.rowSpan;
1893 rowSpanCells[column.index] = { cell: cell, left: left, row: row };
1894 }
1895 }
1896 }
1897 }
1898}
1899function applyColSpans(table) {
1900 var all = table.allRows();
1901 for (var rowIndex = 0; rowIndex < all.length; rowIndex++) {
1902 var row = all[rowIndex];
1903 var colSpanCell = null;
1904 var combinedColSpanWidth = 0;
1905 var colSpansLeft = 0;
1906 for (var columnIndex = 0; columnIndex < table.columns.length; columnIndex++) {
1907 var column = table.columns[columnIndex];
1908 // Width and colspan
1909 colSpansLeft -= 1;
1910 if (colSpansLeft > 1 && table.columns[columnIndex + 1]) {
1911 combinedColSpanWidth += column.width;
1912 delete row.cells[column.index];
1913 }
1914 else if (colSpanCell) {
1915 var cell = colSpanCell;
1916 delete row.cells[column.index];
1917 colSpanCell = null;
1918 cell.width = column.width + combinedColSpanWidth;
1919 }
1920 else {
1921 var cell = row.cells[column.index];
1922 if (!cell)
1923 continue;
1924 colSpansLeft = cell.colSpan;
1925 combinedColSpanWidth = 0;
1926 if (cell.colSpan > 1) {
1927 colSpanCell = cell;
1928 combinedColSpanWidth += column.width;
1929 continue;
1930 }
1931 cell.width = column.width + combinedColSpanWidth;
1932 }
1933 }
1934 }
1935}
1936function fitContent(table, doc) {
1937 var rowSpanHeight = { count: 0, height: 0 };
1938 for (var _i = 0, _a = table.allRows(); _i < _a.length; _i++) {
1939 var row = _a[_i];
1940 for (var _b = 0, _c = table.columns; _b < _c.length; _b++) {
1941 var column = _c[_b];
1942 var cell = row.cells[column.index];
1943 if (!cell)
1944 continue;
1945 doc.applyStyles(cell.styles, true);
1946 var textSpace = cell.width - cell.padding('horizontal');
1947 if (cell.styles.overflow === 'linebreak') {
1948 // Add one pt to textSpace to fix rounding error
1949 cell.text = doc.splitTextToSize(cell.text, textSpace + 1 / doc.scaleFactor(), { fontSize: cell.styles.fontSize });
1950 }
1951 else if (cell.styles.overflow === 'ellipsize') {
1952 cell.text = ellipsize(cell.text, textSpace, cell.styles, doc, '...');
1953 }
1954 else if (cell.styles.overflow === 'hidden') {
1955 cell.text = ellipsize(cell.text, textSpace, cell.styles, doc, '');
1956 }
1957 else if (typeof cell.styles.overflow === 'function') {
1958 var result = cell.styles.overflow(cell.text, textSpace);
1959 if (typeof result === 'string') {
1960 cell.text = [result];
1961 }
1962 else {
1963 cell.text = result;
1964 }
1965 }
1966 cell.contentHeight = cell.getContentHeight(doc.scaleFactor(), doc.getLineHeightFactor());
1967 var realContentHeight = cell.contentHeight / cell.rowSpan;
1968 if (cell.rowSpan > 1 &&
1969 rowSpanHeight.count * rowSpanHeight.height <
1970 realContentHeight * cell.rowSpan) {
1971 rowSpanHeight = { height: realContentHeight, count: cell.rowSpan };
1972 }
1973 else if (rowSpanHeight && rowSpanHeight.count > 0) {
1974 if (rowSpanHeight.height > realContentHeight) {
1975 realContentHeight = rowSpanHeight.height;
1976 }
1977 }
1978 if (realContentHeight > row.height) {
1979 row.height = realContentHeight;
1980 }
1981 }
1982 rowSpanHeight.count--;
1983 }
1984}
1985function ellipsize(text, width, styles, doc, overflow) {
1986 return text.map(function (str) { return ellipsizeStr(str, width, styles, doc, overflow); });
1987}
1988function ellipsizeStr(text, width, styles, doc, overflow) {
1989 var precision = 10000 * doc.scaleFactor();
1990 width = Math.ceil(width * precision) / precision;
1991 if (width >= getStringWidth(text, styles, doc)) {
1992 return text;
1993 }
1994 while (width < getStringWidth(text + overflow, styles, doc)) {
1995 if (text.length <= 1) {
1996 break;
1997 }
1998 text = text.substring(0, text.length - 1);
1999 }
2000 return text.trim() + overflow;
2001}
2002
2003function createTable(jsPDFDoc, input) {
2004 var doc = new DocHandler(jsPDFDoc);
2005 var content = parseContent(input, doc.scaleFactor());
2006 var table = new Table(input, content);
2007 calculateWidths(doc, table);
2008 doc.applyStyles(doc.userStyles);
2009 return table;
2010}
2011function parseContent(input, sf) {
2012 var content = input.content;
2013 var columns = createColumns(content.columns);
2014 // If no head or foot is set, try generating it with content from columns
2015 if (content.head.length === 0) {
2016 var sectionRow = generateSectionRow(columns, 'head');
2017 if (sectionRow)
2018 content.head.push(sectionRow);
2019 }
2020 if (content.foot.length === 0) {
2021 var sectionRow = generateSectionRow(columns, 'foot');
2022 if (sectionRow)
2023 content.foot.push(sectionRow);
2024 }
2025 var theme = input.settings.theme;
2026 var styles = input.styles;
2027 return {
2028 columns: columns,
2029 head: parseSection('head', content.head, columns, styles, theme, sf),
2030 body: parseSection('body', content.body, columns, styles, theme, sf),
2031 foot: parseSection('foot', content.foot, columns, styles, theme, sf),
2032 };
2033}
2034function parseSection(sectionName, sectionRows, columns, styleProps, theme, scaleFactor) {
2035 var rowSpansLeftForColumn = {};
2036 var result = sectionRows.map(function (rawRow, rowIndex) {
2037 var skippedRowForRowSpans = 0;
2038 var cells = {};
2039 var colSpansAdded = 0;
2040 var columnSpansLeft = 0;
2041 for (var _i = 0, columns_1 = columns; _i < columns_1.length; _i++) {
2042 var column = columns_1[_i];
2043 if (rowSpansLeftForColumn[column.index] == null ||
2044 rowSpansLeftForColumn[column.index].left === 0) {
2045 if (columnSpansLeft === 0) {
2046 var rawCell = void 0;
2047 if (Array.isArray(rawRow)) {
2048 rawCell =
2049 rawRow[column.index - colSpansAdded - skippedRowForRowSpans];
2050 }
2051 else {
2052 rawCell = rawRow[column.dataKey];
2053 }
2054 var cellInputStyles = {};
2055 if (typeof rawCell === 'object' && !Array.isArray(rawCell)) {
2056 cellInputStyles = (rawCell === null || rawCell === void 0 ? void 0 : rawCell.styles) || {};
2057 }
2058 var styles = cellStyles(sectionName, column, rowIndex, theme, styleProps, scaleFactor, cellInputStyles);
2059 var cell = new Cell(rawCell, styles, sectionName);
2060 // dataKey is not used internally no more but keep for
2061 // backwards compat in hooks
2062 cells[column.dataKey] = cell;
2063 cells[column.index] = cell;
2064 columnSpansLeft = cell.colSpan - 1;
2065 rowSpansLeftForColumn[column.index] = {
2066 left: cell.rowSpan - 1,
2067 times: columnSpansLeft,
2068 };
2069 }
2070 else {
2071 columnSpansLeft--;
2072 colSpansAdded++;
2073 }
2074 }
2075 else {
2076 rowSpansLeftForColumn[column.index].left--;
2077 columnSpansLeft = rowSpansLeftForColumn[column.index].times;
2078 skippedRowForRowSpans++;
2079 }
2080 }
2081 return new Row(rawRow, rowIndex, sectionName, cells);
2082 });
2083 return result;
2084}
2085function generateSectionRow(columns, section) {
2086 var sectionRow = {};
2087 columns.forEach(function (col) {
2088 if (col.raw != null) {
2089 var title = getSectionTitle(section, col.raw);
2090 if (title != null)
2091 sectionRow[col.dataKey] = title;
2092 }
2093 });
2094 return Object.keys(sectionRow).length > 0 ? sectionRow : null;
2095}
2096function getSectionTitle(section, column) {
2097 if (section === 'head') {
2098 if (typeof column === 'object') {
2099 return column.header || column.title || null;
2100 }
2101 else if (typeof column === 'string' || typeof column === 'number') {
2102 return column;
2103 }
2104 }
2105 else if (section === 'foot' && typeof column === 'object') {
2106 return column.footer;
2107 }
2108 return null;
2109}
2110function createColumns(columns) {
2111 return columns.map(function (input, index) {
2112 var _a, _b;
2113 var key;
2114 if (typeof input === 'object') {
2115 key = (_b = (_a = input.dataKey) !== null && _a !== void 0 ? _a : input.key) !== null && _b !== void 0 ? _b : index;
2116 }
2117 else {
2118 key = index;
2119 }
2120 return new Column(key, input, index);
2121 });
2122}
2123function cellStyles(sectionName, column, rowIndex, themeName, styles, scaleFactor, cellInputStyles) {
2124 var theme = getTheme(themeName);
2125 var sectionStyles;
2126 if (sectionName === 'head') {
2127 sectionStyles = styles.headStyles;
2128 }
2129 else if (sectionName === 'body') {
2130 sectionStyles = styles.bodyStyles;
2131 }
2132 else if (sectionName === 'foot') {
2133 sectionStyles = styles.footStyles;
2134 }
2135 var otherStyles = assign({}, theme.table, theme[sectionName], styles.styles, sectionStyles);
2136 var columnStyles = styles.columnStyles[column.dataKey] ||
2137 styles.columnStyles[column.index] ||
2138 {};
2139 var colStyles = sectionName === 'body' ? columnStyles : {};
2140 var rowStyles = sectionName === 'body' && rowIndex % 2 === 0
2141 ? assign({}, theme.alternateRow, styles.alternateRowStyles)
2142 : {};
2143 var defaultStyle = defaultStyles(scaleFactor);
2144 var themeStyles = assign({}, defaultStyle, otherStyles, rowStyles, colStyles);
2145 return assign(themeStyles, cellInputStyles);
2146}
2147
2148function _applyPlugin (jsPDF) {
2149 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2150 jsPDF.API.autoTable = function () {
2151 var args = [];
2152 for (var _i = 0; _i < arguments.length; _i++) {
2153 args[_i] = arguments[_i];
2154 }
2155 var options;
2156 if (args.length === 1) {
2157 options = args[0];
2158 }
2159 else {
2160 console.error('Use of deprecated autoTable initiation');
2161 options = args[2] || {};
2162 options.columns = args[0];
2163 options.body = args[1];
2164 }
2165 var input = parseInput(this, options);
2166 var table = createTable(this, input);
2167 drawTable(this, table);
2168 return this;
2169 };
2170 // Assign false to enable `doc.lastAutoTable.finalY || 40` sugar
2171 jsPDF.API.lastAutoTable = false;
2172 jsPDF.API.previousAutoTable = false; // deprecated in v3
2173 jsPDF.API.autoTable.previous = false; // deprecated in v3
2174 jsPDF.API.autoTableText = function (text, x, y, styles) {
2175 autoTableText(text, x, y, styles, this);
2176 };
2177 jsPDF.API.autoTableSetDefaults = function (defaults) {
2178 DocHandler.setDefaults(defaults, this);
2179 return this;
2180 };
2181 jsPDF.autoTableSetDefaults = function (defaults, doc) {
2182 DocHandler.setDefaults(defaults, doc);
2183 };
2184 jsPDF.API.autoTableHtmlToJson = function (tableElem, includeHiddenElements) {
2185 var _a;
2186 if (includeHiddenElements === void 0) { includeHiddenElements = false; }
2187 if (typeof window === 'undefined') {
2188 console.error('Cannot run autoTableHtmlToJson in non browser environment');
2189 return null;
2190 }
2191 var doc = new DocHandler(this);
2192 var _b = parseHtml(doc, tableElem, window, includeHiddenElements, false), head = _b.head, body = _b.body;
2193 var columns = ((_a = head[0]) === null || _a === void 0 ? void 0 : _a.map(function (c) { return c.content; })) || [];
2194 return { columns: columns, rows: body, data: body };
2195 };
2196 /**
2197 * @deprecated
2198 */
2199 jsPDF.API.autoTableEndPosY = function () {
2200 console.error('Use of deprecated function: autoTableEndPosY. Use doc.lastAutoTable.finalY instead.');
2201 var prev = this.lastAutoTable;
2202 if (prev && prev.finalY) {
2203 return prev.finalY;
2204 }
2205 else {
2206 return 0;
2207 }
2208 };
2209 /**
2210 * @deprecated
2211 */
2212 jsPDF.API.autoTableAddPageContent = function (hook) {
2213 console.error('Use of deprecated function: autoTableAddPageContent. Use jsPDF.autoTableSetDefaults({didDrawPage: () => {}}) instead.');
2214 if (!jsPDF.API.autoTable.globalDefaults) {
2215 jsPDF.API.autoTable.globalDefaults = {};
2216 }
2217 jsPDF.API.autoTable.globalDefaults.addPageContent = hook;
2218 return this;
2219 };
2220 /**
2221 * @deprecated
2222 */
2223 jsPDF.API.autoTableAddPage = function () {
2224 console.error('Use of deprecated function: autoTableAddPage. Use doc.addPage()');
2225 this.addPage();
2226 return this;
2227 };
2228}
2229
2230// export { applyPlugin } didn't export applyPlugin
2231// to index.d.ts for some reason
2232function applyPlugin(jsPDF) {
2233 _applyPlugin(jsPDF);
2234}
2235function autoTable(d, options) {
2236 var input = parseInput(d, options);
2237 var table = createTable(d, input);
2238 drawTable(d, table);
2239}
2240// Experimental export
2241function __createTable(d, options) {
2242 var input = parseInput(d, options);
2243 return createTable(d, input);
2244}
2245function __drawTable(d, table) {
2246 drawTable(d, table);
2247}
2248try {
2249 // eslint-disable-next-line @typescript-eslint/no-var-requires
2250 var jsPDF = require('jspdf');
2251 // Webpack imported jspdf instead of jsPDF for some reason
2252 // while it seemed to work everywhere else.
2253 if (jsPDF.jsPDF)
2254 jsPDF = jsPDF.jsPDF;
2255 applyPlugin(jsPDF);
2256}
2257catch (error) {
2258 // Importing jspdf in nodejs environments does not work as of jspdf
2259 // 1.5.3 so we need to silence potential errors to support using for example
2260 // the nodejs jspdf dist files with the exported applyPlugin
2261}
2262
2263export { Cell, CellHookData, Column, Row, Table, __createTable, __drawTable, applyPlugin, autoTable as default };