许可证
配置 Exchange 导出授权、查询剩余额度并处理授权错误。
Exchange 在运行 @univerjs-pro/exchange-node 的服务端进程中读取许可证。转换用法见 Office 文件导入导出。
配置授权
推荐通过环境变量 UNIVER_LICENSE 与 UNIVER_LICENSE_KEY 成对提供授权。无需调用 configureExchange;SDK 在首次导出或额度查询时自动读取一次,后续调用复用该配置。未提供环境凭据时使用 Free;已提供但无效的授权会报错,不能用于导出。
也可以使用 configureExchange({ license, licenseKey }) 显式配置,它返回 Promise<void>。显式配置完全忽略环境变量;应等待配置完成后再开始使用新授权的导出。
import { configureExchange, getExportQuota } from '@univerjs-pro/exchange-node'await configureExchange({ license: '<license content>', licenseKey: '<licenseKey content>',})const quota = await getExportQuota()license 与 licenseKey 使用授权提供方交付的完整内容,不是文件路径。两项应成对配置,并通过应用的密钥管理系统提供。
| 输入 | 使用方式 |
|---|---|
不调用 configureExchange | 首次使用时成对读取环境变量;均未提供则使用 Free。 |
configureExchange({ license, licenseKey }) | 只使用显式凭据,完全忽略环境变量。 |
configureExchange({}) | 显式选择 Free,忽略环境变量。 |
| 所选来源只提供一个字段 | 返回 INVALID_ARGUMENT,不会从另一来源补齐。 |
完整的环境配置读取后即固定,即使后续操作失败也不会自动重读。更换默认授权应显式调用并等待 configureExchange;配置失败时保留此前配置,应处理错误后再开始新的导出。
同一 JavaScript 上下文中的 ESM 与 CommonJS 共用配置。每个 worker_threads Worker 都需独立配置或从环境变量初始化。导出使用调用公开导出方法时的配置,后续换证不会改变已发起的导出。
为单次操作指定授权
导出 API 和 getExportQuota 的选项可传入完整的 license、licenseKey,仅作用于本次操作,不修改默认配置。例如,使用同一授权查询额度并导出:
import { UniverInstanceType } from '@univerjs/core'import { ExchangeFormat, exportToBuffer, getExportQuota } from '@univerjs-pro/exchange-node'const credentials = { license: '<license content>', licenseKey: '<licenseKey content>' }const quota = await getExportQuota(credentials)const output = await exportToBuffer(workbook, { type: UniverInstanceType.UNIVER_SHEET, format: ExchangeFormat.XLSX, ...credentials,})此方式同样适用于文件导出、Snapshot 导出和可选 PDF 导出。不传这两个字段时使用默认配置;只传一个字段返回 INVALID_ARGUMENT。显式传入的完整凭据不会从默认配置或环境变量补齐,空字符串也不会被视为省略;授权无效时返回 LICENSE_INVALID,不会重新使用默认商业授权。
可选 PDF 支持
安装 PDF 扩展包,并在配置授权前导入 PDF 入口:
pnpm add @univerjs-pro/exchange-node @univerjs-pro/exchange-pdf-node-bindingimport '@univerjs-pro/exchange-node/pdf'import { configureExchange, getExportQuota } from '@univerjs-pro/exchange-node'await configureExchange({ license: '<license content>', licenseKey: '<licenseKey content>',})const quota = await getExportQuota()该入口注册 PDF 支持,原生组件在实际使用时加载。PDF 仍使用 importBuffer、importFile、exportToBuffer、exportToFile 及对应 Snapshot API,指定 UniverInstanceType.UNIVER_PDF 和 ExchangeFormat.PDF;无需改用另一套转换 API。仅处理 PDF 的应用不需要加载 Office 原生组件。环境变量配置同样适用于 PDF。
查询剩余额度
getExportQuota({ license, licenseKey }) 返回 Promise<ExportQuota>,查询该授权在 Office 与 PDF 间共享的额度。不传凭据时查询默认配置。查询不接收类型参数,也不判断授权是否允许导出某个类型;类型授权在实际导出时检查。
查询不扣次、不预留额度,也不检查 SDK 版本、授权是否已生效或导出类型权限。余额为零时仍成功返回当前快照;其他并发请求可能随后使用额度,请同时处理实际导出的错误。
授权尚未生效时,有限额度返回首个授权月的快照,periodStart 为未来日期。查询成功或 licenseStatus 为 valid 均不代表当前允许导出;版本、生效时间、类型权限、可用额度和并发名额在实际导出时检查。
| 字段 | 类型 | 含义 |
|---|---|---|
licenseStatus | 'not_configured' | 'expired' | 'valid' | 导出订阅未配置、已到期或未到期;valid 不表示已通过导出准入检查。无效授权直接报错。 |
expiresAt | string | null | 导出订阅到期的 UTC ISO 时间;未配置或无到期时间时为 null。 |
observedAt | string | 本次快照的 UTC ISO 时间。 |
limit | number | null | 当前月额度上限;不限次数时为 null。 |
used | number | null | 当前月已成功导出的次数;不限次数时为 null。 |
reserved | number | null | 当前月正在处理的导出占用次数;不限次数时为 null。 |
remaining | number | null | 当前可用次数,即 max(0, limit - used - reserved);不限次数时为 null。 |
periodStart | string | null | 所查询月额度窗口的 UTC ISO 起点,包含该时刻;尚未生效时为首期起点,不限次数时为 null。 |
periodEnd | string | null | 所查询月额度窗口的 UTC ISO 终点,不包含该时刻;不限次数时为 null。 |
periodEnd 表示下一月额度开始的时间,expiresAt 表示整个导出订阅到期的时间。订阅有效时始终使用商业额度;本月耗尽不会使用 Free,下个月开始使用新的商业月额度。订阅到期后使用原有 Free 剩余额度,不重新发放或清零。
有限额度快照示例:
{ "licenseStatus": "valid", "expiresAt": "2027-10-19T23:59:59Z", "observedAt": "2026-10-21T09:00:00Z", "limit": 500, "used": 20, "reserved": 1, "remaining": 479, "periodStart": "2026-10-19T00:00:00Z", "periodEnd": "2026-11-19T00:00:00Z"}使用额度
Free 每授权月允许 10 次成功导出。商业授权的次数、并发及版本范围以所购授权为准。Free 与商业授权均不设置授权层面的文件大小和单元格数量上限。周期与剩余额度以查询结果为准,未用完的月额度不结转。
导入无需配置导出授权,也不消耗导出次数。同一部署中,Office 与 PDF 使用同一商业授权时共享额度。Office 转换格式见 Office 文件导入导出。
每次成功转换计 1 次,返回 Buffer 即视为转换成功。转换成功后的文件写入、上传或下载失败不退回次数;再次成功转换会再次计次。本周期额度耗尽后拒绝新的导出,需等待下一授权周期或换用额度更高的有效授权;有效商业授权不会借用 Free 额度。
处理错误
使用结构化 code 判断错误,不要解析 message 文本。用户界面可根据错误码提供本地化提示;诊断信息请保留供技术支持使用。
import { UniverInstanceType } from '@univerjs/core'import { ExchangeError, ExchangeFormat, exportToBuffer } from '@univerjs-pro/exchange-node'try { const output = await exportToBuffer(workbook, { type: UniverInstanceType.UNIVER_SHEET, format: ExchangeFormat.XLSX, })} catch (error) { if (error instanceof ExchangeError) { // 根据 error.code 展示对应提示,例如额度不足时为 LICENSE_EXPORT_QUOTA_EXCEEDED console.error(error.code) } else { throw error }}下表区分额度查询(getExportQuota)与实际导出的报错时机。两类 API 均返回 Promise,使用 await 配合 try/catch 处理错误。
| 错误码 | 报错时机 | 含义及处理方式 |
|---|---|---|
LICENSE_EXPORT_QUOTA_EXCEEDED | 仅导出 | 当前周期的可用导出额度不足;查询额度或联系商务调整授权。 |
LICENSE_CONCURRENCY_TIMEOUT | 仅导出 | 等待可用导出并发名额超时;降低并发后再发起导出。 |
LICENSE_UNIT_TYPE_REJECTED | 仅导出 | 当前授权未包含此导出类型或该类型授权已到期;使用包含该类型的有效授权。 |
LICENSE_INVALID | 查询、导出 | 授权无效;检查完整凭据或联系授权提供方更新授权。 |
LICENSE_POLICY_INVALID | 查询、导出 | 授权配置不符合 SDK 要求;联系授权提供方更新授权。 |
LICENSE_NOT_YET_EFFECTIVE | 仅导出 | 授权尚未生效;在生效后使用。 |
LICENSE_VERSION_NOT_ALLOWED | 仅导出 | 当前 SDK 版本不在授权范围内;使用匹配版本或更新授权。 |
UNSUPPORTED_FORMAT | 仅导出 | 不支持指定的格式或格式与类型不匹配;检查导出选项。 |
INVALID_FILE | 仅导出 | 转换输入无效;检查输入内容。 |
INCOMPLETE_SNAPSHOT | 仅导出 | 导出数据不完整;提供完整数据或 Snapshot。 |
CONVERSION_FAILED | 仅导出 | 文件转换失败;保留错误信息并检查输入内容。 |
IO_ERROR | 仅导出 | 文件读写失败;成功转换后的文件写入失败已经消耗 1 次。 |
INVALID_ARGUMENT | 查询、导出 | 参数或凭据不完整;检查传入配置。 |
NATIVE_LOAD_FAILED | 查询、导出 | SDK 原生组件无法加载;检查已安装包及运行环境是否匹配。 |
LICENSE_USAGE_STATE_INVALID | 查询、导出 | 授权用量状态无法验证;保留错误信息并联系技术支持。 |
LICENSE_USAGE_STORAGE_ERROR | 查询、导出 | 授权用量处理失败;保留错误信息并联系技术支持,避免自动重复提交。 |
应用可根据 licenseStatus 与 expiresAt 自行展示到期提醒;SDK 不额外返回提示列表。
遇到授权用量处理异常时,不应仅根据错误推断本次是否已计次,请保留完整错误并联系技术支持。
你觉得这篇文档如何?