如何使用Node.js打印PDF文件

This article was translated from English: Does it need improvement?
Translated
View the article in English

在Node.js中打印PDF文件需要将文档发送到操作系统的打印后台处理程序。 pdf-to-printer npm包将系统调用抽象为一个基于Promise的API,它在Windows、macOS和Linux上工作,允许您在单个方法调用中排队一个打印作业。 在打印前生成PDF — 将HTML、URL或模板转换为可打印的文档 — IronPDF for Node.js自然而然地与此工作流配对。

快速入门:在Node.js中打印PDF文件

//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/quickstart.js
// 1. Install: npm install pdf-to-printer
const printer = require('pdf-to-printer');

// 2. Print the PDF file (returns a Promise)
printer
  .print('./invoice.pdf')
  .then(() => console.log('Print job queued successfully.'))
  .catch((err) => console.error('Print failed:', err));
//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/quickstart.js
// 1. Install: npm install pdf-to-printer
const printer = require('pdf-to-printer');

// 2. Print the PDF file (returns a Promise)
printer
  .print('./invoice.pdf')
  .then(() => console.log('Print job queued successfully.'))
  .catch((err) => console.error('Print failed:', err));
JAVASCRIPT

在Node.js中打印PDF的前置条件是什么?

使用pdf-to-printer前需要Node.js 14.x或更高版本和npm。 该包依赖于本机操作系统打印命令而不是捆绑的打印引擎,因此目标机器上必须已经配置了打印机驱动程序。

Windows 上,该包通过PowerShell调用SumatraPDF。 确保PowerShell脚本执行未被系统策略阻止。 在macOS和Linux上,该包委托给lp命令,它是CUPS打印系统的一部分。 确认已安装CUPS,并且至少有一台打印机在lpstat -p中注册。

请注意推荐使用Node.js 18.x LTS用于生产工作负载。 pdf-to-printer包支持所有活动的Node.js LTS版本。

如何设置Node.js项目以打印PDF?

在编写任何打印逻辑前,初始化新项目,安装该包,并创建一个最小的目录结构。

//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/setup.sh
mkdir pdf-printer
cd pdf-printer
npm init -y
npm install pdf-to-printer
//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/setup.sh
mkdir pdf-printer
cd pdf-printer
npm init -y
npm install pdf-to-printer
SHELL

安装后,为您的打印逻辑创建一个pdfs/文件夹来存放您想要打印的文档。 一个单独的config.js用于打印机设置,使打印机名称不在您的核心逻辑中——这是一个对于多环境部署的有用模式,其中目标打印机在开发和生产之间不同。

该模块使用运行时解析的本机绑定,因此不需要编译步骤。 node_modules/pdf-to-printer/dist/目录将包含为检测到的平台预构建的二进制文件。

如何使用基本用法打印PDF文件?

将绝对或相对文件路径传递给printer.print()。 方法在系统默认打印机上将这份文档排队,并在作业被后处理程序接受时解决Promise — 而不是在物理打印完成时。

//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/basic-print.js
const fs = require('fs').promises;
const printer = require('pdf-to-printer');

async function printPDF(filePath) {
  // Verify the file exists before sending to printer
  await fs.access(filePath);

  const stats = await fs.stat(filePath);
  if (stats.size === 0) {
    throw new Error('PDF file is empty');
  }

  await printer.print(filePath);
  console.log(`Print job queued: ${filePath}`);
}

printPDF('./pdfs/invoice.pdf').catch((err) => {
  if (err.code === 'ENOENT') {
    console.error('File not found:', err.path);
  } else {
    console.error('Print error:', err.message);
  }
});
//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/basic-print.js
const fs = require('fs').promises;
const printer = require('pdf-to-printer');

async function printPDF(filePath) {
  // Verify the file exists before sending to printer
  await fs.access(filePath);

  const stats = await fs.stat(filePath);
  if (stats.size === 0) {
    throw new Error('PDF file is empty');
  }

  await printer.print(filePath);
  console.log(`Print job queued: ${filePath}`);
}

printPDF('./pdfs/invoice.pdf').catch((err) => {
  if (err.code === 'ENOENT') {
    console.error('File not found:', err.path);
  } else {
    console.error('Print error:', err.message);
  }
});
JAVASCRIPT

