I am attempting to generate a pdf file in a node.js environment. I am running node v 14.17.6. The issue I am seeing is that when I attempt to load a png image from the working directory, the image in the pdf is instead just a black square taking up the same space. I've attempted to save the image with transparency removed as I've seen some issues with this.
Note: This is all done in a node.js environment, not in the browser. I've spent over an hour looking for duplicates, but most duplicates seem to be centered on manipulation with the canvas or img element in the browser environment and not all on the server side.
The below code is a massively scaled down reproduction of the issue (all you need is a package.json file with jspdf @ 2.5.1 and an image in the same directory, in this case blue.png)
import fs from 'fs';
import { jsPDF } from 'jspdf';
const file = fs.readFileSync('blue.png');
const fileUri = `data:image/png;base64,${file.toString('base64')}`;
const pdf = new jsPDF('p', 'mm', [400, 500]);
pdf.addImage(fileUri, 'png', 100, 100, 200, 300);
fs.writeFileSync('test.pdf', pdf.output());
package.json is here:
{
"name": "stack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"type": "module",
"dependencies": {
"jspdf": "^2.5.1"
}
}
Updated:
import fs from 'fs';
import { jsPDF } from 'jspdf';
import Base64 from 'base-64';
import PNGJS from 'png-js';
const file = fs.readFileSync('blue.png');
console.log(file);
const fileUri = `data:image/png;base64,${file.toString('base64')}`;
global.btoa = Base64.encode;
global.html2pdf = {};
global.window = {document: {createElementNS: () => {return {}} }};
global.navigator = {};
global.PNG = PNGJS;
const pdf = new jsPDF();
pdf.addImage(fileUri, 'PNG', 40, 20, 0, 0);
fs.writeFileSync('test.pdf', pdf.output());
delete global.btoa;
delete global.PNG;
delete global.window;
delete global.navigator;
delete global.html2pdf;
DataUri: data:image/png;base64,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
from jsPDF in Node.js environment loads a black square as opposed to a png image
No comments:
Post a Comment