tojocky / node-printer

Native node.js printer
1.54k stars 443 forks source link

error thrown after label printing #186

Open Slos opened 7 years ago

Slos commented 7 years ago

Hi,

I know this is probably a long shot but ... trying anyway...

First of all, I'm a total newbie with nodejs/javascript. I've managed to print a label on a Zebra printer which is configured in CUPS on a raspberry pi. However, an error is thrown after the label is printed and my node app crashed as a result.

The printer in question is attached to a PC in our warehouse. The node app runs on the pi which is in the same LAN as the PC. The application successfully finds the printer on startup:

var Printer = require('node-printer'); console.log(Printer.list()); prints [ 'ZM400' ]

so far so good

when I use printer.PrintDirect() I get an error 'printDirect is not a function'... weird, not sure why... so I resorted to using printer.printBuffer() instead. As I mentioned, this does print... but an error is thrown and I don't know what is causing the error.

Do I have a problem with nested callbacks? I tried adding a try / catch around the printBuffer() call but no luck...

The scenario is as follows. My application is a node/express app which accepts a get request from a client. Upon receiving the request a function is called which make a POST request to a 3rd party API which returns a PDF file (in base64 encoded binary format). I am base64 decoding the data and passing it on to the printer.printBuffer() method. After that, express responds to the client with a index.html file..

app.get('/api/getlabel', function(req, res) { requestZasilkovnaCreatePdfLabel(res); });

`function requestZasilkovnaCreatePdfLabel(res) {

var xml = "";

console.log(Printer.list());

var responseXml = ""; // var printer = new Printer('ZM400'); var resp = res;

shippingLabelRequest.post({ url: "http://www.zasilkovna.cz/api/rest", headers: { "content-type": "application/xml", }, body: xml }, function (error, response, body) { responseXml = body; xmlParser.parseString(responseXml, function(err, result) { pdfData = result.response.result[0]; var buf = Buffer.from(pdfData, 'base64'); console.log(buf); printLabel(buf);

        res.sendFile('views/index.html', {root: __dirname});
    });
});

};`

`function printLabel(data) { var printer = new Printer('ZM400'); // var jobFromBuffer = printer.printBuffer(buf); printer.printBuffer(data);

// printer.printDirect({data:data
//  , printer:'ZM400'
//  , type: "TEXT"
//  , success:function(){
//      console.log("printed: "+barcode_text);
//  }
//  , error:function(err){console.log(err);}
// });

// Listen events from job
// jobFromBuffer.once('sent', function() {
//  jobFromBuffer.on('onexit', function() {
//  console.log('Job ' + jobFromBuffer.identifier + 'has been printed');
//  jobFromBuffer.removeAllListeners();
//  });
// });

}`

The label comes out of the printer fine but on the console I get:

events.js:141 throw er; // Unhandled 'error' event ^

Error: spawn lpq ENOENT at exports._errnoException (util.js:907:11) at Process.ChildProcess._handle.onexit (internal/child_process.js:189:32) at onErrorNT (internal/child_process.js:363:16) at nextTickCallbackWith2Args (node.js:511:9) at process._tickCallback (node.js:425:17)

please help :(

meji92 commented 6 years ago

I have the same issue. You have been able to solve it @Slos?

Slos commented 6 years ago

Hi meji92,

I did manage to solve this issue and I am printing labels on the Zebra printer without any problems now.

I noticed I am using 'printer' library instead of 'node-printer'

const printer = require('printer/lib');

printLabel:  function(orderId, buffer, printer_name, dataType, userName) {
            printer.printDirect({data: buffer
                , printer: printer_name
                , type: dataType
                , success:function() {
                        logger.info("Printed shipping label for order " + orderId + " on " + printer_name);
                        orderStatusManager.storeOrderStatusInformation(orderId, OrderStatusEnum.LABEL_PRINTED, userName, "");
                        warehouseManager.unlinkOrderFromBoxes(orderId);

                        //orderStatusManager.storeOrderStatusInformation(orderId, OrderStatusEnum.SHIPPED, userName, ""); // TODO this needs to be moved out once scanned for handover to transporter
                    }
                , error:function(err){
                        logger.error("Failed to print shipping label for order " + orderId + " on " + printer_name, err);
                        var statusComment = {
                            "message" : "Failed to print label"
                        }
                        orderStatusManager.storeOrderStatusInformation(orderId, OrderStatusEnum.FAULT, userName, JSON.stringify(statusComment));
                    }
            });

the above function is called like this, for example: labelPrinter.printLabel(orderId, str, CourierLabelPrinterSelectionEnum.IN_TIME, "RAW", userName);

or labelPrinter.printLabel(orderId, buf, CourierLabelPrinterSelectionEnum.ZASILKOVNA, "PDF", userName);

where in first example str is var buf = new Buffer.from(body.substr(0,4)+"^CI28\n"+body.substr(4)); //we need to hack the ZPL we get from InTime!? var str = String(buf);

and in second example buf is var buf = Buffer.from(result.response.result[0], 'base64');

you also need to make sure the printer is configured correctly in CUPS (and the lpd deamon is running on the print server) and the correct printer name is used in the print call.

I hope this helps :/

msg me if you are still stuck and maybe I will be able to help

meji92 commented 6 years ago

Thanks a lot for your quickly and complete response! I am using the correct library and other functions (printText() & printFile()) so I will check the lpd daemon and the name used in print call.

Again, thank you very much!