在调用printer.print()之前检查文件是否存在,防止路径错误或文件已移动时出现静默故障。 ENOENT如果路径无法解析,给您一个描述性的错误,而不是一个通用的排队器拒绝。 常见的错误原因包括不正确的相对路径、缺少打印机驱动程序和打印机离线状态。

重要当打印作业被操作系统后台处理程序接受时Promise才会解析,而不是在文档完成打印时。 为了审计目的,记录解析时的时间戳,而不是假设文档已离开打印机。

如何在打印前生成PDF?

当文档尚不存在为文件时,使用IronPDF for Node.js生成它,然后再调用printer.print()。 IronPDF将HTML、URL和模板字符串渲染成可打印的PDF文件,无需单独的浏览器实例。

//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/generate-and-print.js
const { PdfDocument } = require('@ironsoftware/ironpdf');
const printer = require('pdf-to-printer');

async function generateAndPrint(htmlContent, outputPath) {
  // Render HTML to a PDF file using IronPDF
  const pdf = await PdfDocument.fromHtml(htmlContent);
  await pdf.saveAs(outputPath);

  // Send the generated file to the default printer
  await printer.print(outputPath);
  console.log(`Generated and printed: ${outputPath}`);
}

generateAndPrint('<h1>Monthly Report</h1><p>Sales data for May 2026.</p>', './pdfs/report.pdf');
//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/generate-and-print.js
const { PdfDocument } = require('@ironsoftware/ironpdf');
const printer = require('pdf-to-printer');

async function generateAndPrint(htmlContent, outputPath) {
  // Render HTML to a PDF file using IronPDF
  const pdf = await PdfDocument.fromHtml(htmlContent);
  await pdf.saveAs(outputPath);

  // Send the generated file to the default printer
  await printer.print(outputPath);
  console.log(`Generated and printed: ${outputPath}`);
}

generateAndPrint('<h1>Monthly Report</h1><p>Sales data for May 2026.</p>', './pdfs/report.pdf');
JAVASCRIPT

这种模式在报告工作流中很常见,其中PDF内容在运行时从数据库记录或API响应中组装。 请参阅HTML到PDF转换教程,以完整了解IronPDF的渲染选项,包括CSS支持和页眉/页脚注入。

如何指定自定义打印机选项?

printer.print()的第二个参数传递,以目标为特定的打印机、设置副本数、选择页范围或控制页缩放。 打印机名称必须匹配printer.getPrinters()返回的确切值。

//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/custom-options.js
const printer = require('pdf-to-printer');

async function printWithOptions(filePath) {
  // List available printers to find the correct name
  const printers = await printer.getPrinters();
  printers.forEach((p) => {
    console.log(`${p.name} -- default: ${p.isDefault}`);
  });

  const options = {
    printer: 'HP LaserJet Pro',  // Exact name from getPrinters()
    copies: 2,                   // Number of copies
    pages: '1-3,5',              // Pages to print (optional)
    scale: 'fit',                // 'fit' | 'noscale' | 'shrink'
    orientation: 'portrait',     // 'portrait' | 'landscape'
  };

  await printer.print(filePath, options);
  console.log(`Printed ${options.copies} copies to "${options.printer}"`);
}

printWithOptions('./pdfs/shipping-label.pdf').catch(console.error);
//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/custom-options.js
const printer = require('pdf-to-printer');

async function printWithOptions(filePath) {
  // List available printers to find the correct name
  const printers = await printer.getPrinters();
  printers.forEach((p) => {
    console.log(`${p.name} -- default: ${p.isDefault}`);
  });

  const options = {
    printer: 'HP LaserJet Pro',  // Exact name from getPrinters()
    copies: 2,                   // Number of copies
    pages: '1-3,5',              // Pages to print (optional)
    scale: 'fit',                // 'fit' | 'noscale' | 'shrink'
    orientation: 'portrait',     // 'portrait' | 'landscape'
  };

  await printer.print(filePath, options);
  console.log(`Printed ${options.copies} copies to "${options.printer}"`);
}

printWithOptions('./pdfs/shipping-label.pdf').catch(console.error);
JAVASCRIPT

getPrinters()具有两个目的:它确认打印机在线并可访问,并且提供OS用于路由打印作业的权威名称字符串。 打印机名称往往包含与系统设置中显示名不同的版本号或网络后缀。

提示在Windows上,getPrinters()从注册表返回打印机列表。 在macOS/Linux上,它查询CUPS。 打印机isDefault标志标识接收没有指定打印机名称时作业的打印机。

