--- name: sv-print description: 可视化打印设计器组件。基于 Svelte 构建,支持 Vue、React、Angular、jQuery 等框架引入。提供拖拽式模板设计、预览、打印、导出 PDF/图片功能,支持插件扩展元素(ECharts、二维码、Fabric等)。 --- # sv-print 可视化打印设计器组件。基于 Svelte 构建,支持 Vue、React、Angular、jQuery 等框架引入。 ## 快速开始 ### 安装 ```bash # Svelte/Vanilla JS npm i sv-print # React npm i @sv-print/react # Vue2 npm i @sv-print/vue # Vue3 npm i @sv-print/vue3 # 核心库 npm i @sv-print/hiprint ``` ### 引入样式 在 main.ts 或 main.js 文件中引入组件样式 ```js import 'sv-print/dist/style.css'; ``` ### 引入打印样式 需要复制 `node_modules/@sv-print/hiprint/dist/print-lock.css` 到开发资源目录。
例如: Vue 项目的 `public` 目录。
假如你部署的网站是: `https://www.abcd.com/index.html` 那么确保 `https://www.abcd.com/print-lock.css` 能够正常访问。 在 `index.html` 中添加打印样式: ```html ``` ### 基本使用 ```vue ``` ## 核心概念 ### 模板 JSON 模板数据格式包含 `panels` 数组,每个面板支持: - `width/height`: 面板尺寸(单位 mm) - `printElements`: 打印元素列表 - `paperHeader/paperFooter`: 页眉/页脚线 - `paperNumberLeft/paperNumberTop`: 页码位置 - `backgroundColor`: 背景颜色 - `watermarkOptions`: 水印配置 See [template.md](template.md) for details. ### 全局对象 | 对象 | 用途 | | ---------------- | --------------------------------- | | `hiprint` | 创建模板、打印预览、provider 管理 | | `hiwebSocket` | 连接打印客户端 | | `hinnn` | 工具类(单位转换、事件等) | | `HIPRINT_CONFIG` | 全局配置对象 | See [api.md](api.md) for details. ### 设计器组件 Designer 组件支持丰富的参数: - `template`: 模板 JSON 数据 - `printData`: 打印预览数据 - `config`: 配置参数 - `plugins`: 插件列表 - `events`: 事件回调 - `theme`: 主题配置 See [designer.md](designer.md) for details. ### 插件系统 官方插件: - `@sv-print/plugin-ele-bwip-js` - 二维码/条形码 - `@sv-print/plugin-ele-echarts` - ECharts 图表 - `@sv-print/plugin-ele-fabric` - Fabric 绘制 - `@sv-print/plugin-ele-e2table` - Excel 表格 - `@sv-print/plugin-text-auto` - 文本自适应 - `@sv-print/plugin-formatter` - 数据格式化 See [plugins.md](plugins.md) for details. ## 常见场景 ### 浏览器打印 ```js const printTemplate = new hiprint.PrintTemplate({ template: json }); const printData = { name: 'i不简' }; await printTemplate.print(printData); // 批量打印 await printTemplate.print([printData, printData, printData]); ``` ### 静默打印(需要打印客户端) ```js const res = await printTemplate.print2(printData, { printer: '打印机名称', pageSize: { width: 210 * 1000, height: 297 * 1000 }, copies: 2, landscape: false, color: true, }); ``` ### 获取预览 HTML ```js const html = (await printTemplate.getHtml(printData)).html(); ``` ## 导出 ### 导出 PDF(需插件) ```js import pluginApiPdf from '@sv-print/plugin-api-pdf3'; import { hiprint } from 'sv-print'; // 注册插件 hiprint.register({ plugins: [pluginApiPdf({})], }); // 导出 PDF const printTemplate = new hiprint.PrintTemplate({ template: json }); const printData = { name: '测试数据' }; // 方式一:直接下载 await printTemplate.toPdf(printData, '文件名称'); // 方式二:获取 Blob 对象 const res = await printTemplate.toPdf(printData, { name: 'pdf名称', isDownload: false, // 不自动下载,返回结果对象 type: 'blob', // 输出类型: blob | bloburl | dataurl | pdfobjectnewwindow onProgress: (cur, total) => { console.log('进度', Math.floor((cur / total) * 100) + '%'); }, }); console.log('PDF Blob:', res); // 方式三:小模板填充到指定纸张大小 // 适用于:模板中 panelLayoutOptions.layoutRowGap > 0 或 layoutColumnGap > 0 // 且 printData 为数组时,小模板会自动填充到指定纸张大小 await printTemplate.toPdf(printDataArray, '发货单', { paperWidth: 210, // 纸张宽度 (mm) paperHeight: 297, // 纸张高度 (mm) }); ``` **toPdf 参数说明:** | 参数 | 类型 | 默认值 | 说明 | | ----------- | -------- | ------- | ---------------------------------------------------- | | name | string | 'print' | 下载文件名 | | isDownload | boolean | true | 是否自动下载 | | type | string | 'blob' | 输出类型: blob, bloburl, dataurl, pdfobjectnewwindow | | paperWidth | number | - | 纸张宽度 (mm),小模板填充时有效 | | paperHeight | number | - | 纸张高度 (mm),小模板填充时有效 | | onProgress | function | - | 进度回调 (cur, total) | ### 导出图片(需插件) ```js import pluginApiImage from '@sv-print/plugin-api-image'; import { hiprint } from 'sv-print'; // 注册插件 hiprint.register({ plugins: [pluginApiImage({})], }); // 导出图片 const printTemplate = new hiprint.PrintTemplate({ template: json }); const printData = { name: '测试数据' }; // 方式一:直接下载 await printTemplate.toImage(printData, '图片名称'); // 方式二:获取 URL 或 Blob const res = await printTemplate.toImage(printData, { name: '图片名称', isDownload: false, // 不自动下载 type: 'image/jpeg', // 图片类型: image/jpeg | image/png quality: 0.92, // 图片质量 0-1 toType: 'url', // 返回类型: url | blob limit: 10, // 多少页为一个图片文件 onProgress: (cur, total) => { console.log('进度', Math.floor((cur / total) * 100) + '%'); }, }); console.log('图片URL:', res); // 方式三:小模板填充到指定纸张大小 await printTemplate.toImage(printDataArray, '发货单', { paperWidth: 210, // 纸张宽度 (mm) paperHeight: 297, // 纸张高度 (mm) }); ``` **toImage 参数说明:** | 参数 | 类型 | 默认值 | 说明 | | ----------- | -------- | ------------ | ------------------------------- | | name | string | 'print' | 下载文件名 | | isDownload | boolean | true | 是否自动下载 | | type | string | 'image/jpeg' | 图片类型: image/jpeg, image/png | | quality | number | 0.92 | 图片质量 0-1 | | toType | string | 'url' | 返回类型: url, blob | | limit | number | 10 | 多少页为一个图片文件 | | paperWidth | number | - | 纸张宽度 (mm),小模板填充时有效 | | paperHeight | number | - | 纸张高度 (mm),小模板填充时有效 | | onProgress | function | - | 进度回调 (cur, total) | ### 小模板填充说明 当需要将多个小模板(如名片、标签等)填充到一张大纸(如 A4)时使用: ```js // 模板 JSON:配置行列间距 const templateJson = { panels: [ { index: 0, name: '小模板', height: 50, // 小模板高度 (mm) width: 90, // 小模板宽度 (mm) panelLayoutOptions: { layoutType: 'row', // 行列布局类型: row, column layoutRowGap: 10, // 行间距 (mm) layoutColumnGap: 8, // 列间距 (mm) }, printElements: [ // 元素配置 ], }, ], }; // 打印数据:数组格式 const printDataArray = [ { name: '张三', phone: '13800138000' }, { name: '李四', phone: '13900139000' }, { name: '王五', phone: '13700137000' }, // 更多数据... ]; // 导出到 A4 纸 await printTemplate.toPdf(printDataArray, '批量名片', { paperWidth: 210, // A4 宽度 (mm) paperHeight: 297, // A4 高度 (mm) }); ``` ### 完整导出示例 ```vue ``` ## 实际业务场景示例 ### 场景一:自定义 Header 标题和菜单(保存到服务器) ```vue ``` ### 场景二:隐藏默认菜单,只保留自定义保存按钮 ```vue ``` ### 场景三:根据 ID 从服务端加载模板并预览 ```vue ``` ### 场景四:切换主题和语言 ```vue ``` ### 场景五:自定义可拖拽元素 ```vue ``` ### 场景六:表格元素使用 ```js // 表格元素模板 const tableTemplate = { panels: [ { index: 0, name: '面板0', height: 297, width: 210, printElements: [ { options: { left: 60, top: 60, height: 100, width: 500, field: 'table', columnFields: [ { text: 'ID', field: 'id' }, { text: '姓名', field: 'name' }, { text: '数量', field: 'count' }, ], columns: [ [ { width: 100, title: 'ID', field: 'id', checked: true }, { width: 150, title: '姓名', field: 'name', checked: true }, { width: 100, title: '数量', field: 'count', checked: true }, ], ], }, printElementType: { title: '表格', type: 'table', editable: true, columnResizable: true, isEnableInsertRow: true, isEnableDeleteRow: true, }, }, ], }, ], }; // 打印数据 const printData = { table: [ { id: 1, name: '商品A', count: 100 }, { id: 2, name: '商品B', count: 200 }, { id: 3, name: '商品C', count: 300 }, ], }; ``` ### 场景七:二维码/条形码元素 **方式一:使用文本元素(无需插件)** 通过 `text` 元素设置 `textType` 属性实现二维码或条形码: ```js // 二维码模板 const qrcodeTemplate = { panels: [ { index: 0, name: '面板0', height: 297, width: 210, printElements: [ { options: { left: 100, top: 60, height: 50, width: 50, title: '123456789', // 显示内容 textType: 'qrcode', // 设置为二维码 color: '#000000', }, printElementType: { title: '文本', type: 'text', }, }, ], }, ], }; // 条形码模板 const barcodeTemplate = { panels: [ { index: 0, name: '面板0', height: 297, width: 210, printElements: [ { options: { left: 100, top: 60, height: 40, width: 150, title: '123456789', textType: 'barcode', // 设置为条形码 color: '#000000', }, printElementType: { title: '文本', type: 'text', }, }, ], }, ], }; ``` **方式二:使用插件扩展的新元素类型(推荐)** 引入 `@sv-print/plugin-ele-bwip-js` 插件后,会新增 `barcode` 和 `qrcode` 元素类型: ```vue ``` ### 场景八:接收外部保存信号触发设计器保存 ```vue ``` ### 场景九:设置默认纸张和尺寸 ```vue ``` ### 场景十:禁用/调整 UI 组件 通过 `styleOption`、`showOption`、`rulerStyle` 可以隐藏或调整各个小组件的位置: ```vue ``` **styleOption 可配置项说明:** | 组件 | 说明 | 可配置项 | | ---------------- | ---------- | ----------------------- | | panels | 多面板区域 | mode | | draggableEls | 可拖拽元素 | show, mode, style, html | | options | 属性面板 | show, mode, style, html | | pageStructure | 页面结构 | show, mode, style, html | | locationExchange | 位置交换 | show, mode, style, html | | miniMap | 小地图 | show, mode, style, html | | history | 历史记录 | show, mode, style, html | | editableTools | 编辑工具 | show, mode, style | | zIndexTools | 层级工具 | show, mode, style | | fontTools | 字体工具 | show, mode, style | | zoomTools | 缩放工具 | show, mode, style | | rotateTools | 旋转工具 | show, mode, style | **mode 取值说明:** - `default` - 默认位置 - `top` - 固定在顶部 - `bottom` - 固定在底部 - `left` - 固定在左侧 - `right` - 固定在右侧 - `fixed` - 自由拖拽(需配合 style 设置初始位置)