打印与导出
Viewer 的打印和导出都建立在同一个前提上:页面已经通过 Viewer 渲染出来。
这一层不重新设计模板。它消费当前 Schema、数据、渲染页尺寸和页面 DOM。
浏览器打印
最短路径是直接调用 print():
await viewer.print()不传 driverId 时,Viewer 会走浏览器打印路径。即使你已经注册了自定义打印驱动,默认也仍然是浏览器打印。
有 Host 时,Viewer 会先给当前 Host 加一层打印隔离样式,再调用 host.print()。打印结束或抛错后,这层隔离状态会被清理。
纸张尺寸策略
pageSizeMode 用来回答一个问题:纸张尺寸听谁的。
await viewer.print({ pageSizeMode: 'driver' })
await viewer.print({ pageSizeMode: 'fixed' })当前只支持两个值:
driver:连续纸会让打印机驱动决定纸张;固定页仍会使用 Schema 解析出的纸张尺寸。fixed:按 Schema 或已渲染页面尺寸生成固定纸张策略。
连续纸比较特殊。如果连续纸请求 fixed,Viewer 需要已经有渲染页尺寸。否则会发出 PRINT_RENDER_METRICS_MISSING 诊断。
自定义打印驱动
需要接本地服务、远程网关或专用设备时,注册一个打印驱动。
viewer.registerPrintDriver({
id: 'thermal-printer',
defaults: {
pageSizeMode: 'fixed',
},
async print(context) {
console.log(context.printPolicy)
console.log(context.renderedPages)
console.log(context.container)
},
})
await viewer.print({
driverId: 'thermal-printer',
})驱动可以提供 defaults.pageSizeMode。调用 viewer.print() 时,如果你没有显式传 pageSizeMode,Viewer 会使用驱动默认值。
context 里最常用的是:
schema和dataprintPolicyrenderedPagescontaineronPhase、onProgress、onDiagnostic
驱动适合做协议适配。布局、分页和尺寸策略应该交给 Viewer 先算好。
打印任务回调
自定义驱动可以复用 Viewer 传进来的任务回调。
await viewer.print({
driverId: 'thermal-printer',
onPhase(event) {
console.log(event.phase, event.message)
},
onProgress(event) {
console.log(event.current, event.total)
},
onDiagnostic(event) {
console.warn(event.code, event.message)
},
throwOnError: true,
})throwOnError: true 会让打印驱动错误、打印策略错误或浏览器打印错误继续向外抛出。默认情况下,Viewer 会发诊断并结束这次打印调用。
导出器注册
导出使用 registerExporter()。
viewer.registerExporter({
id: 'pdf-exporter',
format: 'pdf',
async export(context) {
console.log(context.renderedPages)
console.log(context.container)
return new Blob(['ok'], { type: 'application/pdf' })
},
})然后调用 exportDocument():
const blob = await viewer.exportDocument({
format: 'pdf',
entry: 'preview',
})Viewer 会按 format 找到第一个匹配的导出器。如果不传 format,会使用当前实例注册的第一个导出器。
没有匹配导出器时,会发出 NO_EXPORTER 诊断。传了 throwOnError: true 时,同一个错误会继续抛出。
导出任务回调
导出器可以有 prepare(),也可以在 export() 里上报进度和诊断。
const blob = await viewer.exportDocument({
format: 'pdf',
entry: 'api',
onPhase(event) {
console.log(event.phase)
},
onProgress(event) {
console.log(event.current, event.total)
},
onDiagnostic(event) {
console.warn(event.code, event.message)
},
throwOnError: true,
})当前 Viewer 会在导出过程中发出这些阶段:
- 有
prepare()时:preparing - 调用
export()前:exporting - 导出成功后:
completed
如果导出器抛错,Viewer 会发出 EXPORTER_ERROR。throwOnError: true 时会继续抛出原始错误。
字符串快捷调用
exportDocument() 也可以直接传格式字符串。
const blob = await viewer.exportDocument('pdf')这等价于:
const blob = await viewer.exportDocument({
format: 'pdf',
entry: 'api',
})如果你的导出来自预览按钮、保存菜单或程序调用,可以显式传 entry。当前类型支持 save-menu、preview 和 api。
打印策略解析
写驱动时,你通常会想知道 Viewer 最终准备怎么打印。
import { resolvePrintPolicy } from '@easyink/viewer'
const policy = resolvePrintPolicy({
schema: documentSchema,
options: { pageSizeMode: 'fixed' },
renderedPages: viewer.renderedPages,
})策略对象里常用字段是:
pageModepageSizeModesheetSizeorientationpageBreakBehavioroffset
sheetSize.source 会告诉你尺寸来自 schema 还是已渲染页面。
PDF 导出路径
Viewer 本身只定义导出器接口,不内置 PDF 导出实现。
viewer.registerExporter({
id: 'pdf-exporter',
format: 'pdf',
async export(context) {
const pages = Array.from(
context.container?.querySelectorAll<HTMLElement>('.ei-viewer-page') ?? [],
)
return renderPdfSomehow(pages, context.renderedPages ?? [])
},
})如果你要使用官方 DOM 转 PDF 插件,继续看 自定义导出插件。如果你要把 Viewer 接到打印设备,继续看 自定义打印驱动。
关于打印与导出,目前知道这些就够用了。排查错误时可以继续看 诊断系统。