可以配置哪些打印机选项?

printerOptions对象支持以下字段:

pdf-to-printer option properties
选项类型说明示例值
打印机string正如getPrinters()返回的确切打印机名'HP LaserJet Pro'
副本number打印份数2
页面string页范围字符串'1-3,5'
scalestring页面缩放模式'fit''noscale''shrink'
方向string页面方向覆盖'portrait''landscape'

对于需要自定义纸张尺寸或需要在PDF生成过程中应用特定页面方向的文档,在保存文件之前在IronPDF渲染步骤中配置这些选项。

Icon Quote related to 可以配置哪些打印机选项?

我最喜欢的这种库是 IronPDF。它允许快速高效地操作 PDF 文件。它还具有许多有价值的功能,比如导出为 PDF/A 格式和数字签名 PDF 文档。

Milan Jovanovic related to 可以配置哪些打印机选项?

Milan Jovanovic

微软MVP

查看案例研究
Icon Quote related to 可以配置哪些打印机选项?

IronOCR 意味着我们每年可以节省 $40,000 的人工处理成本,同时提高生产力,并释放资源用于高影响任务。我强烈推荐它。

Brent Matzelle related to 可以配置哪些打印机选项?

Brent Matzelle

首席技术官,OPYN

查看案例研究
Icon Quote related to 可以配置哪些打印机选项?

Iron Suite 在我们的运营中起着至关重要的作用。这些工具提高了业务各方面的效率,包括创建平面图和改善库存管理。

David Jones related to 可以配置哪些打印机选项?

David Jones

首席软件工程师,Agorus Build

查看案例研究

如何在Node.js中实现批量打印?

通过迭代数组并为每个文件调用await保持作业顺序,这防止打印排队器被同时请求淹没。

//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/batch-print.js
const printer = require('pdf-to-printer');
const fs = require('fs').promises;
const path = require('path');

class BatchPrinter {
  constructor(printerName = null) {
    this.printerName = printerName;
    this.queue = [];
  }

  async addFiles(filePaths) {
    for (const filePath of filePaths) {
      try {
        await fs.access(filePath);
        this.queue.push(filePath);
      } catch {
        console.warn(`Skipped (not found): ${filePath}`);
      }
    }
  }

  async printAll(options = {}) {
    const results = { successful: 0, failed: 0, errors: [] };

    for (const filePath of this.queue) {
      try {
        const printOptions = {
          ...options,
          ...(this.printerName && { printer: this.printerName }),
        };
        await printer.print(filePath, printOptions);
        results.successful++;
        console.log(`Printed: ${path.basename(filePath)}`);
      } catch (err) {
        results.failed++;
        results.errors.push({ file: filePath, error: err.message });
      }
    }

    this.queue = [];
    return results;
  }
}

// Usage: print monthly reports to a specific printer
(async () => {
  const batch = new BatchPrinter('Office Printer A3');

  await batch.addFiles([
    './reports/january.pdf',
    './reports/february.pdf',
    './reports/march.pdf',
  ]);

  const results = await batch.printAll({ copies: 1 });
  console.log(`Done -- ${results.successful} printed, ${results.failed} failed.`);
})();
//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/batch-print.js
const printer = require('pdf-to-printer');
const fs = require('fs').promises;
const path = require('path');

class BatchPrinter {
  constructor(printerName = null) {
    this.printerName = printerName;
    this.queue = [];
  }

  async addFiles(filePaths) {
    for (const filePath of filePaths) {
      try {
        await fs.access(filePath);
        this.queue.push(filePath);
      } catch {
        console.warn(`Skipped (not found): ${filePath}`);
      }
    }
  }

  async printAll(options = {}) {
    const results = { successful: 0, failed: 0, errors: [] };

    for (const filePath of this.queue) {
      try {
        const printOptions = {
          ...options,
          ...(this.printerName && { printer: this.printerName }),
        };
        await printer.print(filePath, printOptions);
        results.successful++;
        console.log(`Printed: ${path.basename(filePath)}`);
      } catch (err) {
        results.failed++;
        results.errors.push({ file: filePath, error: err.message });
      }
    }

    this.queue = [];
    return results;
  }
}

