@ind-rcg/plugins-printengine 260.1004.0 → 262.1003.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev/printEngine.js +2446 -215
- package/dist/dev/src/fs-shim.js +58 -0
- package/dist/dev/src/pdfConverterClass.js +111 -52
- package/dist/prod/printEngine.js +1 -1
- package/dist/prod/printEngine.js.LICENSE.txt +13 -14
- package/package.json +16 -11
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* FILE_HEADER
|
|
3
|
+
*/
|
|
4
|
+
'use strict';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module fs-shim
|
|
8
|
+
* Browser filesystem shim for pdfmake font loading
|
|
9
|
+
*
|
|
10
|
+
* **Source**: Custom implementation for pdfmake 0.3.x compatibility (not third-party)
|
|
11
|
+
*
|
|
12
|
+
* This module provides a minimal fs-like API that bridges pdfkit's filesystem
|
|
13
|
+
* dependencies with pdfmake's virtual filesystem. Required because pdfkit attempts
|
|
14
|
+
* to use fs.readFileSync for font loading, which is not available in browsers.
|
|
15
|
+
*
|
|
16
|
+
* The virtual filesystem is populated with font data from pdfmake's vfs_fonts.js
|
|
17
|
+
* on module initialization.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const virtualFs = require('pdfmake/js/virtual-fs.js').default;
|
|
21
|
+
const BrowserFontsVfs = require('pdfmake/build/vfs_fonts.js');
|
|
22
|
+
const LogClass = require('./logClass');
|
|
23
|
+
const __log = new LogClass();
|
|
24
|
+
|
|
25
|
+
// Load font data into virtual file system on module load
|
|
26
|
+
// BrowserFontsVfs has fonts directly as properties, not under .vfs
|
|
27
|
+
if (BrowserFontsVfs) {
|
|
28
|
+
for (let key in BrowserFontsVfs) {
|
|
29
|
+
if (Object.prototype.hasOwnProperty.call(BrowserFontsVfs, key)) {
|
|
30
|
+
try {
|
|
31
|
+
let data;
|
|
32
|
+
let encoding;
|
|
33
|
+
if (typeof BrowserFontsVfs[key] === 'object') {
|
|
34
|
+
data = BrowserFontsVfs[key].data;
|
|
35
|
+
encoding = BrowserFontsVfs[key].encoding || 'base64';
|
|
36
|
+
} else {
|
|
37
|
+
data = BrowserFontsVfs[key];
|
|
38
|
+
encoding = 'base64';
|
|
39
|
+
}
|
|
40
|
+
virtualFs.writeFileSync(key, data, encoding);
|
|
41
|
+
} catch (e) {
|
|
42
|
+
__log.error('Failed to load font into virtual filesystem:', key, e);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = {
|
|
49
|
+
readFileSync: function(filename, options) {
|
|
50
|
+
return virtualFs.readFileSync(filename, options);
|
|
51
|
+
},
|
|
52
|
+
existsSync: function(filename) {
|
|
53
|
+
return virtualFs.existsSync(filename);
|
|
54
|
+
},
|
|
55
|
+
writeFileSync: function(filename, content, options) {
|
|
56
|
+
return virtualFs.writeFileSync(filename, content, options);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
6
|
const _ = require('lodash');
|
|
7
|
-
const PdfPrinter = require('pdfmake');
|
|
7
|
+
const PdfPrinter = require('pdfmake/js/Printer').default;
|
|
8
8
|
const Format = require('./formatClass');
|
|
9
9
|
const TableCellIdentifier = require('./tableCellIdentifier');
|
|
10
10
|
|
|
11
11
|
// required for webpack include (browser impl), used in conjunction with BrowserFonts definition
|
|
12
|
-
|
|
12
|
+
// BrowserFontsVfs now loaded by fs-shim.js to avoid circular dependency and integrate with virtual filesystem
|
|
13
|
+
// const BrowserFontsVfs = require('pdfmake/build/vfs_fonts.js');
|
|
13
14
|
const classLog = require("./logClass");
|
|
14
15
|
|
|
15
16
|
// => use 'Roboto' font (pdfMake default) due to licensing (Apache 2.0)
|
|
@@ -38,6 +39,12 @@ const BrowserFonts = {
|
|
|
38
39
|
}
|
|
39
40
|
};
|
|
40
41
|
|
|
42
|
+
// pdfmake browser components for PDF generation
|
|
43
|
+
const PdfMakeBase = require('pdfmake/js/base.js').default;
|
|
44
|
+
const OutputDocumentBrowser = require('pdfmake/js/browser-extensions/OutputDocumentBrowser.js').default;
|
|
45
|
+
const URLResolver = require('pdfmake/js/URLResolver.js').default;
|
|
46
|
+
const virtualFs = require('pdfmake/js/virtual-fs.js').default;
|
|
47
|
+
|
|
41
48
|
const TableLayouts = {
|
|
42
49
|
lightHorizontalLinesMainItemsOnly: {
|
|
43
50
|
hLineWidth: function (i, node) {
|
|
@@ -100,10 +107,33 @@ Object.freeze(EXPORT_TYPE);
|
|
|
100
107
|
class PdfConverter {
|
|
101
108
|
constructor() {
|
|
102
109
|
this.__pdfMake = null;
|
|
103
|
-
|
|
110
|
+
|
|
111
|
+
// First try to use global pdfMake (for tests or when pdfmake is loaded separately)
|
|
112
|
+
if(typeof global !== "undefined" && global.pdfMake)
|
|
113
|
+
{
|
|
114
|
+
this.__pdfMake = global.pdfMake;
|
|
115
|
+
}
|
|
116
|
+
else if(typeof pdfMake !== "undefined")
|
|
104
117
|
{
|
|
105
118
|
this.__pdfMake = pdfMake;
|
|
106
119
|
}
|
|
120
|
+
// Fall back to creating browser pdfmake instance (for webpack bundled builds)
|
|
121
|
+
else if (PdfMakeBase && OutputDocumentBrowser && URLResolver) {
|
|
122
|
+
// Create browser-specific pdfmake instance
|
|
123
|
+
class BrowserPdfMake extends PdfMakeBase {
|
|
124
|
+
constructor() {
|
|
125
|
+
super();
|
|
126
|
+
this.urlResolver = () => new URLResolver(this.virtualfs);
|
|
127
|
+
this.fonts = BrowserFonts;
|
|
128
|
+
this.tableLayouts = TableLayouts;
|
|
129
|
+
// Note: Font data is loaded into virtualfs by fs-shim.js
|
|
130
|
+
}
|
|
131
|
+
_transformToDocument(doc) {
|
|
132
|
+
return new OutputDocumentBrowser(doc);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
this.__pdfMake = new BrowserPdfMake();
|
|
136
|
+
}
|
|
107
137
|
|
|
108
138
|
this.__format = new Format();
|
|
109
139
|
this.__pdfHeight = null;
|
|
@@ -1006,8 +1036,15 @@ class PdfConverter {
|
|
|
1006
1036
|
return doPageBreak;
|
|
1007
1037
|
}
|
|
1008
1038
|
|
|
1009
|
-
__calculatePageBreakBefore(currentNode,
|
|
1039
|
+
__calculatePageBreakBefore(currentNode, nodeGetters) {
|
|
1010
1040
|
let doPageBreak = false;
|
|
1041
|
+
|
|
1042
|
+
// pdfmake 0.3.x API: nodeGetters contains getter functions - validate availability
|
|
1043
|
+
if (!nodeGetters || typeof nodeGetters.getNodesOnNextPage !== 'function') {
|
|
1044
|
+
return false;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
const nodesOnNextPage = nodeGetters.getNodesOnNextPage();
|
|
1011
1048
|
|
|
1012
1049
|
// looking for potential pageBreaks only makes sense if there are elements to be placed there (=> might require adaption for subtotals)
|
|
1013
1050
|
if (!_.isNil(nodesOnNextPage) && _.isArray(nodesOnNextPage) && nodesOnNextPage.length > 0) {
|
|
@@ -1016,6 +1053,10 @@ class PdfConverter {
|
|
|
1016
1053
|
let tcidCurrentNode = TableCellIdentifier.fromString(currentNode.id);
|
|
1017
1054
|
if (!_.isNil(tcidCurrentNode) && tcidCurrentNode.isKnown()) {
|
|
1018
1055
|
|
|
1056
|
+
// pdfmake 0.3.x: get the node arrays via getter functions
|
|
1057
|
+
const followingNodesOnPage = nodeGetters.getFollowingNodesOnPage();
|
|
1058
|
+
const previousNodesOnPage = nodeGetters.getPreviousNodesOnPage();
|
|
1059
|
+
|
|
1019
1060
|
// check for dynamic pageBreak of parent-child rows
|
|
1020
1061
|
doPageBreak = this.__calculatePageBreakForParentChildRows(currentNode, followingNodesOnPage, nodesOnNextPage, previousNodesOnPage, tcidCurrentNode);
|
|
1021
1062
|
if (!doPageBreak) {
|
|
@@ -1038,7 +1079,7 @@ class PdfConverter {
|
|
|
1038
1079
|
return doPageBreak;
|
|
1039
1080
|
}
|
|
1040
1081
|
|
|
1041
|
-
__createPdfDocument(pdfDefinition, pdfCreationFunction) {
|
|
1082
|
+
async __createPdfDocument(pdfDefinition, pdfCreationFunction) {
|
|
1042
1083
|
// clone pdf definition if applicable ...
|
|
1043
1084
|
let pdfDefinitionCopy = null;
|
|
1044
1085
|
if (!_.isNil(pdfDefinition) && !_.isUndefined(pdfDefinition.dynamicPageBreak) && pdfDefinition.dynamicPageBreak &&
|
|
@@ -1072,12 +1113,12 @@ class PdfConverter {
|
|
|
1072
1113
|
this.__definition = pdfDefinition;
|
|
1073
1114
|
|
|
1074
1115
|
// exec pdfCreation function ...
|
|
1075
|
-
pdfCreationFunction.apply(this, [pdfDefinition]);
|
|
1116
|
+
await pdfCreationFunction.apply(this, [pdfDefinition]);
|
|
1076
1117
|
|
|
1077
1118
|
return pdfDefinitionCopy;
|
|
1078
1119
|
}
|
|
1079
1120
|
|
|
1080
|
-
__createFinalPdfDocument(pdfDefinition, pdfDefinitionCopy, pdfCreationFunction) {
|
|
1121
|
+
async __createFinalPdfDocument(pdfDefinition, pdfDefinitionCopy, pdfCreationFunction) {
|
|
1081
1122
|
// perform pageBreak magic ...
|
|
1082
1123
|
if (!_.isNil(pdfDefinition) && !_.isUndefined(pdfDefinition.dynamicPageBreak) && pdfDefinition.dynamicPageBreak &&
|
|
1083
1124
|
!_.isUndefined(pdfDefinition.dynamicPageBreakData) && _.isArray(pdfDefinition.dynamicPageBreakData) &&
|
|
@@ -1093,7 +1134,7 @@ class PdfConverter {
|
|
|
1093
1134
|
this.__definition = pdfDefinitionCopy;
|
|
1094
1135
|
|
|
1095
1136
|
// exec pdfCreation function ...
|
|
1096
|
-
pdfCreationFunction.apply(this, [pdfDefinitionCopy]);
|
|
1137
|
+
await pdfCreationFunction.apply(this, [pdfDefinitionCopy]);
|
|
1097
1138
|
}
|
|
1098
1139
|
}
|
|
1099
1140
|
|
|
@@ -1111,22 +1152,22 @@ class PdfConverter {
|
|
|
1111
1152
|
return this.__definition;
|
|
1112
1153
|
}
|
|
1113
1154
|
|
|
1114
|
-
writeToStream(pdfDefinition, stream) {
|
|
1155
|
+
async writeToStream(pdfDefinition, stream) {
|
|
1115
1156
|
// setup pdf creator ...
|
|
1116
1157
|
let printer = new PdfPrinter(ServerFonts);
|
|
1117
1158
|
let pdfDoc = null;
|
|
1118
|
-
let pdfCreatorFunction = (definition) => {
|
|
1159
|
+
let pdfCreatorFunction = async (definition) => {
|
|
1119
1160
|
printer = new PdfPrinter(ServerFonts);
|
|
1120
|
-
pdfDoc = printer.createPdfKitDocument(definition, {
|
|
1161
|
+
pdfDoc = await printer.createPdfKitDocument(definition, {
|
|
1121
1162
|
tableLayouts: TableLayouts
|
|
1122
1163
|
});
|
|
1123
1164
|
};
|
|
1124
1165
|
|
|
1125
1166
|
// create pdf and prepare for recreation if applicable ...
|
|
1126
|
-
let pdfDefinitionCopy = this.__createPdfDocument(pdfDefinition, pdfCreatorFunction);
|
|
1167
|
+
let pdfDefinitionCopy = await this.__createPdfDocument(pdfDefinition, pdfCreatorFunction);
|
|
1127
1168
|
|
|
1128
1169
|
// recreate pdf if applicable ...
|
|
1129
|
-
this.__createFinalPdfDocument(pdfDefinition, pdfDefinitionCopy, pdfCreatorFunction);
|
|
1170
|
+
await this.__createFinalPdfDocument(pdfDefinition, pdfDefinitionCopy, pdfCreatorFunction);
|
|
1130
1171
|
|
|
1131
1172
|
pdfDoc.pipe(stream);
|
|
1132
1173
|
pdfDoc.end();
|
|
@@ -1199,48 +1240,66 @@ class PdfConverter {
|
|
|
1199
1240
|
});
|
|
1200
1241
|
}
|
|
1201
1242
|
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
break;
|
|
1222
|
-
|
|
1223
|
-
case EXPORT_TYPE.BLOB:
|
|
1224
|
-
pdfDocGenerator.getBlob((blob) => {
|
|
1225
|
-
resolve(blob);
|
|
1226
|
-
});
|
|
1227
|
-
break;
|
|
1228
|
-
|
|
1229
|
-
case EXPORT_TYPE.DATA_URL:
|
|
1230
|
-
pdfDocGenerator.getDataUrl((dataUrl) => {
|
|
1231
|
-
resolve(dataUrl);
|
|
1232
|
-
});
|
|
1233
|
-
break;
|
|
1234
|
-
|
|
1235
|
-
default:
|
|
1236
|
-
throw new Error('Unknown export type: ' + type );
|
|
1237
|
-
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Load custom printFont data into pdfmake's virtual file system.
|
|
1245
|
+
* Required for pdfmake 0.3.x where fonts must be in VFS before use.
|
|
1246
|
+
*
|
|
1247
|
+
* @param {Object} printFont - Object with Regular, Bold, Italic, BoldItalic keys containing base64 font data
|
|
1248
|
+
*/
|
|
1249
|
+
__loadCustomFontsToVfs(printFont) {
|
|
1250
|
+
if (!_.isObject(printFont)) {
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
const fontKeys = ['Regular', 'Bold', 'Italic', 'BoldItalic'];
|
|
1255
|
+
for (const key of fontKeys) {
|
|
1256
|
+
if (key in printFont && printFont[key]) {
|
|
1257
|
+
try {
|
|
1258
|
+
// Font data is already base64 encoded
|
|
1259
|
+
virtualFs.writeFileSync(key, printFont[key], 'base64');
|
|
1260
|
+
} catch (e) {
|
|
1261
|
+
__log.error('Failed to load custom font into virtual filesystem:', key, e);
|
|
1238
1262
|
}
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1239
1266
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1267
|
+
async __getPdfDataAsync(type, pdfDefinition, previousResult = null) {
|
|
1268
|
+
if (_.isNil(pdfDefinition) && !_.isNil(previousResult)) {
|
|
1269
|
+
return previousResult;
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
try {
|
|
1273
|
+
// Load custom fonts into VFS if present (required for pdfmake 0.3.x)
|
|
1274
|
+
if (pdfDefinition.printFont) {
|
|
1275
|
+
this.__loadCustomFontsToVfs(pdfDefinition.printFont);
|
|
1242
1276
|
}
|
|
1243
|
-
|
|
1277
|
+
|
|
1278
|
+
// pdfmake 0.3.x API: createPdf(docDefinition, options)
|
|
1279
|
+
// fonts and tableLayouts are set on the pdfmake instance - validate initialization
|
|
1280
|
+
if (!this.__pdfMake || typeof this.__pdfMake.createPdf !== 'function') {
|
|
1281
|
+
throw new Error('pdfMake instance not properly initialized');
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
let pdfDocGenerator = this.__pdfMake.createPdf(pdfDefinition, {});
|
|
1285
|
+
|
|
1286
|
+
// pdfmake 0.3.x returns Promises, not callbacks
|
|
1287
|
+
switch (type) {
|
|
1288
|
+
case EXPORT_TYPE.BASE_64: {
|
|
1289
|
+
return await pdfDocGenerator.getBase64();
|
|
1290
|
+
}
|
|
1291
|
+
case EXPORT_TYPE.BLOB: {
|
|
1292
|
+
return await pdfDocGenerator.getBlob();
|
|
1293
|
+
}
|
|
1294
|
+
case EXPORT_TYPE.DATA_URL: {
|
|
1295
|
+
return await pdfDocGenerator.getDataUrl();
|
|
1296
|
+
}
|
|
1297
|
+
default:
|
|
1298
|
+
throw new Error('Unknown export type: ' + type);
|
|
1299
|
+
}
|
|
1300
|
+
} catch (error) {
|
|
1301
|
+
throw new Error(`PDF ${type} export failed: ${error.message}`);
|
|
1302
|
+
}
|
|
1244
1303
|
}
|
|
1245
1304
|
|
|
1246
1305
|
async toBase64(pdfDefinition) {
|