How to pipe a stream using pdfkit with node js

15,236

Since pdfkit PDFDocument now is a stream, you have to buffer the data coming from the buffer:

var ipp = require("ipp");
var PDFDocument = require("pdfkit");

var doc = new PDFDocument;
doc.text("Hello World");

var buffers = [];
doc.on('data', buffers.push.bind(buffers));
doc.on('end', function () {
    var printer = ipp.Printer("http://127.0.0.1:631/printers/1");
    var file = {
        "operation-attributes-tag":{
            "requesting-user-name": "User",
        "job-name": "Print Job",
        "document-format": "application/pdf"
        },
        data: Buffer.concat(buffers)
    };

    printer.execute("Print-Job", file, function (err, res) {
        console.log("Printed: "+res.statusCode);
    });
});
doc.end();

Or you can use something like concat-stream module:

var ipp = require("ipp");
var PDFDocument = require("pdfkit");
var concat = require("concat-stream");

var doc = new PDFDocument;
doc.text("Hello World");

doc.pipe(concat(function (data) {
    var printer = ipp.Printer("http://127.0.0.1:631/printers/1");
    var file = {
        "operation-attributes-tag":{
            "requesting-user-name": "User",
        "job-name": "Print Job",
        "document-format": "application/pdf"
        },
        data: data
    };

    printer.execute("Print-Job", file, function (err, res) {
        console.log("Printed: "+res.statusCode);
    });
}));
doc.end();
Share:
15,236
Josiah
Author by

Josiah

Updated on June 27, 2022

Comments

  • Josiah
    Josiah almost 2 years

    Before PDFkit 0.5 - the following worked for me (generating a pdf via pdfkit/printing via ipp to CUPS):

    var ipp = require("ipp");
    var PDFDocument = require("pdfkit");
    
    var doc = new PDFDocument;
    doc.text("Hello World");
    
    doc.output(function(pdf)){
        var printer = ipp.Printer("http://127.0.0.1:631/printers/1");
        var file = {
            "operation-attributes-tag":{
                "requesting-user-name": "User",
            "job-name": "Print Job",
            "document-format": "application/pdf"
            },
            data: new Buffer(pdf, "binary")
        };
    
        printer.execute("Print-Job", file, function (err, res) {
            console.log("Printed: "+res.statusCode);
        });
    }
    

    As of PDFkit 0.5 - the output method is deprecated - but I can't seem to find an example of using the new pipe method with my scenario. If I'm not using a browser, do I still need a module like blob-stream?

  • Josiah
    Josiah almost 10 years
    Worked perfectly! Thanks!
  • jeremywoertink
    jeremywoertink over 9 years
    This works for me as well. Be sure to call doc.end() to actually fire off the end event. I've added an edit for anyone that comes across this new to the library.
  • Rogério Oliveira
    Rogério Oliveira almost 5 years
    Hi there! I would like to use that suggestion in my code. Unfortunately, I've a problem: when I try to save the binary data performing fs.writeFileSync('test.pdf', buffers) to get its content back, it generates a corrupted file. @Josiah some suggestion? Thank you a lot.
  • Farid Nouri Neshat
    Farid Nouri Neshat almost 5 years
    Yeah, you can concatenate the buffers into one buffer and only then you can pass it to fs.writeFileSync: fs.writeFileSync('test.pdf', Buffer.concat(buffers)). Of course to do it properly you should be streaming to it and you wouldn't need buffering: doc.pipe (fs.createWriteStream('test.pdf'))
  • Luke Brown
    Luke Brown almost 4 years
    This was really helpful using doc.on('end'). Spent 4 hours trying to get this working and your solution fixed it. Saves me creating a temp file to upload elsewhere, whereas now I can just send Buffer directly.