// Usage: print monthly reports to a specific printer
(async () => {
  const batch = new BatchPrinter('Office Printer A3');

  await batch.addFiles([
    './reports/january.pdf',
    './reports/february.pdf',
    './reports/march.pdf',
  ]);

  const results = await batch.printAll({ copies: 1 });
  console.log(`Done -- ${results.successful} printed, ${results.failed} failed.`);
})();
JAVASCRIPT

BatchPrinter类将验证与执行分开。 文件在addFiles()期间不存在的情况下被跳过,以便单个缺失的文件不会中止整个批次。 printAll()方法记录每个文件的错误,并返回一个可以记录或转发给监控服务的摘要。

对于动态生成的报告,将此模式与IronPDF的HTML字符串到PDF转换结合使用以在单个管道中生成和打印。PDF压缩示例值得在大批量打印之前应用,以减少网络打印机上的后台传输时间。

提示如果打印机支持缓慢地打印排队,作业间添加一个短的await延迟——某些较旧的网络打印机拒绝快速连续提交。 200-500毫秒的暂停通常是足够的。

Node.js PDF打印的特定平台注意事项是什么?

pdf-to-printer包在每个操作系统上使用不同的系统命令。 理解底层机制有助于诊断特定平台的故障。

PDF打印在Windows上如何工作?

在Windows上,pdf-to-printer通过PowerShell命令外壳调用SumatraPDF。 SumatraPDF已与包捆绑,无需单独安装。 必须在当前执行策略下允许PowerShell脚本执行。 在PowerShell中运行Get-ExecutionPolicy进行检查; 如果结果是Bypass用于会话。

Windows上的打印机名称区分大小写,必须与设置 > 蓝牙和设备 > 打印机和扫描仪中显示的值完全匹配,包括任何括号中的网络后缀。

PDF打印在macOS和Linux上如何工作?

在macOS和Linux上,该包调用lp(CUPS的一部分)。 使用lpstat -p确认CUPS正在运行——这会列出所有注册打印机及其当前状态。 如果没有打印机出现,可能是CUPS服务未启动; 在Linux上使用sudo systemctl start cups或在macOS上通过系统偏好设置 > 打印机启用。

lp命令不支持与Windows SumatraPDF路径相同的所有选项。 orientation选项可能在基于CUPS的打印中没有效果,具体取决于打印机驱动程序。 在部署之前在目标硬件上测试。

警告pdf-to-printer包目前仅打印到本地和网络打印机。 通过该包不支持像Microsoft Universal Print这样的云打印服务。

如何处理打印PDF时的安全性和权限?

处理敏感文件(合同、财务记录、医疗表格)的生产打印系统需要访问控制和审计跟踪。 跟踪谁打印了什么及何时打印是许多受监管行业的合规要求。

//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/secure-print.js
const printer = require('pdf-to-printer');
const crypto = require('crypto');

class AuditedPrinter {
  constructor() {
    this.log = [];
  }

  async print(filePath, userId, options = {}) {
    const jobId = crypto.randomBytes(8).toString('hex');
    const entry = { jobId, userId, filePath, options, status: 'pending', startedAt: new Date().toISOString() };
    this.log.push(entry);

    try {
      await printer.print(filePath, options);
      entry.status = 'completed';
      entry.completedAt = new Date().toISOString();
      return { success: true, jobId };
    } catch (err) {
      entry.status = 'failed';
      entry.error = err.message;
      throw err;
    }
  }

  getLog(userId = null) {
    return userId ? this.log.filter((e) => e.userId === userId) : this.log;
  }
}

// Usage
const auditedPrinter = new AuditedPrinter();

(async () => {
  await auditedPrinter.print('./contracts/nda-2026.pdf', 'user-42', { copies: 1 });
  console.log('Audit log:', auditedPrinter.getLog('user-42'));
})();
//:path=/static-assets/pdf/content-code-examples/nodejs/how-to/nodejs-print-pdf/secure-print.js
const printer = require('pdf-to-printer');
const crypto = require('crypto');

class AuditedPrinter {
  constructor() {
    this.log = [];
  }

  async print(filePath, userId, options = {}) {
    const jobId = crypto.randomBytes(8).toString('hex');
    const entry = { jobId, userId, filePath, options, status: 'pending', startedAt: new Date().toISOString() };
    this.log.push(entry);

    try {
      await printer.print(filePath, options);
      entry.status = 'completed';
      entry.completedAt = new Date().toISOString();
      return { success: true, jobId };
    } catch (err) {
      entry.status = 'failed';
      entry.error = err.message;
      throw err;
    }
  }

