vg-print 1.0.410 → 1.0.412

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [中文](#chinese) | [English](#english)
4
4
 
5
5
  <span id="chinese"></span>
6
- [开源免费]一个开箱即用的打印设计器组件库(Vue 3)。现在聚焦于单一组件 `FullDesigner`,同时暴露底层 `hiprint` 能力与客户端直连(`hiwebSocket`)配置,便于快速集成模板设计、预览、浏览器打印、导出 PDF/图片、直- 接打印等功能。
6
+ [开源免费]一个开箱即用的打印设计器组件库(Vue 3)。现在聚焦于单一组件 `FullDesigner`,同时暴露底层 `hiprint` 能力与客户端直连(`hiwebSocket`)配置,便于快速集成模板设计、预览、浏览器打印、导出 PDF/图片、直接打印等功能。
7
7
  - 您可以直接安装引入体验功能.功能在不断完善中,请及时更新使用,欢迎反馈与建议,共同成长
8
8
  - 没有域名限制,无网可用. 随时提供帮助和解决问题.
9
9
  - npm搜索vg-print.
@@ -88,12 +88,12 @@ hiprint.register({
88
88
 
89
89
 
90
90
 
91
- # 静默打印客户端工具安装包
91
+ ## 静默打印客户端工具安装包
92
92
 
93
93
  ![静默打印客户端工具](https://gitee.com/gao111/electron-vg-print/raw/master/electron-hiprint.png)
94
94
 
95
95
  客户端工具下载:
96
- ```
96
+ ```text
97
97
  https://download.csdn.net/download/github_38400706/92538739
98
98
  ```
99
99
  ## 特性
@@ -103,12 +103,11 @@ https://download.csdn.net/download/github_38400706/92538739
103
103
  - 通过属性配置 `hiwebSocket` 的 `host`、`token` 与自动连接
104
104
  - 暴露实例方法:预览、打印、导出、连接控制等,外部可直接调用
105
105
  - 集成并导出 `hiprint`,可进行模板对象级的高级定制
106
- - 内置 `@sv-print/plugin-api-pdf3` 与 `@sv-print/plugin-api-image` 插件,提供更强大的导出功能
107
106
 
108
107
 
109
108
  ## 安装
110
109
 
111
- ```
110
+ ```bash
112
111
  npm i vg-print
113
112
  ```
114
113
 
@@ -154,10 +153,11 @@ npm i vg-print
154
153
  假如你部署的网站是: https://www.abcd.com/index.html
155
154
  那么确保 https://www.abcd.com/print-lock.css
156
155
  能够正常访问在你项目的 index.html 入口 添加 print-lock.css 打印样式【名称 print-lock.css】注意: media="print"
157
- <!-- 可以调整成 相对链接/自有链接, 【重要】名称需要一致 【print-lock.css】-->
158
- ```
156
+ 可以调整成相对链接/自有链接,但【重要】名称需要一致(`print-lock.css`):
157
+
158
+ ```html
159
159
  <link rel="stylesheet" type="text/css" media="print" href="/print-lock.css" />
160
- ```
160
+ ```
161
161
 
162
162
  ### 使用示例:与 FullDesigner 配合
163
163
 
@@ -282,7 +282,7 @@ const onSaveDirect = () => designer.value?.save()
282
282
 
283
283
  ```vue
284
284
  <template>
285
- <el-button @click="openPreview">显示预览</el按钮>
285
+ <el-button @click="openPreview">显示预览</el-button>
286
286
  <Preview
287
287
  ref="previewRef"
288
288
  v-model:modalShow="visible"
@@ -346,12 +346,13 @@ const showCustomPreview = () => {
346
346
 
347
347
  样式引入(确保设计与打印样式生效):
348
348
 
349
- ```
349
+ ```js
350
350
  // 全局样式(组件库样式)
351
351
  import 'vg-print/style.css'
352
+ ```
352
353
 
353
- // 打印锁样式(推荐;保证打印时样式稳定)
354
- // `index.html` 中引入:
354
+ ```html
355
+ <!-- 打印锁样式(推荐;保证打印时样式稳定) -->
355
356
  <link rel="stylesheet" type="text/css" media="print" href="/css/print-lock.css" />
356
357
  ```
357
358
 
@@ -476,7 +477,7 @@ const onSave = ({ template, data, templateId }) => {
476
477
 
477
478
  本库导出 `hiprint`,可直接创建与操作模板对象(`hiprint.PrintTemplate`):
478
479
 
479
- ```
480
+ ```js
480
481
  import { hiprint, defaultElementTypeProvider } from 'vg-print'
481
482
  // 全局配置
482
483
  hiprint.setConfig({ showAdsorbLine: true, showPosition: true, showSizeBox: true })
@@ -490,86 +491,86 @@ hiprint.init({
490
491
  lang: 'en'
491
492
  })
492
493
  // 创建模板对象
493
- const tpl = new hiprint.PrintTemplate({ template: {} })
494
+ const tpl = new hiprint.PrintTemplate({ template: {} })
494
495
  // 设计模板
495
- tpl.design('#hiprint-printTemplate', { grid: true })
496
+ tpl.design('#hiprint-printTemplate', { grid: true })
496
497
  // 浏览器打印
497
- tpl.print({ name: '示例' }, {}, {
498
- callback: () => {
499
- this.waitShowPrinter = false
500
- },
501
- })
498
+ tpl.print({ name: '示例' }, {}, {
499
+ callback: () => {
500
+ this.waitShowPrinter = false
501
+ },
502
+ })
502
503
 
503
504
  // 直接打印(需客户端已连接)
504
- tpl.print2({ name: '示例' }, {
505
- printer: '', // 打印机 名称
506
- title: '打印预览pdf'
507
- });
505
+ tpl.print2({ name: '示例' }, {
506
+ printer: '', // 打印机名称
507
+ title: '打印预览pdf'
508
+ });
508
509
 
509
510
 
510
511
  // 导出 PDF(内置示例参数)
511
- // 方式 1: 原生导出 (toPdf)
512
- // 模式1: 小模版需要在一页中排列的话...数据是数组格式
513
- tpl.toPdf([...], '打印预览pdf', {
514
- isDownload: true, // 不自动下载
515
- type: "blob", // 默认 blob 支持: blob、bloburl、pdfobjectnewwindow、dataurl --> jspdf.output(type)
516
- onProgress: (cur, total) => {
517
- const percent = Math.floor((cur / total) * 100);
518
- console.log("toPdf 进度", percent);
519
- // 导出进度100%的时候关闭等待
520
- if (cur === total) {
521
- // 导出完成
522
- }
523
- },
524
-
525
- })
512
+ //模式1: 小模版需要在一页中排列的话,增加增加页面宽高参数(想把多订单放在一页中排列)----小模板拼到大纸张(例如 A4)
513
+ tpl.toPdf(this.printDataVar, '打印预览pdf', {
514
+ paperWidth: 210,
515
+ paperHeight: 297,
516
+ scale: 2,
517
+ perPage: 6, // 每页模板数
518
+ leftOffset: -1, // 对齐偏移
519
+ topOffset: -1, // 对齐偏移
520
+ onProgress: (cur, total) => {
521
+ // 导出进度100%的时候关闭等待
522
+ if (cur === total) {
523
+ this.loading = false
524
+ }
525
+ console.log('toPdf 进度', Math.floor((cur/total)*100))
526
+ }
527
+ })
526
528
 
527
- // 方式 2: 插件导出 (toPdf2) - 推荐
528
- // 支持更多选项,如 isDownload, type (blob/url/...)
529
- tpl.toPdf2(this.printDataVar, '文件名', {
530
- paperWidth: 210,
531
- paperHeight: 297,
532
- scale: 2,
533
- perPage: 6,
534
- leftOffset:-1,
535
- topOffset:-1,
536
- onProgress: (cur: number, total: number) => {
537
- console.log('toPdf 进度', Math.floor((cur/total)*100))
538
- if (cur === total) {
539
- // 导出完成
540
- }
529
+ // 模式2:普通模板,导出预览全部页:
530
+ tpl.toPdf(this.printDataVar, '打印预览pdf', {
531
+ onProgress: (cur, total) => {
532
+ // 导出进度100%的时候关闭等待
533
+ if (cur === total) {
534
+ this.loading = false
541
535
  }
542
- })
536
+ }
537
+ });
543
538
 
544
539
  // 导出图片(内置示例参数)
545
- // 方式 1: 原生导出 (toImage)
546
- tpl.toImage({ name: '示例' }, {
547
- isDownload: true, // 不自动下载
548
- name: "图片名称",
549
- limit: 1, // 默认 10 多少页为一个 图片文件, 太多 图片文件就很长
550
- type: "image/jpeg", // 默认 image/jpeg --> canvas.toDataURL(type, quality)
551
- pixelRatio: 2, // 图片像素比 2: 提高清晰度 默认 window.devicePixelRatio.
552
- quality: 0.8, // 默认 0.92 图片质量 0-1
553
- toType: "url", // 默认 url 支持: url、blob
554
- onProgress: (cur, total) => {
555
- const percent = Math.floor((cur / total) * 100);
556
- console.log("toImage 进度", percent);
557
- if (cur === total) {
558
- // 导出完成
559
- }
560
- },
561
- })
562
-
563
- // 方式 2: 插件导出 (toImage2) - 推荐
564
- // 支持跨域图片(useCORS), 更多格式控制
565
- tpl.toImage2(this.printDataVar, {
566
- isDownload: true,
567
- name: '图片名称',
568
- type: 'image/jpeg',
569
- useCORS: true, // 开启跨域支持
570
- onProgress: (cur, total) => { ... }
571
- })
540
+ // 导出为多张图片,每张合成 6 页,自动下载 JPEG
541
+ tpl.toImage(this.printDataVar, {
542
+ isDownload: true,
543
+ name: '图片名称',
544
+ limit: 0,
545
+ type: 'image/jpeg',
546
+ pixelRatio: 2,
547
+ quality: 0.8,
548
+ toType: 'url',
549
+ onProgress: (cur, total) => {
550
+ // 导出进度100%的时候关闭等待
551
+ if (cur === total) {
552
+ this.loading = false;
553
+ }
554
+ }
555
+ })
572
556
 
557
+ //按 A4 纸张排版导出(把小模板排到 A4):
558
+ tpl.toImage(this.printDataVar, {
559
+ paperWidth: 210,
560
+ paperHeight: 297,
561
+ limit: 6,
562
+ isDownload: true,
563
+ name: 'A4排版',
564
+ type: 'image/jpeg',
565
+ pixelRatio: 2,
566
+ onProgress: (cur, total) => {
567
+ console.log('toImage 进度', Math.floor((cur/total)*100))
568
+ // 导出进度100%的时候关闭等待
569
+ if (cur === total) {
570
+ this.loading = false
571
+ }
572
+ }
573
+ })
573
574
  ```
574
575
 
575
576
  水印与授权行为说明:设计态与运行态分离。设计态不自动显示默认水印(由面板设置项决定);运行态按授权和面板内容合并控制。
@@ -584,9 +585,7 @@ import {
584
585
  getHtml,
585
586
  printBrowser,
586
587
  exportPdf,
587
- exportPdf2, // 插件导出
588
588
  exportImage,
589
- exportImage2, // 插件导出
590
589
  getPrinterList,
591
590
  refreshPrinterList,
592
591
  getAddress,
@@ -631,17 +630,8 @@ const preview = async () => {
631
630
  printBrowser(tpl, printData)
632
631
 
633
632
  // 4) 导出 PDF
634
- // 插件方法 (推荐)
635
- exportPdf(tpl, printData, '打印预览pdf', {
636
- isDownload: true, // 不自动下载
637
- type: "blob", // 默认 blob 支持: blob、bloburl、pdfobjectnewwindow、dataurl --> jspdf.output(type)
638
- onProgress: (cur, total) => {
639
- const percent = Math.floor((cur / total) * 100);
640
- console.log("toPdf 进度", percent);
641
- },
642
- })
643
633
  // 原生方法
644
- exportPdf2(tpl, printData, '打印预览pdf', {
634
+ exportPdf(tpl, printData, '打印预览pdf', {
645
635
  paperWidth: 210,
646
636
  paperHeight: 297,
647
637
  scale: 2,
@@ -653,23 +643,8 @@ exportPdf2(tpl, printData, '打印预览pdf', {
653
643
  }
654
644
  })
655
645
 
656
- // 5) 导出图片
657
- // 插件方法 (推荐)
658
- await exportImage(tpl, printData, {
659
- isDownload: true, // 不自动下载
660
- name: "图片名称",
661
- limit: 1, // 默认 10 多少页为一个 图片文件, 太多 图片文件就很长
662
- type: "image/jpeg", // 默认 image/jpeg --> canvas.toDataURL(type, quality)
663
- pixelRatio: 2, // 图片像素比 2: 提高清晰度 默认 window.devicePixelRatio.
664
- quality: 0.8, // 默认 0.92 图片质量 0-1
665
- toType: "url", // 默认 url 支持: url、blob
666
- onProgress: (cur, total) => {
667
- const percent = Math.floor((cur / total) * 100);
668
- console.log("toImage 进度", percent);
669
- },
670
- })
671
646
  // 原生方法
672
- await exportImage2(tpl, printData, {
647
+ await exportImage(tpl, printData, {
673
648
  isDownload: true,
674
649
  name: '图片名称',
675
650
  limit: 1,
@@ -733,80 +708,133 @@ const { pdfPath, imgPath } = await clientGenerate(tpl, printData, {
733
708
  disconnect()
734
709
  ```
735
710
 
736
- ### 导出 PDF 两种模式
711
+ ### 导出 PDF(toPdf / exportPdf)
737
712
 
738
- - 普通导出(按模板自身纸张与分页设置):
713
+ > `exportPdf(tpl, data, filename, options)` 本质调用的是模板实例的 `tpl.toPdf(data, filename, options)`;两者参数一致。
714
+
715
+ #### 模式 A:普通导出(按模板自身纸张与分页)
716
+
717
+ - 特点:不传纸张宽高,导出结果与预览分页一致(每个 `.hiprint-printPaper` 一页)。
718
+ - 适用:报告类、A4/A5 正常分页模板。
739
719
 
740
720
  ```js
741
- // 不传纸张尺寸,使用模板的面板尺寸与分页配置
721
+ // 不传 paperWidth/paperHeight,使用模板的面板尺寸与分页配置
742
722
  exportPdf(tpl, printData, '打印预览pdf', {
743
- onProgress: (cur, total) => console.log('toPdf 进度', Math.floor((cur/total)*100))
723
+ onProgress: (cur, total) => console.log('toPdf 进度', Math.floor((cur / total) * 100))
744
724
  })
745
725
  ```
746
726
 
747
- - A4 排版导出(把小模板排到指定纸张):
727
+ #### 模式 B:排版导出(把小模板拼到大纸张,例如 A4
728
+
729
+ - 特点:传入 `paperWidth/paperHeight`(mm)后,会进入“平铺排版导出”。
730
+ - 适用:小标签、小票、多订单合并到一张纸导出。
748
731
 
749
732
  ```js
750
- // 传入纸张尺寸与排版参数,将多个模板排到一张 A4
733
+ // 传入纸张尺寸与排版参数,将多个“标签模板”平铺到一张 A4
751
734
  exportPdf(tpl, printData, '打印预览pdf', {
752
735
  paperWidth: 210, // mm
753
736
  paperHeight: 297, // mm
754
- scale: 2, // 缩放系数(影响清晰度与排版)
755
- perPage: 6, // 每页排版的模板数量
756
- leftOffset: -1, // 左对齐偏移(mm
757
- topOffset: -1, // 上对齐偏移(mm
758
- onProgress: (cur, total) => console.log('toPdf 进度', Math.floor((cur/total)*100))
737
+ perPage: 6, // 每页放 6 个(不够的到下一页)
738
+ leftOffset: -1, // -1 表示水平居中;>=0 表示左边距 mm
739
+ topOffset: -1, // -1 表示垂直居中;>=0 表示上边距 mm
740
+ scale: 2, // 清晰度/性能权衡(也可用 pixelRatio
741
+ onProgress: (cur, total) => console.log('toPdf 进度', Math.floor((cur / total) * 100))
759
742
  })
760
743
  ```
761
744
 
762
- ### 导出图片 两种模式
745
+ #### 排版规则(重点:perPage=0/不传的行为)
746
+
747
+ - 传入了纸张宽高(`paperWidth/paperHeight` 或 `usePaperType: true`)时:
748
+ - `perPage > 0`:强制“每页 N 个”,例如 `perPage: 6` 就会 6 个一页。
749
+ - `perPage = 0` 或不传 `perPage`:自动计算“一页能放几个放几个”(由纸张尺寸 + 标签尺寸 + 行列间距决定)。
750
+ - 没有传纸张宽高时:
751
+ - 默认导出与预览一致(通常“一个模板一页”)。
752
+ - `perPage` 在该模式下不生效(因为不做平铺排版)。
753
+
754
+ ---
755
+
756
+ ### 导出图片(toImage / exportImage)
763
757
 
764
- - 普通导出(按模板自身纸张与分页设置):
758
+ > `exportImage(tpl, data, options)` 本质调用的是模板实例的 `tpl.toImage(data, options)`;两者参数一致。
759
+
760
+ #### 模式 A:普通导出(按模板分页导出图片)
765
761
 
766
762
  ```js
767
- // 不传纸张尺寸,按模板分页导出图片
763
+ // 不传 paperWidth/paperHeight:按模板分页导出
764
+ // splitPages: true 表示“每页一张图片”(推荐:避免长图占用太大内存)
768
765
  await exportImage(tpl, printData, {
769
766
  isDownload: true,
770
767
  name: '图片',
771
- limit: 1, // 多少页合成一张图片;0 或不传则导出整图
772
- type: 'image/jpeg', // 'image/png'
773
- pixelRatio: 2, // 像素比例(清晰度)
768
+ splitPages: true,
769
+ type: 'image/png', // 含二维码/条码建议 png;纯文字/照片可 jpeg
770
+ pixelRatio: 2,
774
771
  quality: 0.8, // 仅 JPEG 有效(0-1)
775
- toType: 'url', // 不下载时返回类型:'url' 'blob'
776
- onProgress: (cur, total) => console.log('toImage 进度', Math.floor((cur/total)*100))
772
+ toType: 'blob', // 推荐 blob(避免大 dataURL 阻塞)
773
+ onProgress: (cur, total) => console.log('toImage 进度', Math.floor((cur / total) * 100))
774
+ })
775
+ ```
776
+
777
+ ##### 合成长图(可选)
778
+
779
+ ```js
780
+ // limit: N 表示每 N 页合成一张“长图”;limit<=0 表示全部页合成一张(可能很大,不推荐)
781
+ await exportImage(tpl, printData, {
782
+ isDownload: true,
783
+ name: '长图',
784
+ limit: 6,
785
+ type: 'image/jpeg',
786
+ pixelRatio: 2,
787
+ quality: 0.85
777
788
  })
778
789
  ```
779
790
 
780
- - A4 排版导出(把小模板排到指定纸张):
791
+ #### 模式 B:排版导出(把小模板拼到大纸张,例如 A4
781
792
 
782
793
  ```js
783
- // 传入纸张尺寸以 A4 方式排版导出
794
+ // 传入纸张尺寸后,图片导出也会进入“平铺排版导出”
795
+ // 注意:在排版模式下 limit 的语义等同于 perPage(每张纸放几个标签)
784
796
  await exportImage(tpl, printData, {
785
797
  paperWidth: 210, // mm
786
798
  paperHeight: 297, // mm
787
- limit: 6, // 每张合成 6
799
+ limit: 6, // 每张“纸”放 6 个(不够的到下一张)
788
800
  isDownload: true,
789
801
  name: 'A4排版',
790
- type: 'image/jpeg',
791
- pixelRatio: 2,
792
- quality: 0.8
802
+ splitPages: true, // 每张纸输出一张图片(文件名自动追加 -1/-2/...)
803
+ type: 'image/png',
804
+ pixelRatio: 2
793
805
  })
794
806
  ```
795
807
 
808
+ #### 排版规则(重点:limit=0/不传的行为)
809
+
810
+ - 传入了纸张宽高(`paperWidth/paperHeight`)时:
811
+ - `limit > 0`:强制“每张纸 N 个”(等同于 PDF 的 `perPage`)。
812
+ - `limit = 0` 或不传 `limit`:自动计算“一张纸能放几个放几个”。
813
+ - 没有传纸张宽高时:
814
+ - `splitPages: true`:每页一张图(推荐)。
815
+ - `splitPages: false` 且 `limit > 0`:每 N 页合成长图。
816
+ - `splitPages: false` 且 `limit <= 0`:所有页合成一张超长图(不推荐)。
817
+
818
+ ---
819
+
796
820
  ### 参数说明(PDF/图片通用,含描述)
797
821
 
798
- - `paperWidth`、`paperHeight` 纸张尺寸(mm);传入后按该纸张排版,不传则使用模板自身尺寸与分页
799
- - `scale` 渲染缩放(PDF);提升清晰度或控制排版密度
800
- - `perPage` 每页模板数量(PDF);用于小模板排版到大纸张
801
- - `leftOffset`、`topOffset` 对齐偏移(mm);微调整体排版位置(PDF)
802
- - `limit` 图片合并页数;1 表示每张 1 页,6 表示每张 6 页;0/不传导出整图
803
- - `type` 图片格式;`'image/jpeg'` 或 `'image/png'`
804
- - `pixelRatio` 像素比例(图片);越大越清晰但文件更大
805
- - `quality` 图片质量(0-1,仅 JPEG 有效)
806
- - `toType` 返回类型(不下载时);`'url'` 或 `'blob'`
807
- - `isDownload` 是否直接下载图片文件
808
- - `name` 文件名或下载名
809
- - `onProgress(cur, total)` 导出进度回调;以 `cur/total` 计算百分比
822
+ - `paperWidth`、`paperHeight`:纸张尺寸(mm);传入后启用“排版导出”(小模板拼到大纸张)。
823
+ - `usePaperType`:PDF/图片可用;为 `true` 时按模板的 `paperType`(如 A4)设置页面尺寸。
824
+ - `scale` / `pixelRatio`:渲染缩放;`pixelRatio` 优先级高于 `scale`。值越大越清晰,但越耗时/耗内存。
825
+ - `perPage`:PDF 排版模式每页模板数量;`0/不传` 表示自动填充。
826
+ - `limit`:图片普通模式下用于“每 N 页合成长图”;图片排版模式下等同于“每张纸 N 个”;`0/不传` 表示自动填充(排版模式)或全量合成(普通模式,谨慎)。
827
+ - `splitPages`:图片每页/每张纸输出一张(推荐)。
828
+ - `type`:图片格式;`'image/jpeg'` 或 `'image/png'`(二维码/条码建议 png)。
829
+ - `quality`:图片质量(0-1,仅 JPEG 有效)。
830
+ - `toType`:返回类型(不下载时);`'url'` 或 `'blob'`。
831
+ - `isDownload`:是否自动触发下载。
832
+ - `name`:文件名(图片会自动追加页码后缀)。
833
+ - `leftOffset`、`topOffset`:排版对齐偏移(mm);`-1` 表示居中,`>=0` 表示边距。
834
+ - `onProgress(cur, total)`:导出进度回调;以 `cur/total` 计算百分比。
835
+ - `forcePng`(PDF):强制使用 PNG 写入 PDF(条码/二维码建议开启)。
836
+ - `maxCanvasPixels`:单页最大画布像素上限;导出卡顿/崩溃时可调小(例如 `2e7`)。
837
+ - `debugPerf`:输出每页渲染耗时到控制台,便于定位慢点。
810
838
 
811
839
  ### 导入说明(含描述)
812
840
 
@@ -914,16 +942,16 @@ No domain restrictions, available offline. Provides one-on-one technical support
914
942
  Search `vg-print` on npm.
915
943
  Contact me: QQ 984239686 or use the WeChat group on the homepage to solve problems.
916
944
 
917
- # Silent Printing Client Tool Installer
945
+ ## Silent Printing Client Tool Installer
918
946
 
919
947
  ![Silent Printing Client Tool](https://gitee.com/gao111/electron-vg-print/raw/master/electron-hiprint.png)
920
948
 
921
949
  More info and download:
922
- ```
950
+ ```text
923
951
  https://gitee.com/gao111/electron-vg-print
924
952
  ```
925
953
  Client tool download:
926
- ```
954
+ ```text
927
955
  https://download.csdn.net/download/github_38400706/92538739
928
956
  ```
929
957
 
@@ -934,7 +962,6 @@ https://download.csdn.net/download/github_38400706/92538739
934
962
  - Configure `hiwebSocket` `host`, `token` and auto-connection via props
935
963
  - Exposes instance methods: preview, print, export, connection control, etc., for external calls
936
964
  - Integrates and exports `hiprint` for advanced customization at the template object level
937
- - Built-in `@sv-print/plugin-api-pdf3` and `@sv-print/plugin-api-image` plugins for more powerful export functions
938
965
 
939
966
  ## Installation
940
967
 
@@ -1288,7 +1315,106 @@ exportPdf(tpl, printData, 'filename')
1288
1315
 
1289
1316
  ### Export PDF / Image
1290
1317
 
1291
- Support normal export and A4 layout export.
1318
+ `exportPdf` / `exportImage` are lightweight wrappers around the template instance methods:
1319
+
1320
+ - `exportPdf(tpl, data, filename, options)` → `tpl.toPdf(data, filename, options)`
1321
+ - `exportImage(tpl, data, options)` → `tpl.toImage(data, options)`
1322
+
1323
+ #### Export PDF
1324
+
1325
+ **Mode A: Normal export (follow template paging)**
1326
+
1327
+ ```js
1328
+ // No paperWidth/paperHeight: export pages exactly like preview pagination
1329
+ exportPdf(tpl, printData, 'report', {
1330
+ onProgress: (cur, total) => console.log('toPdf', Math.floor((cur / total) * 100))
1331
+ })
1332
+ ```
1333
+
1334
+ **Mode B: Layout export (tile small labels into a big paper, e.g. A4)**
1335
+
1336
+ ```js
1337
+ exportPdf(tpl, printData, 'labels', {
1338
+ paperWidth: 210, // mm
1339
+ paperHeight: 297, // mm
1340
+ perPage: 6, // put 6 labels per sheet (rest goes to next sheet)
1341
+ leftOffset: -1, // -1: center; >=0: left margin (mm)
1342
+ topOffset: -1, // -1: center; >=0: top margin (mm)
1343
+ scale: 2, // clarity vs performance (pixelRatio also supported)
1344
+ onProgress: (cur, total) => console.log('toPdf', Math.floor((cur / total) * 100))
1345
+ })
1346
+ ```
1347
+
1348
+ **Layout rules**
1349
+
1350
+ - With `paperWidth/paperHeight` (or `usePaperType: true`):
1351
+ - `perPage > 0`: fixed “N per sheet”
1352
+ - `perPage = 0` or omitted: auto-fill “as many as can fit per sheet”
1353
+ - Without paper size:
1354
+ - Export follows template pagination; `perPage` does not apply in this mode.
1355
+
1356
+ #### Export Image
1357
+
1358
+ **Mode A: Normal export (follow template paging)**
1359
+
1360
+ ```js
1361
+ // Recommended: one image per page (avoid very long images)
1362
+ await exportImage(tpl, printData, {
1363
+ isDownload: true,
1364
+ name: 'page',
1365
+ splitPages: true,
1366
+ type: 'image/png', // QR/barcode recommended
1367
+ pixelRatio: 2,
1368
+ toType: 'blob'
1369
+ })
1370
+ ```
1371
+
1372
+ **Optional: merge into long images**
1373
+
1374
+ ```js
1375
+ // limit: N pages per output image; limit<=0 merges all pages into one (can be huge)
1376
+ await exportImage(tpl, printData, {
1377
+ isDownload: true,
1378
+ name: 'merged',
1379
+ limit: 6,
1380
+ type: 'image/jpeg',
1381
+ pixelRatio: 2,
1382
+ quality: 0.85
1383
+ })
1384
+ ```
1385
+
1386
+ **Mode B: Layout export (tile small labels into a big paper, e.g. A4)**
1387
+
1388
+ ```js
1389
+ // In layout mode, `limit` works like “labels per sheet”
1390
+ await exportImage(tpl, printData, {
1391
+ paperWidth: 210,
1392
+ paperHeight: 297,
1393
+ limit: 6,
1394
+ isDownload: true,
1395
+ name: 'A4-layout',
1396
+ splitPages: true,
1397
+ type: 'image/png',
1398
+ pixelRatio: 2
1399
+ })
1400
+ ```
1401
+
1402
+ **Layout rules**
1403
+
1404
+ - With `paperWidth/paperHeight`:
1405
+ - `limit > 0`: fixed “N per sheet”
1406
+ - `limit = 0` or omitted: auto-fill “as many as can fit per sheet”
1407
+ - Without paper size:
1408
+ - `splitPages: true`: one image per page (recommended)
1409
+ - `splitPages: false` + `limit > 0`: merge N pages per long image
1410
+ - `splitPages: false` + `limit <= 0`: merge all pages into one long image (not recommended)
1411
+
1412
+ #### Common options
1413
+
1414
+ - `pixelRatio` / `scale`: render scale (higher = clearer but slower)
1415
+ - `forcePng` (PDF): force PNG for QR/barcode
1416
+ - `maxCanvasPixels`: cap per-page canvas pixels to reduce freezes
1417
+ - `debugPerf`: log per-page render time to console
1292
1418
 
1293
1419
  ### Notes
1294
1420