p3x-html-pdf 2025.4.136 → 2025.4.148
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/README.md +5 -14
- package/package.json +1 -1
- package/src/index.js +1 -1
- package/src/package/install.js +77 -56
- package/test/test.js +13 -4
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
# 📃 Generates PDF from HTML with custom headers and footers with wkhtmltopdf v2025.4.
|
|
9
|
+
# 📃 Generates PDF from HTML with custom headers and footers with wkhtmltopdf v2025.4.148
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
@@ -196,16 +196,7 @@ The `p3x-footer` and `p3x-header` should not have any styles other than `id` and
|
|
|
196
196
|
|
|
197
197
|
### ARM64 Support
|
|
198
198
|
|
|
199
|
-
|
|
200
|
-
`/usr/local/bin/wkhtmltopdf-arm64`
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
To use this functionality, you must manually download the binary and place it in the specified location.
|
|
204
|
-
You can download the ARM64 binary from the link below:
|
|
205
|
-
|
|
206
|
-
[Download wkhtmltopdf-arm64 binary](https://github.com/houseoftech/wkhtmltopdf-arm64/raw/refs/heads/master/bin/wkhtmltopdf-arm64)
|
|
207
|
-
|
|
208
|
-
Currently, the ARM64 binary setup is manual. If there is sufficient demand, an automated installation process may be implemented in the future.
|
|
199
|
+
Full ARM64 support.
|
|
209
200
|
|
|
210
201
|
|
|
211
202
|
---
|
|
@@ -213,9 +204,9 @@ Currently, the ARM64 binary setup is manual. If there is sufficient demand, an a
|
|
|
213
204
|
## 🖼️ Example Output
|
|
214
205
|
|
|
215
206
|
Check out an example output PDF:
|
|
216
|
-
[Example PDF](https://cdn.corifeus.com/git/html-pdf/assets/p3x-html-pdf-
|
|
207
|
+
[Example PDF](https://cdn.corifeus.com/git/html-pdf/assets/p3x-html-pdf-output.pdf).
|
|
217
208
|
|
|
218
|
-

|
|
219
210
|
|
|
220
211
|
---
|
|
221
212
|
|
|
@@ -374,7 +365,7 @@ All my domains, including [patrikx3.com](https://patrikx3.com), [corifeus.eu](ht
|
|
|
374
365
|
---
|
|
375
366
|
|
|
376
367
|
|
|
377
|
-
[**P3X-HTML-PDF**](https://corifeus.com/html-pdf) Build v2025.4.
|
|
368
|
+
[**P3X-HTML-PDF**](https://corifeus.com/html-pdf) Build v2025.4.148
|
|
378
369
|
|
|
379
370
|
[](https://www.npmjs.com/package/p3x-html-pdf) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QZVM4V6HVZJW6) [](https://www.patrikx3.com/en/front/contact) [](https://www.facebook.com/corifeus.software)
|
|
380
371
|
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -14,7 +14,7 @@ const binPathAddon = isWin ? '' : 'wkhtmltox/';
|
|
|
14
14
|
let binpath = path.resolve(`${__dirname}/../release/${binPathAddon}bin/wkhtmltopdf`);
|
|
15
15
|
// if we are in arm64, change the binpath
|
|
16
16
|
if (os.arch() === 'arm64') {
|
|
17
|
-
binpath =
|
|
17
|
+
binpath = `${__dirname}/../release/wkhtmltopdf-arm64`
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const generate = async (options) => {
|
package/src/package/install.js
CHANGED
|
@@ -1,34 +1,31 @@
|
|
|
1
1
|
const utils = require('corifeus-utils');
|
|
2
|
-
|
|
3
2
|
const os = require('os');
|
|
4
3
|
const path = require('path');
|
|
5
4
|
const fsExtra = require('fs-extra');
|
|
6
|
-
// https://api.github.com/repos/wkhtmltopdf/wkhtmltopdf/tags
|
|
7
|
-
// https://api.github.com/repos/wkhtmltopdf/wkhtmltopdf/releases/latest
|
|
8
|
-
|
|
9
5
|
const progress = require('progress');
|
|
10
6
|
|
|
11
|
-
//
|
|
7
|
+
// GitHub API for wkhtmltopdf releases
|
|
12
8
|
const currentRelease = 'https://api.github.com/repos/wkhtmltopdf/wkhtmltopdf/releases/4730156';
|
|
13
9
|
|
|
10
|
+
// Install function
|
|
14
11
|
const install = async () => {
|
|
15
|
-
|
|
16
12
|
let staticInstaller;
|
|
17
|
-
|
|
18
13
|
const staticInstallerPath = `${process.cwd()}/package.json`;
|
|
19
14
|
|
|
20
|
-
staticInstaller = require(staticInstallerPath)
|
|
21
|
-
// console.log('staticInstaller 1', JSON.stringify(staticInstaller, null, 4 ))
|
|
15
|
+
staticInstaller = require(staticInstallerPath);
|
|
22
16
|
|
|
23
17
|
if (staticInstaller.hasOwnProperty('_where')) {
|
|
24
|
-
staticInstaller = require(`${staticInstaller._where}/package.json`)
|
|
18
|
+
staticInstaller = require(`${staticInstaller._where}/package.json`);
|
|
25
19
|
}
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
21
|
+
if (
|
|
22
|
+
typeof staticInstaller === 'object' &&
|
|
23
|
+
staticInstaller.hasOwnProperty('p3x') &&
|
|
24
|
+
staticInstaller.p3x.hasOwnProperty('installer') &&
|
|
25
|
+
staticInstaller.p3x.installer['p3x-html-pdf'].hasOwnProperty('linux-x64') &&
|
|
26
|
+
staticInstaller.p3x.installer['p3x-html-pdf'].hasOwnProperty('win32-x64')
|
|
27
|
+
) {
|
|
28
|
+
console.log('Found static download instead of GitHub as:', JSON.stringify(staticInstaller.p3x.installer['p3x-html-pdf'], null, 4));
|
|
32
29
|
} else {
|
|
33
30
|
staticInstaller = undefined;
|
|
34
31
|
}
|
|
@@ -37,55 +34,86 @@ const install = async () => {
|
|
|
37
34
|
await fsExtra.remove(binPath);
|
|
38
35
|
|
|
39
36
|
const arch = os.arch();
|
|
40
|
-
const platform = os.platform()
|
|
41
|
-
|
|
37
|
+
const platform = os.platform();
|
|
42
38
|
let platformSearch;
|
|
43
39
|
let archSearch;
|
|
40
|
+
|
|
44
41
|
if (platform === 'linux') {
|
|
45
42
|
platformSearch = 'linux';
|
|
46
43
|
if (arch === 'x64') {
|
|
47
44
|
archSearch = 'amd64';
|
|
45
|
+
} else if (arch === 'arm64') {
|
|
46
|
+
console.log('Detected arm64 architecture. Preparing to download arm64 binary.');
|
|
47
|
+
const releaseBinaryFileName = `${binPath}/wkhtmltopdf-arm64`;
|
|
48
|
+
|
|
49
|
+
await fsExtra.ensureDir(binPath);
|
|
50
|
+
|
|
51
|
+
const downloadResponse = await utils.http.request({
|
|
52
|
+
url: 'https://github.com/houseoftech/wkhtmltopdf-arm64/raw/refs/heads/master/bin/wkhtmltopdf-arm64',
|
|
53
|
+
pipe: true,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const releaseBinaryFile = utils.fs.createWriteStream(releaseBinaryFileName);
|
|
57
|
+
downloadResponse.pipe(releaseBinaryFile.stream);
|
|
58
|
+
|
|
59
|
+
const releaseSize = downloadResponse.headers['content-length'];
|
|
60
|
+
const bar = new progress('Downloading release [:bar] :rate/bps :percent :etas', {
|
|
61
|
+
complete: '=',
|
|
62
|
+
incomplete: ' ',
|
|
63
|
+
width: 20,
|
|
64
|
+
total: parseInt(releaseSize, 10),
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
downloadResponse.on('data', (chunk) => {
|
|
68
|
+
bar.tick(chunk.length);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
await releaseBinaryFile;
|
|
72
|
+
|
|
73
|
+
console.log('Setting executable permissions for arm64 binary.');
|
|
74
|
+
await utils.childProcess.exec(`chmod +x ${releaseBinaryFileName}`, true);
|
|
75
|
+
|
|
76
|
+
console.log('Installation for arm64 completed.');
|
|
77
|
+
return;
|
|
48
78
|
}
|
|
49
79
|
} else if (platform === 'win32' && arch === 'x64') {
|
|
50
|
-
// wkhtmltox-0.12.4_mingw-w64-cross-win64.exe
|
|
51
80
|
platformSearch = 'mingw-w64-cross';
|
|
52
81
|
archSearch = 'win64';
|
|
53
82
|
}
|
|
54
83
|
|
|
55
84
|
if (platformSearch === undefined || archSearch === undefined) {
|
|
56
85
|
console.log(`This platform for p3x-html-pdf is not implemented: ${platform}/${arch}`);
|
|
57
|
-
console.log('The p3x-html-pdf will not work, but will work silently');
|
|
58
|
-
return
|
|
86
|
+
console.log('The p3x-html-pdf will not work, but will work silently.');
|
|
87
|
+
return;
|
|
59
88
|
}
|
|
60
89
|
|
|
61
90
|
console.log(`Found platform: ${platformSearch} and architecture ${archSearch}`);
|
|
62
|
-
|
|
63
|
-
console.log(`Downloading latest release for wkhtmltopdf`);
|
|
91
|
+
console.log('Downloading latest release for wkhtmltopdf.');
|
|
64
92
|
|
|
65
93
|
await utils.fs.ensureDir(binPath);
|
|
66
94
|
|
|
67
|
-
let releaseBinaryFileName
|
|
68
|
-
let downloadResponse
|
|
69
|
-
let releaseBinaryFile
|
|
95
|
+
let releaseBinaryFileName;
|
|
96
|
+
let downloadResponse;
|
|
97
|
+
let releaseBinaryFile;
|
|
70
98
|
|
|
71
99
|
if (staticInstaller === undefined) {
|
|
72
100
|
const headers = {};
|
|
73
101
|
|
|
74
102
|
if (process.env.hasOwnProperty('GITHUB_TOKEN')) {
|
|
75
|
-
headers['Authorization'] = `token ${process.env.GITHUB_TOKEN}
|
|
76
|
-
console.log(
|
|
103
|
+
headers['Authorization'] = `token ${process.env.GITHUB_TOKEN}`;
|
|
104
|
+
console.log('Found GITHUB_TOKEN, using as GitHub authorization.');
|
|
77
105
|
}
|
|
78
106
|
|
|
79
|
-
const {body} = await utils.http.request({
|
|
107
|
+
const { body } = await utils.http.request({
|
|
80
108
|
url: currentRelease,
|
|
81
|
-
headers: headers
|
|
109
|
+
headers: headers,
|
|
82
110
|
});
|
|
83
|
-
const findReleaseAsset = body.assets.find((asset) =>
|
|
84
|
-
|
|
85
|
-
|
|
111
|
+
const findReleaseAsset = body.assets.find((asset) =>
|
|
112
|
+
asset.browser_download_url.includes(platformSearch) && asset.browser_download_url.includes(archSearch)
|
|
113
|
+
);
|
|
86
114
|
|
|
87
|
-
if (findReleaseAsset
|
|
88
|
-
throw new Error('Could not
|
|
115
|
+
if (!findReleaseAsset) {
|
|
116
|
+
throw new Error('Could not find the latest release for wkhtmltopdf.');
|
|
89
117
|
}
|
|
90
118
|
|
|
91
119
|
console.log(`Found the latest release: ${findReleaseAsset.browser_download_url}`);
|
|
@@ -94,22 +122,21 @@ const install = async () => {
|
|
|
94
122
|
downloadResponse = await utils.http.request({
|
|
95
123
|
url: findReleaseAsset.browser_download_url,
|
|
96
124
|
pipe: true,
|
|
97
|
-
})
|
|
125
|
+
});
|
|
98
126
|
|
|
99
127
|
releaseBinaryFile = utils.fs.createWriteStream(releaseBinaryFileName);
|
|
100
128
|
downloadResponse.pipe(releaseBinaryFile.stream);
|
|
101
|
-
|
|
102
129
|
} else {
|
|
103
|
-
console.log(`Found the latest release: ${staticInstaller.p3x.installer['p3x-html-pdf'][`${platform}-${arch}`]}`)
|
|
130
|
+
console.log(`Found the latest release: ${staticInstaller.p3x.installer['p3x-html-pdf'][`${platform}-${arch}`]}`);
|
|
104
131
|
|
|
105
132
|
releaseBinaryFileName = `${binPath}/${path.basename(staticInstaller.p3x.installer['p3x-html-pdf'][`${platform}-${arch}`])}`;
|
|
106
133
|
|
|
107
|
-
|
|
134
|
+
const fixedUrl = staticInstaller.p3x.installer['p3x-html-pdf'][`${platform}-${arch}`];
|
|
108
135
|
|
|
109
136
|
downloadResponse = await utils.http.request({
|
|
110
137
|
url: fixedUrl,
|
|
111
138
|
pipe: true,
|
|
112
|
-
})
|
|
139
|
+
});
|
|
113
140
|
|
|
114
141
|
releaseBinaryFile = utils.fs.createWriteStream(releaseBinaryFileName);
|
|
115
142
|
downloadResponse.pipe(releaseBinaryFile.stream);
|
|
@@ -125,30 +152,24 @@ const install = async () => {
|
|
|
125
152
|
|
|
126
153
|
downloadResponse.on('data', (chunk) => {
|
|
127
154
|
bar.tick(chunk.length);
|
|
128
|
-
})
|
|
155
|
+
});
|
|
129
156
|
|
|
130
157
|
await releaseBinaryFile;
|
|
131
158
|
|
|
132
|
-
|
|
133
159
|
if (platform === 'linux') {
|
|
134
|
-
console.log(`
|
|
135
|
-
await utils.childProcess.exec(`tar -xvf ${releaseBinaryFileName} -C ${binPath}`, true)
|
|
160
|
+
console.log(`Decompressing ${releaseBinaryFileName}`);
|
|
161
|
+
await utils.childProcess.exec(`tar -xvf ${releaseBinaryFileName} -C ${binPath}`, true);
|
|
136
162
|
} else if (platformSearch === 'mingw-w64-cross') {
|
|
137
|
-
console.log(`
|
|
163
|
+
console.log(`Installing ${releaseBinaryFileName}`);
|
|
138
164
|
const winCommand = `cmd.exe /v /c "set binpath=${binPath} && \"${releaseBinaryFileName}\" /S /D=!binpath! && echo !binpath!"`;
|
|
139
|
-
await utils.childProcess.exec(winCommand, true)
|
|
165
|
+
await utils.childProcess.exec(winCommand, true);
|
|
140
166
|
}
|
|
141
167
|
|
|
142
|
-
console.log(`
|
|
143
|
-
await fsExtra.remove(releaseBinaryFileName)
|
|
168
|
+
console.log(`Deleting ${releaseBinaryFileName} file.`);
|
|
169
|
+
await fsExtra.remove(releaseBinaryFileName);
|
|
144
170
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
await utils.childProcess.exec(`npm install ${jqueryVersion}`);
|
|
149
|
-
*/
|
|
171
|
+
console.log('Installation done.');
|
|
172
|
+
process.exit();
|
|
173
|
+
};
|
|
150
174
|
|
|
151
|
-
|
|
152
|
-
process.exit()
|
|
153
|
-
}
|
|
154
|
-
install()
|
|
175
|
+
install();
|
package/test/test.js
CHANGED
|
@@ -5,12 +5,21 @@ const fs = require('fs');
|
|
|
5
5
|
|
|
6
6
|
(async () => {
|
|
7
7
|
try {
|
|
8
|
-
//
|
|
9
|
-
const
|
|
8
|
+
// Define the output path
|
|
9
|
+
const assetsPath = path.resolve(__dirname, '..', 'assets');
|
|
10
|
+
const outputPath = path.join(assetsPath, 'p3x-html-pdf-output.pdf');
|
|
11
|
+
|
|
12
|
+
// Ensure the assets directory exists
|
|
13
|
+
if (!fs.existsSync(assetsPath)) {
|
|
14
|
+
fs.mkdirSync(assetsPath, { recursive: true }); // Create the directory if it doesn't exist
|
|
15
|
+
console.log(`Created directory: ${assetsPath}`);
|
|
16
|
+
}
|
|
17
|
+
|
|
10
18
|
if (fs.existsSync(outputPath)) {
|
|
11
19
|
fs.unlinkSync(outputPath);
|
|
12
20
|
}
|
|
13
21
|
|
|
22
|
+
|
|
14
23
|
// Define options for PDF generation
|
|
15
24
|
const options = {
|
|
16
25
|
settings: {
|
|
@@ -49,7 +58,7 @@ const fs = require('fs');
|
|
|
49
58
|
<th style="border: 1px solid #ddd; padding: 8px; background-color: #f4f4f4;">Price</th>
|
|
50
59
|
<th style="border: 1px solid #ddd; padding: 8px; background-color: #f4f4f4;">Total</th>
|
|
51
60
|
</tr>
|
|
52
|
-
${Array.from({ length:
|
|
61
|
+
${Array.from({ length: 26 }).map((_, i) => {
|
|
53
62
|
const price = (i + 1) * 10;
|
|
54
63
|
const quantity = (i % 5) + 1;
|
|
55
64
|
const total = price * quantity;
|
|
@@ -83,7 +92,7 @@ const fs = require('fs');
|
|
|
83
92
|
<li>Accepted payment methods include credit card, bank transfer, and PayPal.</li>
|
|
84
93
|
<li>Please ensure that all transactions reference the invoice number provided above.</li>
|
|
85
94
|
</ul>
|
|
86
|
-
<p style="font-size: 14px; color: #555;">If you have any questions, feel free to contact our support team at <a href="mailto:support@
|
|
95
|
+
<p style="font-size: 14px; color: #555;">If you have any questions, feel free to contact our support team at <a href="mailto:support@patrikx3.com">support@patrikx3.com</a>.</p>
|
|
87
96
|
</div>
|
|
88
97
|
<div class="ng-template-page-break"></div>
|
|
89
98
|
<div>
|