pdfmake 0.3.0-beta.8 → 0.3.0
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/CHANGELOG.md +7 -40
- package/LICENSE +1 -1
- package/README.md +78 -85
- package/build/pdfmake.js +60308 -68400
- package/build/pdfmake.js.map +1 -1
- package/build/pdfmake.min.js +2 -2
- package/build/pdfmake.min.js.map +1 -1
- package/build/vfs_fonts.js +4 -4
- package/fonts/Roboto/Roboto-Italic.ttf +0 -0
- package/fonts/Roboto/Roboto-Medium.ttf +0 -0
- package/fonts/Roboto/Roboto-MediumItalic.ttf +0 -0
- package/fonts/Roboto/Roboto-Regular.ttf +0 -0
- package/js/3rd-party/svg-to-pdfkit/source.js +3626 -0
- package/js/3rd-party/svg-to-pdfkit.js +7 -0
- package/js/DocMeasure.js +645 -0
- package/js/DocPreprocessor.js +253 -0
- package/js/DocumentContext.js +305 -0
- package/js/ElementWriter.js +354 -0
- package/js/LayoutBuilder.js +1105 -0
- package/js/Line.js +105 -0
- package/js/OutputDocument.js +64 -0
- package/js/OutputDocumentServer.js +22 -0
- package/js/PDFDocument.js +144 -0
- package/js/PageElementWriter.js +155 -0
- package/js/PageSize.js +74 -0
- package/js/Printer.js +291 -0
- package/js/Renderer.js +383 -0
- package/js/SVGMeasure.js +69 -0
- package/js/StyleContextStack.js +168 -0
- package/js/TableProcessor.js +548 -0
- package/js/TextBreaker.js +166 -0
- package/js/TextDecorator.js +143 -0
- package/js/TextInlines.js +206 -0
- package/js/URLResolver.js +43 -0
- package/js/base.js +52 -0
- package/js/browser-extensions/OutputDocumentBrowser.js +81 -0
- package/js/browser-extensions/fonts/Roboto.js +38 -0
- package/js/browser-extensions/index.js +53 -0
- package/js/browser-extensions/pdfMake.js +3 -0
- package/js/browser-extensions/standard-fonts/Courier.js +38 -0
- package/js/browser-extensions/standard-fonts/Helvetica.js +38 -0
- package/js/browser-extensions/standard-fonts/Symbol.js +23 -0
- package/js/browser-extensions/standard-fonts/Times.js +38 -0
- package/js/browser-extensions/standard-fonts/ZapfDingbats.js +23 -0
- package/js/browser-extensions/virtual-fs-cjs.js +3 -0
- package/js/columnCalculator.js +148 -0
- package/js/helpers/node.js +98 -0
- package/js/helpers/tools.js +46 -0
- package/js/helpers/variableType.js +59 -0
- package/js/index.js +15 -0
- package/js/qrEnc.js +721 -0
- package/js/standardPageSizes.js +56 -0
- package/js/tableLayouts.js +98 -0
- package/js/virtual-fs.js +60 -0
- package/package.json +25 -24
- package/src/DocMeasure.js +28 -7
- package/src/DocPreprocessor.js +25 -6
- package/src/DocumentContext.js +62 -33
- package/src/ElementWriter.js +30 -7
- package/src/LayoutBuilder.js +557 -120
- package/src/OutputDocument.js +23 -37
- package/src/OutputDocumentServer.js +6 -11
- package/src/PDFDocument.js +1 -1
- package/src/PageElementWriter.js +21 -2
- package/src/Printer.js +134 -131
- package/src/Renderer.js +13 -15
- package/src/SVGMeasure.js +2 -2
- package/src/StyleContextStack.js +7 -44
- package/src/TableProcessor.js +62 -22
- package/src/TextBreaker.js +24 -5
- package/src/TextInlines.js +1 -1
- package/src/URLResolver.js +24 -58
- package/src/base.js +1 -1
- package/src/browser-extensions/OutputDocumentBrowser.js +33 -71
- package/src/browser-extensions/index.js +3 -3
- package/src/browser-extensions/pdfMake.js +0 -14
- package/src/browser-extensions/standard-fonts/Courier.js +4 -4
- package/src/browser-extensions/standard-fonts/Helvetica.js +4 -4
- package/src/browser-extensions/standard-fonts/Symbol.js +1 -1
- package/src/browser-extensions/standard-fonts/Times.js +4 -4
- package/src/browser-extensions/standard-fonts/ZapfDingbats.js +1 -1
- package/src/columnCalculator.js +24 -3
- package/src/helpers/tools.js +5 -0
- package/src/helpers/variableType.js +11 -0
- package/src/index.js +1 -1
- package/standard-fonts/Helvetica.js +0 -1
- package/src/browser-extensions/URLBrowserResolver.js +0 -84
package/src/TableProcessor.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ColumnCalculator from './columnCalculator';
|
|
2
|
-
import { isNumber } from './helpers/variableType';
|
|
2
|
+
import { isNumber, isPositiveInteger } from './helpers/variableType';
|
|
3
3
|
|
|
4
4
|
class TableProcessor {
|
|
5
5
|
constructor(tableNode) {
|
|
@@ -95,28 +95,48 @@ class TableProcessor {
|
|
|
95
95
|
this.layout = tableNode._layout;
|
|
96
96
|
|
|
97
97
|
availableWidth = writer.context().availableWidth - this.offsets.total;
|
|
98
|
-
ColumnCalculator.buildColumnWidths(tableNode.table.widths, availableWidth);
|
|
98
|
+
ColumnCalculator.buildColumnWidths(tableNode.table.widths, availableWidth, this.offsets.total, tableNode);
|
|
99
99
|
|
|
100
100
|
this.tableWidth = tableNode._offsets.total + getTableInnerContentWidth();
|
|
101
101
|
this.rowSpanData = prepareRowSpanData();
|
|
102
102
|
this.cleanUpRepeatables = false;
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
// headersRows and rowsWithoutPageBreak (headerRows + keepWithHeaderRows)
|
|
105
|
+
this.headerRows = 0;
|
|
106
|
+
this.rowsWithoutPageBreak = 0;
|
|
107
|
+
|
|
108
|
+
const headerRows = tableNode.table.headerRows;
|
|
109
|
+
|
|
110
|
+
if (isPositiveInteger(headerRows)) {
|
|
111
|
+
this.headerRows = headerRows;
|
|
112
|
+
|
|
113
|
+
if (this.headerRows > tableNode.table.body.length) {
|
|
114
|
+
throw new Error(`Too few rows in the table. Property headerRows requires at least ${this.headerRows}, contains only ${tableNode.table.body.length}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
this.rowsWithoutPageBreak = this.headerRows;
|
|
118
|
+
|
|
119
|
+
const keepWithHeaderRows = tableNode.table.keepWithHeaderRows;
|
|
120
|
+
|
|
121
|
+
if (isPositiveInteger(keepWithHeaderRows)) {
|
|
122
|
+
this.rowsWithoutPageBreak += keepWithHeaderRows;
|
|
123
|
+
}
|
|
107
124
|
}
|
|
108
125
|
|
|
109
|
-
this.rowsWithoutPageBreak = this.headerRows + (tableNode.table.keepWithHeaderRows || 0);
|
|
110
126
|
this.dontBreakRows = tableNode.table.dontBreakRows || false;
|
|
111
127
|
|
|
112
|
-
if (this.rowsWithoutPageBreak) {
|
|
128
|
+
if (this.rowsWithoutPageBreak || this.dontBreakRows) {
|
|
113
129
|
writer.beginUnbreakableBlock();
|
|
130
|
+
// Draw the top border of the table
|
|
131
|
+
this.drawHorizontalLine(0, writer);
|
|
132
|
+
if (this.rowsWithoutPageBreak && this.dontBreakRows) {
|
|
133
|
+
// We just increase the value of transactionLevel
|
|
134
|
+
writer.beginUnbreakableBlock();
|
|
135
|
+
}
|
|
114
136
|
}
|
|
115
137
|
|
|
116
138
|
// update the border properties of all cells before drawing any lines
|
|
117
139
|
prepareCellBorders(this.tableNode.table.body);
|
|
118
|
-
|
|
119
|
-
this.drawHorizontalLine(0, writer);
|
|
120
140
|
}
|
|
121
141
|
|
|
122
142
|
onRowBreak(rowIndex, writer) {
|
|
@@ -135,7 +155,12 @@ class TableProcessor {
|
|
|
135
155
|
|
|
136
156
|
this.rowCallback = this.onRowBreak(rowIndex, writer);
|
|
137
157
|
writer.addListener('pageChanged', this.rowCallback);
|
|
138
|
-
if (this.dontBreakRows) {
|
|
158
|
+
if (rowIndex == 0 && !this.dontBreakRows && !this.rowsWithoutPageBreak) {
|
|
159
|
+
// We store the 'y' to draw later and if necessary the top border of the table
|
|
160
|
+
this._tableTopBorderY = writer.context().y;
|
|
161
|
+
writer.context().moveDown(this.topLineWidth);
|
|
162
|
+
}
|
|
163
|
+
if (this.dontBreakRows && rowIndex > 0) {
|
|
139
164
|
writer.beginUnbreakableBlock();
|
|
140
165
|
}
|
|
141
166
|
this.rowTopY = writer.context().y;
|
|
@@ -146,7 +171,7 @@ class TableProcessor {
|
|
|
146
171
|
writer.context().moveDown(this.rowPaddingTop);
|
|
147
172
|
}
|
|
148
173
|
|
|
149
|
-
drawHorizontalLine(lineIndex, writer, overrideY) {
|
|
174
|
+
drawHorizontalLine(lineIndex, writer, overrideY, moveDown = true, forcePage) {
|
|
150
175
|
let lineWidth = this.layout.hLineWidth(lineIndex, this.tableNode);
|
|
151
176
|
if (lineWidth) {
|
|
152
177
|
let style = this.layout.hLineStyle(lineIndex, this.tableNode);
|
|
@@ -244,7 +269,7 @@ class TableProcessor {
|
|
|
244
269
|
lineWidth: lineWidth,
|
|
245
270
|
dash: dash,
|
|
246
271
|
lineColor: borderColor
|
|
247
|
-
}, false, overrideY);
|
|
272
|
+
}, false, isNumber(overrideY), null, forcePage);
|
|
248
273
|
currentLine = null;
|
|
249
274
|
borderColor = null;
|
|
250
275
|
cellAbove = null;
|
|
@@ -254,7 +279,9 @@ class TableProcessor {
|
|
|
254
279
|
}
|
|
255
280
|
}
|
|
256
281
|
|
|
257
|
-
|
|
282
|
+
if (moveDown) {
|
|
283
|
+
writer.context().moveDown(lineWidth);
|
|
284
|
+
}
|
|
258
285
|
}
|
|
259
286
|
}
|
|
260
287
|
|
|
@@ -390,6 +417,15 @@ class TableProcessor {
|
|
|
390
417
|
ys[ys.length - 1].y1 = endingY;
|
|
391
418
|
|
|
392
419
|
let skipOrphanePadding = (ys[0].y1 - ys[0].y0 === this.rowPaddingTop);
|
|
420
|
+
if (rowIndex === 0 && !skipOrphanePadding && !this.rowsWithoutPageBreak && !this.dontBreakRows) {
|
|
421
|
+
// Draw the top border of the table
|
|
422
|
+
let pageTableStartedAt = null;
|
|
423
|
+
if (pageBreaks && pageBreaks.length > 0) {
|
|
424
|
+
// Get the page where table started at
|
|
425
|
+
pageTableStartedAt = pageBreaks[0].prevPage;
|
|
426
|
+
}
|
|
427
|
+
this.drawHorizontalLine(0, writer, this._tableTopBorderY, false, pageTableStartedAt);
|
|
428
|
+
}
|
|
393
429
|
for (let yi = (skipOrphanePadding ? 1 : 0), yl = ys.length; yi < yl; yi++) {
|
|
394
430
|
let willBreak = yi < ys.length - 1;
|
|
395
431
|
let rowBreakWithoutHeader = (yi > 0 && !this.headerRows);
|
|
@@ -409,6 +445,14 @@ class TableProcessor {
|
|
|
409
445
|
this.reservedAtBottom = 0;
|
|
410
446
|
}
|
|
411
447
|
|
|
448
|
+
// Draw horizontal lines before the vertical lines so they are not overridden
|
|
449
|
+
if (willBreak && this.layout.hLineWhenBroken !== false) {
|
|
450
|
+
this.drawHorizontalLine(rowIndex + 1, writer, y2);
|
|
451
|
+
}
|
|
452
|
+
if (rowBreakWithoutHeader && this.layout.hLineWhenBroken !== false) {
|
|
453
|
+
this.drawHorizontalLine(rowIndex, writer, y1);
|
|
454
|
+
}
|
|
455
|
+
|
|
412
456
|
for (let i = 0, l = xs.length; i < l; i++) {
|
|
413
457
|
let leftCellBorder = false;
|
|
414
458
|
let rightCellBorder = false;
|
|
@@ -474,7 +518,9 @@ class TableProcessor {
|
|
|
474
518
|
h: bgHeight,
|
|
475
519
|
lineWidth: 0,
|
|
476
520
|
color: fillColor,
|
|
477
|
-
fillOpacity: fillOpacity
|
|
521
|
+
fillOpacity: fillOpacity,
|
|
522
|
+
// mark if we are in an unbreakable block
|
|
523
|
+
_isFillColorFromUnbreakable: !!writer.transactionLevel
|
|
478
524
|
}, false, true, writer.context().backgroundLength[writer.context().page]);
|
|
479
525
|
}
|
|
480
526
|
|
|
@@ -493,13 +539,6 @@ class TableProcessor {
|
|
|
493
539
|
}
|
|
494
540
|
}
|
|
495
541
|
}
|
|
496
|
-
|
|
497
|
-
if (willBreak && this.layout.hLineWhenBroken !== false) {
|
|
498
|
-
this.drawHorizontalLine(rowIndex + 1, writer, y2);
|
|
499
|
-
}
|
|
500
|
-
if (rowBreakWithoutHeader && this.layout.hLineWhenBroken !== false) {
|
|
501
|
-
this.drawHorizontalLine(rowIndex, writer, y1);
|
|
502
|
-
}
|
|
503
542
|
}
|
|
504
543
|
|
|
505
544
|
writer.context().page = endingPage;
|
|
@@ -538,7 +577,8 @@ class TableProcessor {
|
|
|
538
577
|
|
|
539
578
|
if (this.dontBreakRows) {
|
|
540
579
|
const pageChangedCallback = () => {
|
|
541
|
-
if (!this.headerRows && this.layout.hLineWhenBroken !== false) {
|
|
580
|
+
if (rowIndex > 0 && !this.headerRows && this.layout.hLineWhenBroken !== false) {
|
|
581
|
+
// Draw the top border of the row after a page break
|
|
542
582
|
this.drawHorizontalLine(rowIndex, writer);
|
|
543
583
|
}
|
|
544
584
|
};
|
package/src/TextBreaker.js
CHANGED
|
@@ -1,19 +1,38 @@
|
|
|
1
|
-
import LineBreaker from '
|
|
1
|
+
import LineBreaker from 'linebreak';
|
|
2
2
|
import { isObject } from './helpers/variableType';
|
|
3
3
|
import StyleContextStack from './StyleContextStack';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @param {string} text
|
|
7
7
|
* @param {boolean} noWrap
|
|
8
|
+
* @param {boolean} breakAll
|
|
8
9
|
* @returns {Array}
|
|
9
10
|
*/
|
|
10
|
-
const splitWords = (text, noWrap) => {
|
|
11
|
+
const splitWords = (text, noWrap, breakAll = false) => {
|
|
11
12
|
let words = [];
|
|
13
|
+
if (text === undefined || text === null) {
|
|
14
|
+
text = '';
|
|
15
|
+
} else {
|
|
16
|
+
text = String(text);
|
|
17
|
+
}
|
|
12
18
|
|
|
13
19
|
if (noWrap) {
|
|
14
20
|
words.push({ text: text });
|
|
15
21
|
return words;
|
|
16
22
|
}
|
|
23
|
+
if (breakAll) {
|
|
24
|
+
return text.split('').map(c => {
|
|
25
|
+
if(c.match(/^\n$|^\r$/)) { // new line
|
|
26
|
+
return { text: '', lineEnd: true };
|
|
27
|
+
}
|
|
28
|
+
return { text: c };
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (text.length === 0) {
|
|
33
|
+
words.push({ text: '' });
|
|
34
|
+
return words;
|
|
35
|
+
}
|
|
17
36
|
|
|
18
37
|
let breaker = new LineBreaker(text);
|
|
19
38
|
let last = 0;
|
|
@@ -101,16 +120,16 @@ class TextBreaker {
|
|
|
101
120
|
let item = texts[i];
|
|
102
121
|
let style = null;
|
|
103
122
|
let words;
|
|
104
|
-
|
|
123
|
+
let breakAll = StyleContextStack.getStyleProperty(item || {}, styleContextStack, 'wordBreak', 'normal') === 'break-all';
|
|
105
124
|
let noWrap = StyleContextStack.getStyleProperty(item || {}, styleContextStack, 'noWrap', false);
|
|
106
125
|
if (isObject(item)) {
|
|
107
126
|
if (item._textRef && item._textRef._textNodeRef.text) {
|
|
108
127
|
item.text = item._textRef._textNodeRef.text;
|
|
109
128
|
}
|
|
110
|
-
words = splitWords(item.text, noWrap);
|
|
129
|
+
words = splitWords(item.text, noWrap, breakAll);
|
|
111
130
|
style = StyleContextStack.copyStyle(item);
|
|
112
131
|
} else {
|
|
113
|
-
words = splitWords(item, noWrap);
|
|
132
|
+
words = splitWords(item, noWrap, breakAll);
|
|
114
133
|
}
|
|
115
134
|
|
|
116
135
|
if (lastWord && words.length) {
|
package/src/TextInlines.js
CHANGED
|
@@ -45,7 +45,7 @@ class TextInlines {
|
|
|
45
45
|
* Converts an array of strings (or inline-definition-objects) into a collection
|
|
46
46
|
* of inlines and calculated minWidth/maxWidth and their min/max widths
|
|
47
47
|
*
|
|
48
|
-
* @param {Array} textArray an array of inline-definition-objects (or strings)
|
|
48
|
+
* @param {Array|object} textArray an array of inline-definition-objects (or strings)
|
|
49
49
|
* @param {StyleContextStack} styleContextStack current style stack
|
|
50
50
|
* @returns {object} collection of inlines, minWidth, maxWidth
|
|
51
51
|
*/
|
package/src/URLResolver.js
CHANGED
|
@@ -1,35 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
h.get(url, options, res => {
|
|
13
|
-
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { // redirect url
|
|
14
|
-
fetchUrl(res.headers.location).then(buffer => {
|
|
15
|
-
resolve(buffer);
|
|
16
|
-
}, result => {
|
|
17
|
-
reject(result);
|
|
18
|
-
});
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const ok = res.statusCode >= 200 && res.statusCode < 300;
|
|
23
|
-
if (!ok) {
|
|
24
|
-
reject(new TypeError(`Failed to fetch (status code: ${res.statusCode}, url: "${url}")`));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const chunks = [];
|
|
28
|
-
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
29
|
-
res.on('data', d => chunks.push(d));
|
|
30
|
-
}).on('error', reject);
|
|
31
|
-
});
|
|
32
|
-
};
|
|
1
|
+
async function fetchUrl(url, headers = {}) {
|
|
2
|
+
try {
|
|
3
|
+
const response = await fetch(url, { headers });
|
|
4
|
+
if (!response.ok) {
|
|
5
|
+
throw new Error(`Failed to fetch (status code: ${response.status}, url: "${url}")`);
|
|
6
|
+
}
|
|
7
|
+
return await response.arrayBuffer();
|
|
8
|
+
} catch (error) {
|
|
9
|
+
throw new Error(`Network request failed (url: "${url}", error: ${error.message})`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
33
12
|
|
|
34
13
|
class URLResolver {
|
|
35
14
|
constructor(fs) {
|
|
@@ -38,38 +17,25 @@ class URLResolver {
|
|
|
38
17
|
}
|
|
39
18
|
|
|
40
19
|
resolve(url, headers = {}) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
// url was downloaded earlier
|
|
46
|
-
resolve();
|
|
47
|
-
} else {
|
|
48
|
-
fetchUrl(url, headers).then(buffer => {
|
|
49
|
-
this.fs.writeFileSync(url, buffer);
|
|
50
|
-
resolve();
|
|
51
|
-
}, result => {
|
|
52
|
-
reject(result);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
} else {
|
|
56
|
-
// cannot be resolved
|
|
57
|
-
resolve();
|
|
20
|
+
const resolveUrlInternal = async () => {
|
|
21
|
+
if (url.toLowerCase().startsWith('https://') || url.toLowerCase().startsWith('http://')) {
|
|
22
|
+
if (this.fs.existsSync(url)) {
|
|
23
|
+
return; // url was downloaded earlier
|
|
58
24
|
}
|
|
59
|
-
|
|
60
|
-
|
|
25
|
+
const buffer = await fetchUrl(url, headers);
|
|
26
|
+
this.fs.writeFileSync(url, buffer);
|
|
27
|
+
}
|
|
28
|
+
// else cannot be resolved
|
|
29
|
+
};
|
|
61
30
|
|
|
31
|
+
if (!this.resolving[url]) {
|
|
32
|
+
this.resolving[url] = resolveUrlInternal();
|
|
33
|
+
}
|
|
62
34
|
return this.resolving[url];
|
|
63
35
|
}
|
|
64
36
|
|
|
65
37
|
resolved() {
|
|
66
|
-
return
|
|
67
|
-
Promise.all(Object.values(this.resolving)).then(() => {
|
|
68
|
-
resolve();
|
|
69
|
-
}, result => {
|
|
70
|
-
reject(result);
|
|
71
|
-
});
|
|
72
|
-
});
|
|
38
|
+
return Promise.all(Object.values(this.resolving));
|
|
73
39
|
}
|
|
74
40
|
|
|
75
41
|
}
|
package/src/base.js
CHANGED
|
@@ -18,7 +18,7 @@ class pdfmake {
|
|
|
18
18
|
options.progressCallback = this.progressCallback;
|
|
19
19
|
options.tableLayouts = this.tableLayouts;
|
|
20
20
|
|
|
21
|
-
let printer = new Printer(this.fonts, this.virtualfs, this.urlResolver);
|
|
21
|
+
let printer = new Printer(this.fonts, this.virtualfs, this.urlResolver());
|
|
22
22
|
const pdfDocumentPromise = printer.createPdfKitDocument(docDefinition, options);
|
|
23
23
|
|
|
24
24
|
return this._transformToDocument(pdfDocumentPromise);
|
|
@@ -20,98 +20,60 @@ class OutputDocumentBrowser extends OutputDocument {
|
|
|
20
20
|
/**
|
|
21
21
|
* @returns {Promise<Blob>}
|
|
22
22
|
*/
|
|
23
|
-
getBlob() {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
let blob = new Blob([buffer], { type: 'application/pdf' });
|
|
28
|
-
resolve(blob);
|
|
29
|
-
} catch (e) {
|
|
30
|
-
reject(e);
|
|
31
|
-
}
|
|
32
|
-
}, result => {
|
|
33
|
-
reject(result);
|
|
34
|
-
});
|
|
35
|
-
});
|
|
23
|
+
async getBlob() {
|
|
24
|
+
const buffer = await this.getBuffer();
|
|
25
|
+
return new Blob([buffer], { type: 'application/pdf' });
|
|
36
26
|
}
|
|
37
27
|
|
|
38
28
|
/**
|
|
39
29
|
* @param {string} filename
|
|
40
30
|
* @returns {Promise}
|
|
41
31
|
*/
|
|
42
|
-
download(filename = 'file.pdf') {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
saveAs(blob, filename);
|
|
47
|
-
resolve();
|
|
48
|
-
} catch (e) {
|
|
49
|
-
reject(e);
|
|
50
|
-
}
|
|
51
|
-
}, result => {
|
|
52
|
-
reject(result);
|
|
53
|
-
});
|
|
54
|
-
});
|
|
32
|
+
async download(filename = 'file.pdf') {
|
|
33
|
+
const blob = await this.getBlob();
|
|
34
|
+
saveAs(blob, filename);
|
|
55
35
|
}
|
|
56
36
|
|
|
57
37
|
/**
|
|
58
38
|
* @param {Window} win
|
|
59
39
|
* @returns {Promise}
|
|
60
40
|
*/
|
|
61
|
-
open(win = null) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
win.location.href = pdfUrl;
|
|
41
|
+
async open(win = null) {
|
|
42
|
+
if (!win) {
|
|
43
|
+
win = openWindow();
|
|
44
|
+
}
|
|
45
|
+
const blob = await this.getBlob();
|
|
46
|
+
try {
|
|
47
|
+
let urlCreator = window.URL || window.webkitURL;
|
|
48
|
+
let pdfUrl = urlCreator.createObjectURL(blob);
|
|
49
|
+
win.location.href = pdfUrl;
|
|
71
50
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (win.window === null) { // is closed by AdBlock
|
|
80
|
-
window.location.href = pdfUrl; // open in actual window
|
|
81
|
-
}
|
|
82
|
-
resolve();
|
|
83
|
-
}, 500);
|
|
51
|
+
/* temporarily disabled
|
|
52
|
+
if (win === window) {
|
|
53
|
+
return;
|
|
54
|
+
} else {
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
if (win.window === null) { // is closed by AdBlock
|
|
57
|
+
window.location.href = pdfUrl; // open in actual window
|
|
84
58
|
}
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
});
|
|
93
|
-
});
|
|
59
|
+
return;
|
|
60
|
+
}, 500);
|
|
61
|
+
}
|
|
62
|
+
*/
|
|
63
|
+
} finally {
|
|
64
|
+
win.close();
|
|
65
|
+
}
|
|
94
66
|
}
|
|
95
67
|
|
|
96
68
|
/**
|
|
97
69
|
* @param {Window} win
|
|
98
70
|
* @returns {Promise}
|
|
99
71
|
*/
|
|
100
|
-
print(win = null) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return this.open(win).then(() => {
|
|
105
|
-
resolve();
|
|
106
|
-
}, result => {
|
|
107
|
-
reject(result);
|
|
108
|
-
});
|
|
109
|
-
}, result => {
|
|
110
|
-
reject(result);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
72
|
+
async print(win = null) {
|
|
73
|
+
const stream = await this.getStream();
|
|
74
|
+
stream.setOpenActionAsPrint();
|
|
75
|
+
await this.open(win);
|
|
113
76
|
}
|
|
114
|
-
|
|
115
77
|
}
|
|
116
78
|
|
|
117
79
|
export default OutputDocumentBrowser;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import pdfmakeBase from '../base';
|
|
2
2
|
import OutputDocumentBrowser from './OutputDocumentBrowser';
|
|
3
|
-
import
|
|
3
|
+
import URLResolver from '../URLResolver';
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import configurator from 'core-js/configurator';
|
|
6
6
|
|
|
7
7
|
// core-js: Polyfills will be used only if natives completely unavailable.
|
|
8
8
|
configurator({
|
|
9
|
-
|
|
9
|
+
useNative: ['Promise']
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
let defaultClientFonts = {
|
|
@@ -21,7 +21,7 @@ let defaultClientFonts = {
|
|
|
21
21
|
class pdfmake extends pdfmakeBase {
|
|
22
22
|
constructor() {
|
|
23
23
|
super();
|
|
24
|
-
this.urlResolver = new
|
|
24
|
+
this.urlResolver = () => new URLResolver(this.virtualfs);
|
|
25
25
|
this.fonts = defaultClientFonts;
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -1,15 +1 @@
|
|
|
1
|
-
const isBrowserSupported = () => {
|
|
2
|
-
if ((typeof window === 'undefined') || (typeof window.navigator === 'undefined')) {
|
|
3
|
-
// Enviroment is not browser.
|
|
4
|
-
return true;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
// Internet Explorer 10 and older is not supported.
|
|
8
|
-
return window.navigator.userAgent.indexOf("MSIE") === -1;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
if (!isBrowserSupported()) {
|
|
12
|
-
throw new Error('pdfmake: Internet Explorer 10 and older is not supported. Upgrade to version 11 or use modern browser.');
|
|
13
|
-
}
|
|
14
|
-
|
|
15
1
|
module.exports = require('./index').default;
|
|
@@ -2,10 +2,10 @@ var fs = require('fs');
|
|
|
2
2
|
|
|
3
3
|
var fontContainer = {
|
|
4
4
|
vfs: {
|
|
5
|
-
'data/Courier.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
6
|
-
'data/Courier-Bold.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
7
|
-
'data/Courier-Oblique.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
8
|
-
'data/Courier-BoldOblique.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
5
|
+
'data/Courier.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Courier.afm', 'utf8'), encoding: 'utf8' },
|
|
6
|
+
'data/Courier-Bold.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Courier-Bold.afm', 'utf8'), encoding: 'utf8' },
|
|
7
|
+
'data/Courier-Oblique.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Courier-Oblique.afm', 'utf8'), encoding: 'utf8' },
|
|
8
|
+
'data/Courier-BoldOblique.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Courier-BoldOblique.afm', 'utf8'), encoding: 'utf8' }
|
|
9
9
|
},
|
|
10
10
|
fonts: {
|
|
11
11
|
Courier: {
|
|
@@ -2,10 +2,10 @@ var fs = require('fs');
|
|
|
2
2
|
|
|
3
3
|
var fontContainer = {
|
|
4
4
|
vfs: {
|
|
5
|
-
'data/Helvetica.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
6
|
-
'data/Helvetica-Bold.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
7
|
-
'data/Helvetica-Oblique.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
8
|
-
'data/Helvetica-BoldOblique.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
5
|
+
'data/Helvetica.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Helvetica.afm', 'utf8'), encoding: 'utf8' },
|
|
6
|
+
'data/Helvetica-Bold.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Helvetica-Bold.afm', 'utf8'), encoding: 'utf8' },
|
|
7
|
+
'data/Helvetica-Oblique.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Helvetica-Oblique.afm', 'utf8'), encoding: 'utf8' },
|
|
8
|
+
'data/Helvetica-BoldOblique.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Helvetica-BoldOblique.afm', 'utf8'), encoding: 'utf8' }
|
|
9
9
|
},
|
|
10
10
|
fonts: {
|
|
11
11
|
Helvetica: {
|
|
@@ -2,7 +2,7 @@ var fs = require('fs');
|
|
|
2
2
|
|
|
3
3
|
var fontContainer = {
|
|
4
4
|
vfs: {
|
|
5
|
-
'data/Symbol.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
5
|
+
'data/Symbol.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Symbol.afm', 'utf8'), encoding: 'utf8' }
|
|
6
6
|
},
|
|
7
7
|
fonts: {
|
|
8
8
|
Symbol: {
|
|
@@ -2,10 +2,10 @@ var fs = require('fs');
|
|
|
2
2
|
|
|
3
3
|
var fontContainer = {
|
|
4
4
|
vfs: {
|
|
5
|
-
'data/Times-Roman.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
6
|
-
'data/Times-Bold.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
7
|
-
'data/Times-Italic.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
8
|
-
'data/Times-BoldItalic.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
5
|
+
'data/Times-Roman.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Times-Roman.afm', 'utf8'), encoding: 'utf8' },
|
|
6
|
+
'data/Times-Bold.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Times-Bold.afm', 'utf8'), encoding: 'utf8' },
|
|
7
|
+
'data/Times-Italic.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Times-Italic.afm', 'utf8'), encoding: 'utf8' },
|
|
8
|
+
'data/Times-BoldItalic.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/Times-BoldItalic.afm', 'utf8'), encoding: 'utf8' }
|
|
9
9
|
},
|
|
10
10
|
fonts: {
|
|
11
11
|
Times: {
|
|
@@ -2,7 +2,7 @@ var fs = require('fs');
|
|
|
2
2
|
|
|
3
3
|
var fontContainer = {
|
|
4
4
|
vfs: {
|
|
5
|
-
'data/ZapfDingbats.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules
|
|
5
|
+
'data/ZapfDingbats.afm': { data: fs.readFileSync(__dirname + '/../../../node_modules/pdfkit/js/data/ZapfDingbats.afm', 'utf8'), encoding: 'utf8' }
|
|
6
6
|
},
|
|
7
7
|
fonts: {
|
|
8
8
|
ZapfDingbats: {
|
package/src/columnCalculator.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isString } from './helpers/variableType';
|
|
2
2
|
|
|
3
|
-
function buildColumnWidths(columns, availableWidth) {
|
|
3
|
+
function buildColumnWidths(columns, availableWidth, offsetTotal = 0, tableNode) {
|
|
4
4
|
let autoColumns = [];
|
|
5
5
|
let autoMin = 0;
|
|
6
6
|
let autoMax = 0;
|
|
@@ -24,10 +24,31 @@ function buildColumnWidths(columns, availableWidth) {
|
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
fixedColumns.forEach(col => {
|
|
27
|
+
fixedColumns.forEach((col, colIndex) => {
|
|
28
28
|
// width specified as %
|
|
29
29
|
if (isString(col.width) && /\d+%/.test(col.width)) {
|
|
30
|
-
|
|
30
|
+
// In tables we have to take into consideration the reserved width for paddings and borders
|
|
31
|
+
let reservedWidth = 0;
|
|
32
|
+
if (tableNode) {
|
|
33
|
+
const paddingLeft = tableNode._layout.paddingLeft(colIndex, tableNode);
|
|
34
|
+
const paddingRight = tableNode._layout.paddingRight(colIndex, tableNode);
|
|
35
|
+
const borderLeft = tableNode._layout.vLineWidth(colIndex, tableNode);
|
|
36
|
+
const borderRight = tableNode._layout.vLineWidth(colIndex + 1, tableNode);
|
|
37
|
+
if (colIndex === 0) {
|
|
38
|
+
// first column assumes whole borderLeft and half of border right
|
|
39
|
+
reservedWidth = paddingLeft + paddingRight + borderLeft + (borderRight / 2);
|
|
40
|
+
|
|
41
|
+
} else if (colIndex === fixedColumns.length - 1) {
|
|
42
|
+
// last column assumes whole borderRight and half of border left
|
|
43
|
+
reservedWidth = paddingLeft + paddingRight + (borderLeft / 2) + borderRight;
|
|
44
|
+
|
|
45
|
+
} else {
|
|
46
|
+
// Columns in the middle assume half of each border
|
|
47
|
+
reservedWidth = paddingLeft + paddingRight + (borderLeft / 2) + (borderRight / 2);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const totalAvailableWidth = initial_availableWidth + offsetTotal;
|
|
51
|
+
col.width = (parseFloat(col.width) * totalAvailableWidth / 100) - reservedWidth;
|
|
31
52
|
}
|
|
32
53
|
if (col.width < (col._minWidth) && col.elasticWidth) {
|
|
33
54
|
col._calcWidth = col._minWidth;
|
package/src/helpers/tools.js
CHANGED
|
@@ -14,6 +14,17 @@ export function isNumber(variable) {
|
|
|
14
14
|
return (typeof variable === 'number') || (variable instanceof Number);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* @param {any} variable
|
|
19
|
+
* @returns {boolean}
|
|
20
|
+
*/
|
|
21
|
+
export function isPositiveInteger(variable) {
|
|
22
|
+
if (!isNumber(variable) || !Number.isInteger(variable) || variable <= 0) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
|
|
17
28
|
/**
|
|
18
29
|
* @param {any} variable
|
|
19
30
|
* @returns {boolean}
|