Node.js用pdfkit+ipp打印PDF乱码求助(Brother HL-L2360D)
解决Brother HL-L2360D通过IPP打印PDF乱码问题
核心原因
Brother HL-L2360D属于低端激光打印机,原生不支持直接解析PDF格式。设置document-format: application/octet-stream仅让打印机尝试自动识别内容,但它无法识别PDF二进制流,因此输出乱码。必须将PDF转换为打印机原生支持的格式(如PCL、位图)后再发送。
步骤1:确认打印机支持的文档格式
先通过IPP的Get-Printer-Attributes操作获取打印机支持的格式,重点查看document-format-supported字段:
const ipp = require('ipp'); const printer = ipp.Printer('http://printer.sandbox.com/ipp/print'); printer.execute('Get-Printer-Attributes', null, (err, res) => { if (!err) { console.log('支持的文档格式:', res['printer-attributes-tag']['document-format-supported']); } });
常见支持格式包括application/vnd.hp-PCL、image/png、image/jpeg等。
步骤2:转换PDF为打印机支持的格式并发送
方案A:转换为PNG位图发送(兼容性强)
使用pdf-poppler将PDF转为PNG,再通过IPP发送图片:
- 安装依赖:
npm install pdfkit ipp concat-stream pdf-poppler sharp
- 修改代码:
const ipp = require('ipp'); const PDFDocument = require('pdfkit'); const pdfPoppler = require('pdf-poppler'); const sharp = require('sharp'); const fs = require('fs'); // 生成测试PDF const doc = new PDFDocument({ margin: 0 }); doc.text('Testing Printing Functionality. Sent By Developer', 0, 780); doc.end(); // 捕获PDF缓冲区并转换为PNG const chunks = []; doc.on('data', chunk => chunks.push(chunk)); doc.on('end', async () => { const pdfBuffer = Buffer.concat(chunks); // 将PDF转为PNG const options = { format: 'png', out_dir: './temp', out_prefix: 'print_temp' }; const [pngPath] = await pdfPoppler.convertBuffer(pdfBuffer, options); // 读取并适配打印机分辨率(可选) const pngBuffer = await sharp(pngPath) .resize(1200) // 匹配打印机默认分辨率(如1200dpi) .toBuffer(); // 发送到打印机 const printer = ipp.Printer('http://printer.sandbox.com/ipp/print'); const msg = { 'operation-attributes-tag': { 'requesting-user-name': 'William', 'job-name': 'My Test Job', 'document-format': 'image/png' // 对应打印机支持的格式 }, data: pngBuffer }; printer.execute('Print-Job', msg, (err, res) => { console.log({ err, res }); // 清理临时文件 fs.unlinkSync(pngPath); }); });
方案B:转换为PCL格式发送(打印效率更高)
如果打印机支持PCL格式,可使用Ghostscript将PDF转为PCL:
- 先安装Ghostscript,再安装Node.js包装库:
npm install pdfkit ipp concat-stream gs
- 代码示例:
const ipp = require('ipp'); const PDFDocument = require('pdfkit'); const { execFile } = require('child_process'); const concat = require('concat-stream'); const doc = new PDFDocument({ margin: 0 }); doc.text('Testing Printing Functionality. Sent By Developer', 0, 780); doc.pipe(concat(pdfBuffer => { // 用Ghostscript将PDF转为PCL execFile('gs', [ '-q', '-dNOPAUSE', '-dBATCH', '-sDEVICE=pxlcolor', '-sOutputFile=-', '-', ], { input: pdfBuffer }, (err, pclBuffer) => { if (err) throw err; const printer = ipp.Printer('http://printer.sandbox.com/ipp/print'); const msg = { 'operation-attributes-tag': { 'requesting-user-name': 'William', 'job-name': 'My Test Job', 'document-format': 'application/vnd.hp-PCL' }, data: pclBuffer }; printer.execute('Print-Job', msg, (err, res) => { console.log({ err, res }); }); }); })); doc.end();
额外排查点
- 确认IPP路径正确性:Brother打印机的IPP路径通常为
ipp://printer.sandbox.com/ipp/print或http://printer.sandbox.com:631/ipp/print(631是IPP默认端口),可尝试修改路径测试。 - 检查打印机网络状态:确保打印机在线,且代码运行环境能正常访问打印机IP。
内容的提问来源于stack exchange,提问作者Shambhu
相关产品推荐
相关产品推荐