  getLog(userId = null) {
    return userId ? this.log.filter((e) => e.userId === userId) : this.log;
  }
}

// Usage
const auditedPrinter = new AuditedPrinter();

(async () => {
  await auditedPrinter.print('./contracts/nda-2026.pdf', 'user-42', { copies: 1 });
  console.log('Audit log:', auditedPrinter.getLog('user-42'));
})();
JAVASCRIPT

AuditedPrinter类为每个打印请求分配一个唯一的作业ID,并记录用户身份、文件路径和时间戳。 持久化this.log到数据库或追加记录文件中,将其转化为耐久审计记录。 对于包含个人可识别信息的文件,考虑在它们到达打印队列之前使用IronPDF的PDF加密功能来保护静态文件。

对于通过HTTP接受打印请求的服务器应用程序,在打印前验证文件类型和大小——拒绝任何不是有效PDF二进制的上传。 不要在未经检查的情况下直接将用户提供的文件路径传递给printer.print()

重要将审计日志存储在应用程序可写目录之外。 使用文件系统写入访问权限的攻击者不应能够篡改打印记录。

Node.js PDF打印的下一步是什么?

本指南介绍了如何使用pdf-to-printer打印现有PDF文件到本地和网络打印机,从基础的单文件打印到批量队列,自定义打印机选项、平台考虑和审计记录,适用于受监管环境。

要通过PDF生成扩展此工作流程,开始IronPDF for Node.js的免费试用并按照HTML到PDF教程构建端到端文档管道。有关许可选项和批量定价,请参阅IronPDF许可页面

准备好更进一步了吗? 探索完整的IronPDF for Node.js指南集合,学习如何合并PDF文件压缩PDF文件转换PDF为图像

常见问题解答

在 Node.js 中打印 PDF 文件的最简单方法是什么?

使用pdf-to-printer npm包。通过npm install pdf-to-printer安装,然后调用printer.print('./file.pdf') -- 它返回一个Promise并在单次调用中使用系统默认打印机排队作业。

在 Node.js 中打印 PDF 的前提条件是什么?

Node.js 14.x或更高版本、npm和配置好的打印机驱动程序。在Windows上,PowerShell执行策略必须允许脚本执行。在macOS和Linux上,必须安装并运行CUPS,并通过lpstat -p注册至少一个打印机。

如何在Node.js中打印至特定打印机?

printerOptions对象作为printer.print()的第二个参数传入。将printer字段设置为printer.getPrinters()返回的确切打印机名称。打印机名称区分大小写,必须与操作系统注册表条目完全匹配。

我可以在同一个Node.js脚本中生成PDF然后打印吗?

可以。使用IronPDF for Node.js先生成文件:调用PdfDocument.fromHtml(html)渲染HTML内容,用pdf.saveAs(path)保存,然后将该路径传给printer.print(path)。通过npm install @ironsoftware/ironpdf安装IronPDF。

pdf-to-printer能在macOS和Linux上工作吗?

可以。在macOS和Linux上,包委托给CUPS的lp命令。用lpstat -p确认CUPS正在运行。注意,scaleorientation选项可能无法在所有CUPS打印机驱动程序上生效。

如何在Node.js中为打印作业添加日志?

printer.print()包装在一个类中,使用crypto.randomBytes(8).toString('hex')分配唯一作业ID,并记录文件路径、用户ID和时间戳。将日志数组持久化到应用程序可写目录之外的数据库或仅追加文件中。

Darrius Serrant
全栈软件工程师(WebOps)

Darrius Serrant 拥有迈阿密大学的计算机科学学士学位,目前在 Iron Software 担任全栈 WebOps 市场工程师。从小就被编码吸引,他认为计算机既神秘又易于接触,使其成为创意和问题解决的理想媒介。

在 Iron Software,Darrius 喜欢创造新事物,并简化复杂概念以使其更易理解。作为我们常驻的开发者之一,他还自愿教授学生,与下一代分享他的专业知识。

对于 Darrius 来说,他的工作令人满意,因为它被重视并产生真正的影响。

准备开始了吗?
版本: 2026.6 刚刚发布
Still Scrolling Icon

还在滚动吗?

想快速获得证据?
运行示例看着你的HTML代码变成PDF文件。