npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sv-print/printer

v0.1.6

Published

Cross-platform printer and custom paper-size capability bridge for Electron, built on Koffi and a thin native C ABI (Winspool / Core Printing / CUPS). Ships prebuilt binaries per platform and CPU architecture.

Readme

@sv-print/printer

给 Electron 应用用的跨平台打印机能力包:列出打印机、查询驱动公布的纸张尺寸、校验并构造自定义纸张(标签纸、收银小票、条码纸这类非标尺寸)。

Windows / macOS / Linux 三平台同一套 API。平台细节——Windows 的 DEVMODE、macOS 的 opaque object、Linux 的 CUPS struct——都不暴露到 JS 层,只返回统一 JSON。

为 web 可视化打印设计器 sv-print 配套打印客户端提供的打印机能力包。

文档体验:sv-print.ibujian.cn

特性

  • 一个 tarball 装所有平台,不用按平台挑依赖,也没有平台专属的安装脚本
  • 没有 postinstall、没有运行时下载、不需要 node-gyp、不需要 electron-rebuild:预编译动态库直接跟在包里
  • Koffi 走 N-API,与 Electron 内置 Node 的 ABI 兼容,不需要按 Electron 版本重编
  • 尺寸统一用微米(μm),避开毫米 / 英寸浮点换算的精度抖动
  • TypeScript 类型随包发布,由源码直接生成,不存在手写声明与实现漂移

环境要求

  • 运行时 Node.js >= 16:koffi 走 N-API,与 Electron 内置 Node 的 ABI 无关(Electron 21 内置的 Node 16 也可以)
  • 从源码构建 / 跑测试需要 Node.js >= 20
  • 只能在 Electron 主进程调用(渲染进程请用 preload 转发,见快速开始)
  • 平台:Windows / macOS / Linux

随包发布的动态库

预编译产物按 <platform>-<arch> 分目录存放,运行时自动挑选,不需要你配置:

| target | 对应平台 | | ---------------- | -------------------------------- | | darwin-arm64 | macOS Apple Silicon | | darwin-x64 | macOS Intel | | win32-x64 | Windows x64 | | win32-ia32 | Windows x86(32 位) | | win32-arm64 | Windows ARM64 | | linux-x64 | Linux x64(glibc) | | linux-arm64 | Linux ARM64(glibc) | | linux-x64-musl | Alpine 等 musl libc 的 Linux x64 |

platform / arch 用的是 Node 的命名(darwin / win32 / linux,x64 / arm64 / ia32 / arm)。Linux 额外区分 glibc 与 musl,同样由运行时自动判定。

确认一下当前进程会用哪个 target:

const { resolveTarget } = require("@sv-print/printer");
console.log(resolveTarget()); // "darwin-arm64"

安装

npm install @sv-print/printer

快速开始

主进程

必须在主进程调用,包依赖 Koffi 的 native addon。所有方法都返回 Promise。

// main.js
const { app, BrowserWindow, ipcMain } = require("electron");
const printer = require("@sv-print/printer");

function registerPrinterIpc() {
  ipcMain.handle("printer:getPrinters", () => printer.getPrinters());
  ipcMain.handle("printer:getPaperSizes", (_e, printerId) =>
    printer.getPaperSizes(printerId)
  );
  ipcMain.handle("printer:validatePaper", (_e, printerId, w, h) =>
    printer.validatePaper(printerId, w, h)
  );
  ipcMain.handle("printer:customPaper", (_e, printerId, w, h) =>
    printer.customPaper(printerId, w, h)
  );
}

app.whenReady().then(async () => {
  console.log(printer.binaryInfo()); // 启动自检,见下文

  const list = await printer.getPrinters();
  if (!list.ok || list.printers.length === 0) return;

  const printerId = list.printers[0].id;

  // 驱动公布的纸张尺寸
  const sizes = await printer.getPaperSizes(printerId);
  console.log(sizes.papers); // [{ name: "A4", widthMm: 210, heightMm: 297, widthMicrons: 210000, ... }]

  // 校验一个自定义尺寸:80mm × 50mm 标签纸
  const check = await printer.validatePaper(printerId, 80000, 50000);
  console.log(check.supported, check.reason);

  // 构造一个打印任务可用的自定义纸张描述
  const custom = await printer.customPaper(printerId, 80000, 50000);
  console.log(custom.custom, custom.validatedWidthMicrons);
});

