1

I am creating a sample project with NodeJs and jsPDF. When I run, it echos ReferenceError: window is not defined. I also used John Gordon answer from here, but again also same problem.

I tried with

var express = require('express');
var jsPDF = require('jspdf');
var app = express();

app.get('/', function(req, res)
{
    global.window = {document: {createElementNS: () => {return {}} }};
    global.navigator = {};
    global.btoa = () => {};

    var fs = require('fs');
    var jsPDF = require('jspdf');
    var jsPDFTable = require('jspdf-autotable');

    var doc = new jsPDF();
    doc.text("Hello", 10, 10);
    var data = doc.output();

    fs.writeFileSync('./tmp/storage/pdf/document.pdf', data);

    delete global.window;
    delete global.navigator;
    delete global.btoa;
});

var port = process.env.PORT || 8080;
app.listen(port);
console.log('Server started');

module.exports = app;

3 Answers3

3

All you need to do is to remove your var jsPDF = require('jspdf'); at the top and to have the similar declaration inside your app.get.. (which you already have) function like this,

var express = require('express');
var app = express();

app.get('/', function(req, res)
{
    global.window = {document: {createElementNS: () => {return {}} }};
    global.navigator = {};
    global.btoa = () => {};

    var fs = require('fs');
    var jsPDF = require('jspdf');
    var jsPDFTable = require('jspdf-autotable');

    var doc = new jsPDF();
    doc.text("Hello", 10, 10);
    var data = doc.output();

    fs.writeFileSync('./document.pdf', data);

    delete global.window;
    delete global.navigator;
    delete global.btoa;
});

var port = process.env.PORT || 8080;
app.listen(port);
console.log('Server started');

module.exports = app;

Hope this helps!

David R
  • 14,711
  • 7
  • 54
  • 72
  • Thank you for the code. It works fine without error which I mentioned before. –  Nov 09 '18 at 07:11
2

The specified package jspdf is a client only library and need to be used in a browser environment to work properly.

The description is clear in the package home page:

A library to generate PDFs in client-side JavaScript.

Now, the reason an npm package is available is because bundlers like Webpack and Browserify can load npm packages and convert them into a proper browser compatible script. The require() is not defined in a browser environment and will not work without these bundlers.

So, either choose a library that supports NodeJS like https://www.npmjs.com/package/pdfkit or shift your PDF related code to browser and work with it.

EDIT: https://github.com/MrRio/jsPDF/issues/566#issuecomment-382039316

shows that you can use the library in NodeJS env by making the following changes.

In that case, you need to define the global variables before requireing the module.

global.window = {document: {createElementNS: () => {return {}} }};
global.navigator = {};
global.btoa = () => {};

var fs = require('fs');
var jsPDF = require('jspdf');
var jsPDFTable = require('jspdf-autotable'); 
var app = require('express')();



app.get('/', function(req, res)
{
   var doc = new jsPDF();
   // ...
}
Faizuddin Mohammed
  • 4,118
  • 5
  • 27
  • 51
  • @ Faizuddin Mohammed , Thank you for the effort and nice explanations –  Nov 09 '18 at 07:12
0

You can place the script tag either in the head or body tag in the html page, either one is fine. To decide where to place, this answer might be of help

Roo D
  • 53
  • 7
  • why this? can you make an exmaple for mine? –  Nov 09 '18 at 06:20
  • Actually I realised you are doing this on the server side, so I agree with @Faizuddin Mohammed. If you want to generate pdfs on the server side, in this case a node application, you need to use node-jspdf instead of just jspdf. [node-jspdf](https://www.npmjs.com/package/node-jspdf) for example. – Roo D Nov 09 '18 at 06:39
  • ```var doc = jsPDF(); doc.text(20, 20, 'Hello, world.'); doc.save('Test.pdf', function(err){console.log('saved!');});``` – Roo D Nov 09 '18 at 06:41