@printstack/print-studio 0.1.1 → 0.1.2
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 +121 -160
- package/assets/render.worker-DkH7TepL.js +109 -0
- package/{cloneDeep-PCw2ErRl.js → cloneDeep-waBDTGc3.js} +9 -4
- package/components/print-s-logo/print-s-logo.vue.d.ts +1 -1
- package/components/s-form/types.d.ts +1 -1
- package/core/coordinate-space.d.ts +16 -0
- package/core/document-model.d.ts +1 -1
- package/core/element-registry.d.ts +3 -8
- package/core/page-extensions.d.ts +1 -1
- package/core/types.d.ts +8 -0
- package/core.js +2 -2
- package/designer/commands/menu-adapter.d.ts +3 -3
- package/designer/commands/menu-types.d.ts +8 -1
- package/designer/commands/types.d.ts +2 -0
- package/designer/components/fields/use-table-draft.d.ts +0 -4
- package/designer/components/panels/layer-row-types.d.ts +37 -0
- package/designer/components/panels/layer-row.vue.d.ts +17 -0
- package/designer/components/stage/marquee-overlay.vue.d.ts +8 -0
- package/designer/components/stage/node-style.d.ts +3 -0
- package/designer/components/stage/selection-member.vue.d.ts +14 -0
- package/designer/composables/use-theme.d.ts +3 -0
- package/designer/facade/editing.d.ts +2 -2
- package/designer/facade/entities.d.ts +1156 -22
- package/designer/frame/view.d.ts +2 -0
- package/designer/interactions/marquee.d.ts +1 -1
- package/designer/interactions/move.d.ts +3 -1
- package/designer/mount-print-designer.d.ts +1 -1
- package/designer/plugins/plugin-manager.d.ts +3 -3
- package/designer/plugins/types.d.ts +1 -1
- package/designer/stores/document-store.d.ts +72 -0
- package/designer/stores/editor-store.d.ts +770 -14
- package/designer/stores/page-store.d.ts +25 -1
- package/designer/stores/template-store.d.ts +52 -4
- package/designer/stores/types.d.ts +1 -0
- package/designer/stores/ui-store.d.ts +232 -3
- package/designer/stores/view-store.d.ts +10 -1
- package/designer.d.ts +1 -1
- package/designer.js +3 -3
- package/{document-model-GhFP9OGp.js → document-model-Cc5RoO4j.js} +160 -179
- package/elements/table/table-style.d.ts +3 -10
- package/host-OAp3gFDx.js +123 -0
- package/index.js +5 -5
- package/locales/runtime.d.ts +7 -2
- package/locales/translations/zh-CN/designer.json.d.ts +9 -4
- package/{mount-print-designer-BLgVZOnm.js → mount-print-designer-DnHTrBE9.js} +4 -4
- package/{mount-print-preview-D7M-1AqH.js → mount-print-preview-Bcb08lJ-.js} +4 -3
- package/package.json +1 -1
- package/{presets-D3WhkbZK.js → presets-BunYODhE.js} +2 -2
- package/{registries-dZq8MewR.js → registries-sg39PGF1.js} +767 -780
- package/runtime.js +2 -2
- package/{saas-B1H161e1.js → saas-D-q51uTz.js} +1 -1
- package/saas.js +1 -1
- package/{studio-BFQYHZsg.js → studio-B3B6zI06.js} +796 -722
- package/studio-types.d.ts +1 -1
- package/style.css +1 -1
- package/vue.js +786 -693
- package/assets/render.worker-Ch4qWx3S.js +0 -109
- package/host-CuGR8rD6.js +0 -123
package/README.md
CHANGED
|
@@ -6,238 +6,199 @@
|
|
|
6
6
|
- **数据绑定**:字符串属性 `{{ 路径 | 格式化器 }}` 注入业务数据,表格跨页续排、循环区块展开明细。
|
|
7
7
|
- **输出**:浏览器预览与打印、独立 HTML、PDF Blob。全部在浏览器内完成,无服务端依赖,打印数据由调用方传入。
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
> **完整文档(API 参考、教程、示例、演练场)请访问 [https://print-studio-docs.github.io](https://print-studio-docs.github.io)**。
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## 安装
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
npm install @printstack/print-studio
|
|
15
|
+
```
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
```bash
|
|
17
18
|
pnpm add @printstack/print-studio
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```bash
|
|
18
22
|
yarn add @printstack/print-studio
|
|
19
23
|
```
|
|
20
24
|
|
|
21
|
-
###
|
|
25
|
+
### 环境要求与兼容范围
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
| `@printstack/print-studio/runtime` | `createPrintRenderer()` 纯输出运行时 |
|
|
29
|
-
| `@printstack/print-studio/core` | 文档模型与工具(`deserializeDocument()` 等) |
|
|
27
|
+
- **浏览器**:Chrome / Edge / Firefox / Safari 现代版本;系统打印行为由浏览器决定,建议按目标浏览器实际验收。
|
|
28
|
+
- **模块格式**:纯 ESM 包,不提供 CommonJS 接入。Vue、Pinia 等运行时依赖随包自动安装,非 Vue 项目无需编写 Vue 组件;样式已随隔离 iframe 内联加载,无需手动导入。
|
|
29
|
+
- **Node.js / SSR**:模板渲染依赖浏览器 DOM / Canvas,不在服务端直接运行;服务端输出需以无头浏览器等宿主承载。
|
|
30
|
+
- **PDF / 图片 / 字体**:浏览器资源加载与跨域策略参与输出结果,需用实际资源验证。
|
|
31
|
+
- **移动端**:可打开文档;设计器需要足够的容器宽高。
|
|
30
32
|
|
|
31
|
-
##
|
|
33
|
+
## 选择接入方式
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
按业务场景二选一,两种方式可同时使用:
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
| 接入方式 | 适用场景 | 需要的能力 |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| **嵌入设计器** | 让用户在系统内可视化设计、维护模板 | `PrintDesigner` 组件(Vue)或 `studio.mount()`(任意技术栈) |
|
|
40
|
+
| **仅输出,不嵌设计器** | 只在业务页面用已有模板渲染数据、预览打印 | 仅 `createPrintStudio()`,不调用 `mount()`;或更轻量的 `createPrintRenderer()` |
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
不嵌入设计器时,设计器视图与相关插件代码不会加载(视图运行时按需加载)。
|
|
43
|
+
|
|
44
|
+
### 方式一:嵌入设计器(Vue 应用)
|
|
39
45
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
```vue
|
|
47
|
+
<script setup lang="ts">
|
|
48
|
+
import { PrintDesigner, usePrintStudio } from '@printstack/print-studio/vue'
|
|
49
|
+
|
|
50
|
+
const studio = usePrintStudio({
|
|
51
|
+
storage: false, // 关闭自动草稿,见下文「配置偏好与草稿」
|
|
52
|
+
onSave: async (document) => {
|
|
45
53
|
await fetch('/api/templates', {
|
|
46
54
|
method: 'POST',
|
|
47
55
|
body: JSON.stringify(document),
|
|
48
56
|
})
|
|
49
57
|
},
|
|
50
58
|
})
|
|
51
|
-
|
|
52
|
-
// 2. 挂载设计器界面;resolve 即界面就绪
|
|
53
|
-
await studio.mount({ el: '#designer' })
|
|
54
|
-
|
|
55
|
-
// 3. 编辑模板:代码与设计器界面操作同一份文档
|
|
56
|
-
const page = studio.page.active
|
|
57
|
-
const cell = page.elements.add({
|
|
58
|
-
type: 'text',
|
|
59
|
-
x: 20,
|
|
60
|
-
y: 30,
|
|
61
|
-
width: 100,
|
|
62
|
-
height: 12,
|
|
63
|
-
})
|
|
64
|
-
page.elements.updateProps(cell, { text: '订单号:{{ order.number }}' })
|
|
65
|
-
|
|
66
|
-
// 4. 页面退出时释放工作区
|
|
67
|
-
// studio.unmount() // 仅卸载界面,文档保留,可再次 mount
|
|
68
|
-
// studio.dispose() // 彻底释放
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
要点:
|
|
72
|
-
|
|
73
|
-
- `el` 接受元素或 CSS 选择器,**容器需要有明确高度**,设计器界面填满其容器。
|
|
74
|
-
- 界面配置(`ui` / `settings` / `plugins` / `zIndex`)与回调(`onDirtyChange` / `onError`)作为 `mount()` 选项传入,工作区创建选项仍在 `createPrintStudio()` 中配置。
|
|
75
|
-
- 不传 `initialDocument` 时默认打开内置欢迎模板,可直接试用;业务模板通过 `initialDocument` 或 `studio.document.loadJson(json)` 加载。
|
|
76
|
-
- 一个工作区同时只挂载一个设计器;`mount()` 失败或就绪前卸载会 reject,调用方应捕获并 `dispose()` 工作区。
|
|
77
|
-
|
|
78
|
-
Vue 项目也可以使用组件方式。`usePrintStudio()` 在 setup 中创建同一工作区,页面卸载时自动清理:
|
|
79
|
-
|
|
80
|
-
```vue
|
|
81
|
-
<script setup lang="ts">
|
|
82
|
-
import { PrintDesigner, usePrintStudio } from '@printstack/print-studio/vue'
|
|
83
|
-
|
|
84
|
-
const studio = usePrintStudio({ storage: false })
|
|
85
59
|
</script>
|
|
86
60
|
|
|
87
61
|
<template>
|
|
88
|
-
|
|
62
|
+
<!-- 容器需要有明确高度 -->
|
|
63
|
+
<div style="height: 80vh">
|
|
89
64
|
<PrintDesigner :studio="studio" />
|
|
90
65
|
</div>
|
|
91
66
|
</template>
|
|
92
67
|
```
|
|
93
68
|
|
|
94
|
-
|
|
69
|
+
要点:
|
|
70
|
+
|
|
71
|
+
- `usePrintStudio()` 在 setup 作用域中创建实例,页面卸载时自动 `dispose()`;组件与界面操作同一份文档。
|
|
72
|
+
- 通过 `studio.mount()` 也可把设计器挂载到任意容器(支持元素或 CSS 选择器),一个工作区同时只挂载一个设计器,可用 `unmount()` 移除后重新挂载。非 Vue 技术栈用这种方式。
|
|
95
73
|
|
|
96
|
-
|
|
74
|
+
### 方式二:不嵌设计器,只做输出
|
|
97
75
|
|
|
98
76
|
```ts
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
// 全屏预览层展示,用户自行关闭
|
|
102
|
-
await studio.preview(input)
|
|
77
|
+
import { createPrintStudio } from '@printstack/print-studio'
|
|
103
78
|
|
|
104
|
-
|
|
105
|
-
const handle = await studio.preview(input)
|
|
106
|
-
handle.close()
|
|
79
|
+
const studio = createPrintStudio()
|
|
107
80
|
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
container: document.querySelector('#preview-box')!,
|
|
111
|
-
})
|
|
81
|
+
// 加载系统已有模板数据(不挂载设计器)
|
|
82
|
+
studio.document.loadJson(templateJson)
|
|
112
83
|
|
|
113
|
-
//
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
designerPreview.close()
|
|
84
|
+
// 业务数据渲染 + 输出
|
|
85
|
+
await studio.print({ orderNo: 'A001' })
|
|
86
|
+
const { blob } = await studio.toPDF({ orderNo: 'A001' })
|
|
117
87
|
```
|
|
118
88
|
|
|
119
|
-
|
|
89
|
+
不需要界面时直接用 `createPrintStudio()`,即可完成加载模板、注入数据、预览、打印、导出。不需要任何编辑 UI 时,可用更轻量的纯输出运行时 `createPrintRenderer()`,详见 [createPrintRenderer() 参考](https://print-studio-docs.github.io/reference/renderer)。
|
|
120
90
|
|
|
121
|
-
|
|
91
|
+
## 模板保存到自己的系统
|
|
122
92
|
|
|
123
|
-
`
|
|
93
|
+
模板在设计器中就是一份 JSON 文档(`PrintDocument`),接入点是 `onSave` 回调:
|
|
124
94
|
|
|
125
95
|
```ts
|
|
126
|
-
const
|
|
96
|
+
const studio = usePrintStudio({
|
|
97
|
+
onSave: async (document) => {
|
|
98
|
+
// document 为完整模板 JSON,存到你的数据库 / 接口
|
|
99
|
+
await saveToMySystem(templateId, JSON.stringify(document))
|
|
100
|
+
},
|
|
101
|
+
})
|
|
127
102
|
```
|
|
128
103
|
|
|
129
|
-
|
|
104
|
+
- 触发途径:界面「保存」按钮、文件菜单的保存命令,或代码调用 `studio.document.save()`。`save()` 返回只表示回调执行完成。
|
|
105
|
+
- 若未提供 `onSave`,界面保存能力不可用(`studio.document.dirty` 仍正常)。
|
|
106
|
+
- 程序化获取当前文档:`studio.document.data`;导出 JSON 字符串:`studio.export.json()`。
|
|
107
|
+
- 文档有未保存修改时 `studio.document.dirty` 为 `true`,可用于自己的保存提示;挂载方式可另传 `onDirtyChange` 监听脏状态。
|
|
130
108
|
|
|
131
|
-
|
|
132
|
-
|
|
109
|
+
## 加载系统已有模板
|
|
110
|
+
|
|
111
|
+
两种途径:
|
|
112
|
+
|
|
113
|
+
**代码加载**(嵌入与非嵌入方式都适用):
|
|
133
114
|
|
|
134
115
|
```ts
|
|
135
|
-
|
|
136
|
-
|
|
116
|
+
// 字符串 JSON
|
|
117
|
+
studio.document.loadJson(json)
|
|
118
|
+
// 对象
|
|
119
|
+
studio.document.load(document)
|
|
137
120
|
```
|
|
138
121
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
`studio.toHTML(input)` 生成独立 HTML 字符串,`studio.toPDF(input)` 生成 PDF Blob,交给宿主下载或上传:
|
|
122
|
+
创建实例时直接带入初始模板:
|
|
142
123
|
|
|
143
124
|
```ts
|
|
144
|
-
|
|
145
|
-
const { html } = await studio.toHTML(input)
|
|
146
|
-
|
|
147
|
-
// PDF:返回 { blob, warnings };以下载为例
|
|
148
|
-
const { blob } = await studio.toPDF(input)
|
|
149
|
-
const url = URL.createObjectURL(blob)
|
|
150
|
-
const link = document.createElement('a')
|
|
151
|
-
link.href = url
|
|
152
|
-
link.download = 'order.pdf'
|
|
153
|
-
link.click()
|
|
154
|
-
URL.revokeObjectURL(url)
|
|
125
|
+
const studio = usePrintStudio({ initialDocument: myTemplate })
|
|
155
126
|
```
|
|
156
127
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
以 ERP 订单打印为例。典型接入方式:模板在设计器中定稿后以 JSON 保存到业务系统;业务页面调用打印服务,加载模板、注入订单数据,提供预览与打印:
|
|
128
|
+
**接入模板库**(让用户在设计器「文件 > 模板库」中浏览、选用、上传、维护系统模板):
|
|
160
129
|
|
|
161
130
|
```ts
|
|
162
|
-
|
|
163
|
-
import {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
await getStudio().preview({ order })
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/** 点击「打印」:浏览器打印对话框中确认 */
|
|
190
|
-
export async function printOrder(order: Order): Promise<void> {
|
|
191
|
-
await loadOrderTemplate()
|
|
192
|
-
await getStudio().print({ order })
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/** 点击「导出 PDF」:拿到 Blob 后下载或上传 */
|
|
196
|
-
export async function exportOrderPdf(order: Order): Promise<Blob> {
|
|
197
|
-
await loadOrderTemplate()
|
|
198
|
-
const { blob } = await getStudio().toPDF({ order })
|
|
199
|
-
return blob
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/** 应用退出时释放 */
|
|
203
|
-
export function destroyPrintService(): void {
|
|
204
|
-
studio?.dispose()
|
|
205
|
-
studio = undefined
|
|
206
|
-
}
|
|
131
|
+
import { definePlugin } from '@printstack/print-studio'
|
|
132
|
+
import { createRemoteTemplateProvider } from '@printstack/print-studio/designer'
|
|
133
|
+
|
|
134
|
+
const myTemplateLibrary = definePlugin({
|
|
135
|
+
manifest: {
|
|
136
|
+
apiVersion: '1.0',
|
|
137
|
+
id: 'my-company:templates',
|
|
138
|
+
version: '1.0.0',
|
|
139
|
+
permissions: ['templates'],
|
|
140
|
+
},
|
|
141
|
+
setup(ctx) {
|
|
142
|
+
return ctx.templateLibrary.register(
|
|
143
|
+
createRemoteTemplateProvider({
|
|
144
|
+
id: 'my-company:remote',
|
|
145
|
+
manifestUrl: '/api/templates/manifest',
|
|
146
|
+
title: () => '系统模板',
|
|
147
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
148
|
+
}),
|
|
149
|
+
)
|
|
150
|
+
},
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
const studio = usePrintStudio()
|
|
154
|
+
studio.use(myTemplateLibrary)
|
|
207
155
|
```
|
|
208
156
|
|
|
209
|
-
|
|
157
|
+
- Provider 支持 `create` / `update` / `remove` 时,用户可在模板库中把当前文档存入你的系统、更新或删除已有模板。
|
|
158
|
+
- 不需要模板库时也可用 `studio.template.import()` 程序化导入模板对象。
|
|
159
|
+
|
|
160
|
+
## 配置偏好与草稿
|
|
161
|
+
|
|
162
|
+
两类自动持久化默认都写入 `localStorage`,均有开关和自定义存储接口:
|
|
163
|
+
|
|
164
|
+
| 配置项 | 默认行为 | 关闭 | 自定义存储 |
|
|
165
|
+
| --- | --- | --- | --- |
|
|
166
|
+
| **草稿(未保存的模板数据)** | 修改自动写入 `localStorage`(键 `print-studio:document`),下次打开自动恢复 | `storage: false` | `storage: { get(): string \| null, set(json) }`,实现 `DocumentStorage` 接口 |
|
|
167
|
+
| **偏好设置(主题等界面偏好)** | 变更时写入 `localStorage` | `persistPreferences: false` | `preferenceStorage: { get(key), set(key, value) }`,实现 `PreferenceStorage` 接口 |
|
|
168
|
+
|
|
169
|
+
典型配置:宿主系统统一管理模板,关闭本地草稿,只信任 `onSave`:
|
|
210
170
|
|
|
211
171
|
```ts
|
|
212
|
-
|
|
172
|
+
usePrintStudio({ storage: false, onSave })
|
|
213
173
|
```
|
|
214
174
|
|
|
215
|
-
|
|
175
|
+
需要把草稿/偏好存到服务端或 IndexedDB 时,实现对应接口传入即可。
|
|
216
176
|
|
|
217
|
-
|
|
218
|
-
import { createPrintRenderer } from '@printstack/print-studio/runtime'
|
|
219
|
-
import { deserializeDocument } from '@printstack/print-studio/core'
|
|
177
|
+
## 在业务场景中预览与打印
|
|
220
178
|
|
|
221
|
-
|
|
179
|
+
拿到模板和业务数据后,输出入口都接受 `input`(数据源值,键需与模板中的数据绑定一致):
|
|
222
180
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
)
|
|
181
|
+
```ts
|
|
182
|
+
// 预览:打开成品视图,返回句柄,用完 dispose()
|
|
183
|
+
const handle = await studio.preview({ orderNo: 'A001' })
|
|
184
|
+
handle.dispose()
|
|
227
185
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
await renderer.print(template, input)
|
|
186
|
+
// 打印:提交浏览器打印任务;resolve 表示任务已提交,不代表用户确认或设备出纸
|
|
187
|
+
await studio.print({ orderNo: 'A001' })
|
|
231
188
|
|
|
232
|
-
|
|
189
|
+
// 导出
|
|
190
|
+
const { blob } = await studio.toPDF({ orderNo: 'A001' })
|
|
191
|
+
const { html } = await studio.toHTML({ orderNo: 'A001' })
|
|
233
192
|
```
|
|
234
193
|
|
|
194
|
+
批量打印、PDF 批量导出等进阶输出见教程 [批量打印与批量导出](https://print-studio-docs.github.io/tutorial/batch)。
|
|
195
|
+
|
|
235
196
|
## 更多功能与完整文档
|
|
236
197
|
|
|
237
198
|
> 更多高级功能、详细配置说明及完整 API 文档,请访问 [Print Studio 官方文档](https://print-studio-docs.github.io)。
|
|
238
199
|
|
|
239
|
-
- [快速开始](https://print-studio-docs.github.io/guide/getting-started):从创建项目到预览、打印的完整流程
|
|
240
200
|
- [循序渐进教程](https://print-studio-docs.github.io/tutorial/):模板设计、页面尺寸、元素绘制、数据绑定、保存加载、批量打印
|
|
201
|
+
- [API 参考](https://print-studio-docs.github.io/reference/studio):`createPrintStudio()` 与工作区 API
|
|
241
202
|
- [数据绑定参考](https://print-studio-docs.github.io/reference/data-binding):数据源声明、表达式与格式化器
|
|
242
203
|
- [预览 / 打印 / 导出 API](https://print-studio-docs.github.io/reference/output):输出选项、取消与超时、批量输出
|
|
243
204
|
- [Vue 集成](https://print-studio-docs.github.io/reference/vue-designer):组件 props、事件与上下文
|