渲染进程

渲染进程不直接持有 FFI 能力,用 preload 暴露一个安全接口:

// preload.js
const { contextBridge, ipcRenderer } = require("electron");

contextBridge.exposeInMainWorld("printerAPI", {
  getPrinters: () => ipcRenderer.invoke("printer:getPrinters"),
  getPaperSizes: (printerId) =>
    ipcRenderer.invoke("printer:getPaperSizes", printerId),
  validatePaper: (printerId, w, h) =>
    ipcRenderer.invoke("printer:validatePaper", printerId, w, h),
  customPaper: (printerId, w, h) =>
    ipcRenderer.invoke("printer:customPaper", printerId, w, h),
});
// 渲染进程里
const list = await window.printerAPI.getPrinters();

引入方式

TypeScript / ESM / CommonJS 三种写法都成立,不需要挑构建产物:

// TypeScript
import { getPrinters, binaryInfo, PrinterNativeError } from "@sv-print/printer";
// ESM(含具名导入)
import { getPrinters } from "@sv-print/printer";
// CommonJS
const printer = require("@sv-print/printer");

包是 CommonJS 产物,ESM 的具名导入由 Node 的 CJS 互操作层解析,所以不需要单独的 ESM 构建产物。

API

尺寸单位统一是微米(μm),1 mm = 1000 μm。

| 方法 | 说明 | | --------------------------------- | -------------------------------------------------------- | | getPrinters() | 列出系统当前可见的打印机 | | getPaperSizes(printerId) | 查询驱动公布的纸张尺寸列表 | | validatePaper(printerId, w, h) | 校验操作系统打印驱动 / CUPS 是否接受该自定义尺寸 | | customPaper(printerId, w, h) | 同上,语义上表示「构造一个打印任务可用的自定义纸张描述」 | | binaryInfo() | 当前会加载哪个预编译产物(启动自检 / 排障) | | resolveTarget(platform?, arch?) | 只算 target 三元组,不加载动态库 |

微米换算

| 尺寸 | μm | | --------------- | ------------------- | | 80 mm | 80000 | | 58 mm | 58000 | | 40 × 20 mm | 40000 × 20000 | | A4 210 × 297 mm | 210000 × 297000 |

用微米而不是毫米,是为了避开 JS number 在毫米 / 英寸浮点换算里的精度抖动。

类型

interface Printer {
  id: string; // 平台内唯一标识:Windows 打印机名、CUPS destination 名
  name: string;
  driver?: string; // macOS: make-and-model / Windows: 驱动名 / CUPS: printer-make-and-model
  remote?: boolean; // macOS
  default?: boolean; // macOS
  port?: string; // Windows: USB001、192.168.1.10
  network?: boolean; // Windows
  shared?: boolean; // Windows
  instance?: string; // CUPS
  uri?: string; // CUPS: printer-uri-supported
  state?: string; // CUPS: printer-state,如 idle、processing
  isDefault?: boolean; // CUPS
}

三个平台返回的字段并不完全一致,缺失的就是 undefined。

interface PaperSize {
  id?: string; // macOS paper id / Linux CUPS media 名;Windows 不返回,用 paperCode
  name: string; // 平台本地化名称,如 "A4"、"iso_a4_210x297mm"
  paperCode?: number; // Windows
  widthMm: number;
  heightMm: number;
  widthMicrons: number;
  heightMicrons: number;
  leftMarginMicrons?: number; // CUPS 公布的页边距
  rightMarginMicrons?: number;
  topMarginMicrons?: number;
  bottomMarginMicrons?: number;
}

interface PaperValidation {
  ok: true;
  supported: boolean; // 驱动 / CUPS 是否接受该尺寸
  custom?: boolean; // customPaper 为 true;validatePaper 仅 macOS / Windows 为 true
  source?: "advertised" | "not-advertised"; // Linux:来自 CUPS 公布的媒体,还是没公布
  media?: string; // Linux:匹配到的 CUPS 媒体名
  orientation?: "portrait" | "landscape";
  reason?: string; // supported 为 false 时的原因说明
  requestedWidthMicrons: number;
  requestedHeightMicrons: number;
  validatedWidthMicrons?: number; // macOS / Linux:校验通过的尺寸
  validatedHeightMicrons?: number;
  driverWidthMicrons?: number; // Windows:驱动归一化后的 DEVMODE 尺寸
  driverHeightMicrons?: number;
}

