---
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 设置初始位置)