许可证

配置 Exchange 导出授权、查询剩余额度并处理授权错误。

Exchange 在运行 @univerjs-pro/exchange-node 的服务端进程中读取许可证。转换用法见 Office 文件导入导出。

配置授权

推荐通过环境变量 UNIVER_LICENSE 与 UNIVER_LICENSE_KEY 成对提供授权。无需调用 configureExchange;SDK 在首次导出或额度查询时自动读取一次,后续调用复用该配置。未提供环境凭据时使用 Free;已提供但无效的授权会报错,不能用于导出。

也可以使用 configureExchange({ license, licenseKey }) 显式配置,它返回 Promise<void>。显式配置完全忽略环境变量;应等待配置完成后再开始使用新授权的导出。

TypeScript
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,仅作用于本次操作,不修改默认配置。例如,使用同一授权查询额度并导出:

TypeScript
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 入口:

Shell
pnpm add @univerjs-pro/exchange-node @univerjs-pro/exchange-pdf-node-binding
TypeScript
import '@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 不表示已通过导出准入检查。无效授权直接报错。
expiresAtstring | null导出订阅到期的 UTC ISO 时间;未配置或无到期时间时为 null。
observedAtstring本次快照的 UTC ISO 时间。
limitnumber | null当前月额度上限;不限次数时为 null。
usednumber | null当前月已成功导出的次数;不限次数时为 null。
reservednumber | null当前月正在处理的导出占用次数;不限次数时为 null。
remainingnumber | null当前可用次数,即 max(0, limit - used - reserved);不限次数时为 null。
periodStartstring | null所查询月额度窗口的 UTC ISO 起点,包含该时刻;尚未生效时为首期起点,不限次数时为 null。
periodEndstring | null所查询月额度窗口的 UTC ISO 终点,不包含该时刻;不限次数时为 null。

periodEnd 表示下一月额度开始的时间,expiresAt 表示整个导出订阅到期的时间。订阅有效时始终使用商业额度;本月耗尽不会使用 Free,下个月开始使用新的商业月额度。订阅到期后使用原有 Free 剩余额度,不重新发放或清零。

有限额度快照示例:

JSON
{  "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 文本。用户界面可根据错误码提供本地化提示;诊断信息请保留供技术支持使用。

TypeScript
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 不额外返回提示列表。

遇到授权用量处理异常时,不应仅根据错误推断本次是否已计次,请保留完整错误并联系技术支持。

你觉得这篇文档如何?

© 2026 DreamNum Co., Ltd.