完整类型见包内的 dist/types.d.ts。

语义边界

这几条容易误解,用之前请先看一眼:

  • validatePaper / customPaper 校验的是操作系统打印驱动 / CUPS 所报告或接受的能力,不是对真实纸张、纸盒、物理进纸的保证。

  • customPaper 是「构造并验证一个打印任务可用的自定义媒体描述」,不会修改系统全局打印机配置。真正打印时,仍需把对应尺寸传给打印 API(例如 webContents.print() 的 pageSize)。

  • 本包不提供打印动作,只做查询与校验。

  • Linux 上严格区分两种情况:

    1. exact advertised media —— CUPS destination 明确公布的尺寸,此时 source 为 advertised;
    2. arbitrary custom —— destination 没有公布 exact media 时,本包不会假装它支持任意自定义尺寸,而是返回 supported: false 并在 reason 里说明,此时 source 为 not-advertised。

    这比「尺寸看着合理就返回 true」可靠。

错误处理

所有失败都是 PrinterNativeError,带稳定的 code:

try {
  await printer.getPaperSizes("不存在的打印机");
} catch (error) {
  error.name; // "PrinterNativeError"
  error.code; // "PRINTER_NOT_FOUND"
  error.message; // "Printer not found"
  error.details; // native 返回的原始 JSON
}

参数在进入 native 之前就会校验,抛的是 INVALID_ARGUMENT:

printer.validatePaper("id", 0, 50000); // 抛 INVALID_ARGUMENT
printer.getPaperSizes(""); // 抛 INVALID_ARGUMENT

ERROR_CODES 导出了全部 code 到中文说明的映射:

const { ERROR_CODES } = require("@sv-print/printer");
console.log(ERROR_CODES.PRINTER_NOT_FOUND); // "找不到指定的打印机"

| code | 含义 | | ----------------------------------------------- | ------------------------------------------------- | | PRINTER_NOT_FOUND | 找不到指定的打印机 | | PRINTER_LIST_FAILED / PAPER_QUERY_FAILED | 枚举打印机 / 查询纸张失败(系统打印服务返回错误) | | INVALID_DIMENSION | 尺寸非法,必须是正数且不超过 10000000 微米 | | ENUM_PRINTERS_FAILED | Windows 枚举打印机失败 | | CUPS_DESTS_FAILED / CUPS_INFO_FAILED | Linux CUPS 目标列表 / 目标信息获取失败 | | PRINTER_NATIVE_BINARY_NOT_FOUND | 当前平台 / 架构没有对应的预编译动态库 | | PRINTER_NATIVE_ARCH_MISMATCH | 预编译动态库架构与当前进程不一致 | | PRINTER_NATIVE_UNSUPPORTED_PLATFORM / _ARCH | 不支持的平台 / CPU 架构 | | PRINTER_NATIVE_LOAD_FAILED | 动态库加载失败 | | PRINTER_KOFFI_MODULE_NOT_FOUND | Koffi 的 native addon 没被打进安装包 | | PRINTER_NATIVE_BAD_RESPONSE | native 返回了无法解析的内容 | | NATIVE_ERROR / PRINTER_NATIVE_ERROR | native 层内部错误 | | INVALID_ARGUMENT | 调用参数不合法 |

打包成 Electron 安装包

预编译动态库不是 Node addon,不需要 electron-rebuild,但必须让 asar 把它解包出来。 一个 npm 包里带着全部 8 个 target(约 1 MB),所以还要顺手把用不上的删掉:

// electron-builder.js —— 文件名必须是这个,不能写成 electron-builder.config.js
// electron-builder 只认 electron-builder.{yml,yaml,json,json5,toml,js,cjs,ts},
// 写成 .config.js 会被静默忽略,整个配置都不生效
module.exports = {
  npmRebuild: false,
  asarUnpack: [
    "**/node_modules/@sv-print/printer/**",
    "**/node_modules/koffi/**",
    "**/node_modules/@koromix/**",
  ],
  // 删掉用不上的 prebuilds,并把 Koffi 的 native addon 换成目标平台那一份
  afterPack: "@sv-print/printer/after-pack",
};

