Pdfmake: Error in server side example

Created on 5 Oct 2018  路  9Comments  路  Source: bpampuch/pdfmake

In dev-playground/server.js

With the following code:
https://github.com/bpampuch/pdfmake/blob/c2cdd465e7f5146079e7f4a916e37d2d40567393/dev-playground/server.js#L39-L40

Browsers cannot open PDF which would be sent using res.contentType('application/pdf'); res.send(binary);, saying it's broken.

Change the lines to callback(result); solves the problem.

Most helpful comment

We are having this problem too, and just sending the raw binary buffer with express works just fine.
An example for a working solution for server-side pdf creation is the following:

pdf.js:

const path = require('path');
const PdfPrinter = require('pdfmake');

const fonts = {
  Roboto: {
    normal: path.join(__dirname, '/fonts/Roboto-Regular.ttf'),
    bold: path.join(__dirname, '/fonts/Roboto-Medium.ttf'),
    italics: path.join(__dirname, '/fonts/Roboto-Italic.ttf'),
    bolditalics: path.join(__dirname, '/fonts/Roboto-MediumItalic.ttf'),
  },
};

const printer = new PdfPrinter(fonts);

const Pdf = {
  createPdf(callback) {
    const document = {
      content: [
        'First paragraph',
        'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines'
      ],
    };

    const doc = printer.createPdfKitDocument(document);

    const chunks = [];

    doc.on('data', (chunk) => {
      chunks.push(chunk);
    });

    doc.on('end', () => {
      const result = Buffer.concat(chunks);
      callback(result);
    });

    doc.end();
  },
};

module.exports = Pdf;

The res part of the webserver:

Pdf.createPdf((pdf) => {
  res.contentType('application/pdf');
  res.send(pdf);
});

All 9 comments

I can not simulate it. In what browser is it? It write some error/warning in console?

Chrome 69.0.3497.100
Nothing printed in the console and Chrome tried to open the PDF but got error "Failed to load PDF document."

Tested with:
Browser: Chrome 69.0.3497.100 on Windows 10.
Nodejs: 8.11.4 LTS and 10.9.0

and everything is fine without any problems.

Here are my test environment and test code.

Windows 17763.1
Chrome 69.0.3497.100
Node v10.11.0

var http = require("http");
var express = require("express");
var path = require("path");
var bodyParser = require("body-parser");

var pdfMakePrinter = require("pdfmake");

var app = express();

var rootDir = path.resolve(path.dirname("."));

app.use(express.static(path.join(__dirname, "public")));
app.use(bodyParser.json({ limit: "50mb" }));
app.use(bodyParser.urlencoded({ extended: false }));

function createPdfBinary(pdfDoc, callback) {
  var fontDescriptors = {
    Roboto: {
      normal: path.join(
        __dirname,
        "..",
        "examples",
        "/fonts/Roboto-Regular.ttf"
      ),
      bold: path.join(__dirname, "..", "examples", "/fonts/Roboto-Medium.ttf"),
      italics: path.join(
        __dirname,
        "..",
        "examples",
        "/fonts/Roboto-Italic.ttf"
      ),
      bolditalics: path.join(
        __dirname,
        "..",
        "examples",
        "/fonts/Roboto-MediumItalic.ttf"
      )
    }
  };

  var printer = new pdfMakePrinter(fontDescriptors);

  var doc = printer.createPdfKitDocument(pdfDoc);

  var chunks = [];
  var result;

  doc.on("data", function(chunk) {
    chunks.push(chunk);
  });
  doc.on("end", function() {
    result = Buffer.concat(chunks);
    callback("data:application/pdf;base64," + result.toString("base64"));
  });
  doc.end();
}

app.get("/pdf", function(req, res) {
  var dd = { content: "This is an sample PDF printed with pdfMake" };
  createPdfBinary(
    dd,
    function(binary) {
      res.contentType("application/pdf");
      res.send(binary);
    },
    function(error) {
      res.send("ERROR:" + error);
    }
  );
});

var server = http.createServer(app);
var port = process.env.PORT || 1234;
server.listen(port);

console.log("http server listening on %d", port);

Fonts are all properly placed.
Start server with node .\server.js and GET http://localhost:1234/pdf on Chrome.
The result is still Failed to load PDF document and no complaints in server console.

How does it relate to dev-playground?
How to start dev-playground is described in readme.

Your code is different and run differently, it has no connection with dev-playground.

Thanks for the reply.

I was trying to point that the code I posted above is what people tend to use in production. So instead of require('../src/printer'), I use require("pdfmake"). The rest of the code stays the same.

I assume many would follow the piece of code in app.get part and it might be disappointing if one tries to implement his own server and gets PDF open error.

So it would be nice if you could provide some code suggestions about this possible issue when using a standalone server.

And I also tried to use the whole dev-playground, but after I followed the instructions in readme, I got error: (part of the reason I chose to write my own server sample the other day :-))

[nodemon] 1.18.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node ./dev-playground/server.js`
internal/modules/cjs/loader.js:583
    throw err;
    ^

Error: Cannot find module 'pdfkit'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
    at Function.Module._load (internal/modules/cjs/loader.js:507:25)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (C:\Users\Robert\sources\repos\pdfmake\src\pdfKitEngine.js:7:30)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
[nodemon] app crashed - waiting for file changes before starting...

It would be nice of you to help me out. 馃槉

We are having this problem too, and just sending the raw binary buffer with express works just fine.
An example for a working solution for server-side pdf creation is the following:

pdf.js:

const path = require('path');
const PdfPrinter = require('pdfmake');

const fonts = {
  Roboto: {
    normal: path.join(__dirname, '/fonts/Roboto-Regular.ttf'),
    bold: path.join(__dirname, '/fonts/Roboto-Medium.ttf'),
    italics: path.join(__dirname, '/fonts/Roboto-Italic.ttf'),
    bolditalics: path.join(__dirname, '/fonts/Roboto-MediumItalic.ttf'),
  },
};

const printer = new PdfPrinter(fonts);

const Pdf = {
  createPdf(callback) {
    const document = {
      content: [
        'First paragraph',
        'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines'
      ],
    };

    const doc = printer.createPdfKitDocument(document);

    const chunks = [];

    doc.on('data', (chunk) => {
      chunks.push(chunk);
    });

    doc.on('end', () => {
      const result = Buffer.concat(chunks);
      callback(result);
    });

    doc.end();
  },
};

module.exports = Pdf;

The res part of the webserver:

Pdf.createPdf((pdf) => {
  res.contentType('application/pdf');
  res.send(pdf);
});

Thx @robertying you saved my life hahaha

Probably you can not builded/installed pdfmake from source, see readme.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SummerSonnet picture SummerSonnet  路  3Comments

imoum007 picture imoum007  路  3Comments

ValeSauer picture ValeSauer  路  3Comments

Masber picture Masber  路  3Comments

sayjeyhi picture sayjeyhi  路  3Comments