不加这一行的话,打 win32 的包也会带上 3 个 darwin 和 3 个 linux 的动态库, 某些杀软还会对「不属于本平台的 .dll」直接报警。

Koffi 的 native addon 必须跟着目标平台走

Koffi 的 native addon 不是编译进 koffi 包里的,而是拆成一堆 @koromix/koffi-<platform>-<arch> 的 npm 包(koffi 的 optionalDependencies)。 运行时它按 process.platform-process.arch 去相邻目录找对应那一个:

node_modules/koffi/src/koffi/index.cjs → node_modules/@koromix/koffi-win32-x64

npm 安装时会按 os/cpu 跳过用不上的那些。于是 macOS 上 npm install 之后 node_modules/@koromix/ 里只有 koffi-darwin-arm64,而 electron-builder 打包只是把 node_modules 原样抄进安装包 —— 打出来的 win32 包里依然只有 darwin 那一份, Windows 用户第一次调用就撞上 Koffi 自己那句没什么信息量的 Cannot find the native Koffi module; did you bundle it correctly?。

afterPack 把这件事也一并做了:

| 情况 | 处理 | | ------------------------------------------------ | --------------------------------------------------------------------------------- | | 目标平台的包已经装在应用自己的 node_modules 里 | 直接拷进产物,不联网 | | 没有 | 从 npm 装上与当前 koffi 完全同版本的 tarball(版本不一致会被 koffi 拒绝加载) | | 产物里还有别的平台 | 删掉,打 win32 的包不再夹带 darwin 的 .node | | 认不出的平台/架构,或 koffi 压根没发布这个平台 | 一个字节都不动 | | 补不上(离线、装不上、404) | 直接让打包失败,并把三条补救办法一起打出来 |

公司内网源用 npm_config_registry 指定。完全离线的机器可以自己装好,但要注意 装在哪里会被打进安装包:electron-builder 默认只收生产依赖树,放在 devDependencies 里的包除非被你的 files 通配(如 electron-egg 常见的 "files": ["**/*"])扫到,否则不会进产物。 稳妥的做法是放进依赖而不是 devDependencies:

npm i --save-prod --force @koromix/koffi-win32-x64

也可以打包时设 SV_PRINT_KOFFI_OFFLINE=1,让钩子只从本机已装好的包里取、不联网。

没配 asarUnpack 也能用,但会换一条落点

asarUnpack 里的 **/node_modules/koffi/** 仍然建议配上——它让安装包结构保持常规。 但很多项目只配了 afterPack 没配 asarUnpack,这时 electron-builder 只会自动解包它认得出的 原生文件(版本不同策略还不同:26 会解包带 .node 的包,23 只解含原生二进制的整个包), koffi 的 JS 于是留在 app.asar 里,它的 __dirname 也在 asar 内, ${__dirname}/../../../@koromix/... 指向 asar 里一个空目录,往 app.asar.unpacked 里放包它看不见。

这种情况钩子会改用 koffi 自己的备用查找位置(loadDynamic 里 process.resourcesPath 那一支):

resources/koffi/build/win32_x64/koffi.node

判据不是"解包目录里有没有痕迹"——electron-builder 23 的产物里一个痕迹都不留, 只看目录会误判成"这个应用根本没带 koffi"。钩子直接读 app.asar 的索引(那是打包结果的 权威清单),顺带还能从里面读出 koffi 的版本号,所以连 projectDir 拿不到也能补包。

构建日志里会带一句 koffi is inside app.asar, used its fallback path,便于确认走了哪条路。 两个例外仍然需要 asarUnpack:32 位 ARM(koffi 按 ELF 浮点 ABI 决定目录名,猜不出来), 以及 mac-universal 合并阶段(那时 @electron/universal 只认 asar 索引里的路径)。

代价:asar 里那几份别的平台的 .node 已经压进去了,删不掉(要重新打 asar), 所以这种布局的安装包会比配了 asarUnpack 时大几百 KB 到几 MB。

mac-universal 的每个 slice 会把两个 darwin 包都放本 slice 架构的 addon, 与 prebuilds 的处理同源。原因是 @electron/universal 合并两个 slice 时有三条硬约束:

| 约束 | 违反的后果 | slice 阶段怎么做 | | ------------------------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------- | | 同一路径两侧都要存在,且 Mach-O 内容必须不同 | that's the same in both x64 and arm64 builds | 两个 darwin 包都放本 slice 架构的 addon | | 非 Mach-O 文件(ELF/PE/JS)两侧必须逐字节一致 | Expected all non-binary files to have identical SHAs | linux/win32 的包原样不动 | | mergeASARs 照 app.asar 的索引去磁盘取 unpacked 文件 | ENOENT | 一个字节都不删,裁剪推迟到合并之后那次 afterPack |

第三条踩过一次:app.asar 的索引里仍然登记着那些 unpacked 文件,合并时会照着索引去读, slice 阶段删掉的目录当场就会让整个 universal 合并失败。

prunePrebuilds({ root, platform, arch }) 只管预编译动态库; ensureKoffiNative({ root, platform, arch }) 只管 Koffi 的包,自研流程可以分开调用。

prebuilds 的裁剪规则

afterPack 对预编译动态库做的事:按 electron-builder 当前打包的平台与架构,只留下对应的 target 目录。 几个细节是刻意的:

| 场景 | 保留 | 原因 | | ----------------- | ----------------------------- | -------------------------------------------------------- | | win32 + x64 | win32-x64 | | | mac-universal | darwin-arm64、darwin-x64 | 合并后两个目录里都是通用二进制,任一架构的进程都加载得了 | | linux + x64 | linux-x64、linux-x64-musl | 打包时无从知道目标机的 libc,两个都留 | | 认不出的平台/架构 | 一个都不删 | 删错的后果是应用装完第一次调用就崩 |

它同时支持 asar 打包与 asar: false 两种布局。找不到本包、或 target 编译缺失时, 要么原样保留,要么直接让打包失败并说明缺哪个 target,不会安静地产出一个装完就崩的包。

用 electron-forge / @electron/packager / 自研流程的话,规则等价:所有 *.dll、*.dylib、*.so,以及 node_modules/koffi、node_modules/@koromix,必须位于 asar 之外;并且把 prebuilds/ 里不属于目标平台与架构的目录删掉(也可以直接调用本包导出的 prunePrebuilds({ root, platform, arch }))。

Koffi 走的是 N-API,Electron 内置 Node 与它 ABI 兼容,不需要按 Electron 版本重编。

包里已经处理了 asar 路径:包内 JS 仍在 app.asar 内时,解析器会把动态库路径自动重映射到 app.asar.unpacked。如果没配 asarUnpack,报错信息里会直接给出该加哪几行。

排障

启动自检

console.log(printer.binaryInfo());
// {
//   target: 'darwin-arm64',
//   path: '/app/Contents/Resources/app.asar.unpacked/node_modules/@sv-print/printer/prebuilds/darwin-arm64/libprinter_native.dylib',
//   format: 'macho',
//   arch: 'arm64',
//   source: 'asar-unpacked',
//   insideAsar: false
// }

binaryInfo() 是同步的,不触发 native 调用,适合放在启动时打一行日志。insideAsar 为 true 说明路径还落在 asar 虚拟目录里,dlopen 必然失败——把 asarUnpack 补上即可。

解析器会读文件头核对真实架构(Mach-O / PE / ELF 都支持),所以「目录名写着 arm64、内容其实是 x86_64」这种问题会直接报 PRINTER_NATIVE_ARCH_MISMATCH,而不是等到 dlopen 抛一个含糊的错误。

缺产物时会发生什么

不会在 require 时就炸,而是在第一次调用 API 时抛出带 code 的错误,并把当前安装里已有的目标和补救办法一起打出来:

PrinterNativeError [PRINTER_NATIVE_BINARY_NOT_FOUND]: No native printer library for "linux-arm64".
Looked for: .../prebuilds/linux-arm64/libprinter_native.so
Prebuilt targets present in this install: darwin-arm64, darwin-x64.
Add this to your electron-builder config: asarUnpack: [...]     # 路径在 asar 内时才是这条
All supported targets: darwin-x64, darwin-arm64, ..., linux-arm64-musl.

临时指向自己的动态库

不想改包内文件时,用环境变量覆盖:

export ELECTRON_PRINTER_KOFFI_BINARY=/path/to/libprinter_native.dylib

适合验证「是不是我本地这个库的问题」。

常见问题

渲染进程能直接 require 这个包吗? 不能。包依赖 Koffi 的 native addon,只能在主进程用。渲染进程通过 preload + contextBridge 转发,见快速开始。

装完必须重编吗? 不需要。包内已带对应平台的预编译动态库,npm install 之后直接用。没有 postinstall,不会在安装时下载或编译任何东西。

需要 electron-rebuild 吗? 不需要。预编译动态库不是 Node addon,不参与 N-API 编译;Koffi 是 N-API,与 Electron 内置 Node 的 ABI 兼容,按 Electron 版本重编反而多余。

打包后启动就崩,报 dlopen 或 PRINTER_NATIVE_BINARY_NOT_FOUND? 九成是 asar 没解包。prebuilds/** 里的动态库必须落在 app.asar.unpacked,加上 asarUnpack 规则(见打包成 Electron 安装包)重新打包即可。用 binaryInfo() 看 insideAsar 是不是 true 可以立刻确认。

报 PRINTER_NATIVE_ARCH_MISMATCH 怎么办? 说明库文件头里的真实架构和当前进程对不上。常见于 Rosetta 下跑 x64 进程、或者手工替换过 prebuilds/ 里的文件。binaryInfo() 会报出文件头读到的真实架构,按它重装对应 target 的包即可。

报 Cannot find the native Koffi module; did you bundle it correctly?? Koffi 自己的 native addon(@koromix/koffi-<platform>-<arch>)没跟着目标平台走, 九成是在一台机器上 npm install、又拿去打另一个平台的包。本包会把它换成 PRINTER_KOFFI_MODULE_NOT_FOUND,并直接写清缺哪个包、那个目录里现在有什么:

PrinterNativeError [PRINTER_KOFFI_MODULE_NOT_FOUND]: Koffi's native addon is not in this build:
it loads node_modules/@koromix/koffi-win32-x64 next to the koffi package
(D:\app\resources\app.asar.unpacked\node_modules\@koromix).
Packages found there: koffi-darwin-arm64.
...

对着这个目录确认一眼就能定性:只有别的平台的包,就是本文档上一节说的那件事; 目录是空的或者压根没有 @koromix,则是 asarUnpack 没配。 重新打包前把 asarUnpack 与 afterPack 两行配上(见打包成 Electron 安装包)即可。

getPrinters() 返回空数组? 三个平台都要求打印子系统本身是就绪的:Linux 上 CUPS 服务没启动(systemctl status cups)就会空;Windows 上机器里没有任何已安装的打印机会空;macOS 上没有配置过打印机会空。也可以先用系统自带的打印面板确认能看到打印机。

validatePaper 返回 supported: false,是这台打印机不支持自定义纸张吗? 不一定。Linux 上分两种情况:CUPS 明确公布了该尺寸(source: "advertised")才可能为 true;没公布时本包不会假装支持,直接返回 false 并在 reason 里说明。macOS / Windows 上返回的是驱动是否接受该尺寸。建议先调 getPaperSizes() 看驱动公布了什么,再决定怎么填这个尺寸。

customPaper 会把纸张尺寸加进系统打印机设置吗? 不会。它只构造并校验一个打印任务可用的媒体描述,不修改系统全局配置。要真正按这个尺寸打印,仍需把它传给打印 API,例如 webContents.print({ pageSize: { width, height } })。

尺寸该传毫米还是微米? 微米。80mm 传 80000,58mm 传 58000,A4 传 210000 × 297000。必须是 1 到 10000000 之间的正整数,否则抛 INVALID_ARGUMENT。

这个包能帮我打印吗? 不能。它只提供查询与校验能力,打印动作请用 Electron 的 webContents.print() / printToPDF(),或把拿到的自定义纸张描述传给自己的打印流程。

License

Apache-2.0