diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..c2466a3c
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,102 @@
+{
+ "name": "cloud-ui-materials",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "cloud-ui-materials",
+ "dependencies": {
+ "dom-to-image": "^2.6.0",
+ "lodash.mergewith": "^4.6.2",
+ "node-fetch": "2"
+ }
+ },
+ "node_modules/dom-to-image": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/dom-to-image/-/dom-to-image-2.6.0.tgz",
+ "integrity": "sha512-Dt0QdaHmLpjURjU7Tnu3AgYSF2LuOmksSGsUcE6ItvJoCWTBEmiMXcqBdNSAm9+QbbwD7JMoVsuuKX6ZVQv1qA=="
+ },
+ "node_modules/lodash.mergewith": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
+ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ }
+ },
+ "dependencies": {
+ "dom-to-image": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/dom-to-image/-/dom-to-image-2.6.0.tgz",
+ "integrity": "sha512-Dt0QdaHmLpjURjU7Tnu3AgYSF2LuOmksSGsUcE6ItvJoCWTBEmiMXcqBdNSAm9+QbbwD7JMoVsuuKX6ZVQv1qA=="
+ },
+ "lodash.mergewith": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
+ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="
+ },
+ "node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "requires": {
+ "whatwg-url": "^5.0.0"
+ }
+ },
+ "tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "requires": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index d091a546..50c62861 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,8 @@
"changelog:comment": "node scripts/changelog.js from-comment"
},
"dependencies": {
+ "dom-to-image": "^2.6.0",
"lodash.mergewith": "^4.6.2",
"node-fetch": "2"
}
-}
\ No newline at end of file
+}
diff --git a/packages/cw/print_block_sdk/components/cw-print-designer/api.yaml b/packages/cw/print_block_sdk/components/cw-print-designer/api.yaml
new file mode 100644
index 00000000..2299c6a2
--- /dev/null
+++ b/packages/cw/print_block_sdk/components/cw-print-designer/api.yaml
@@ -0,0 +1,116 @@
+- name: cw-print-designer
+ title: 分页打印组件
+ type: both
+ belong: component
+ labels: [Runtime]
+ attrs:
+ - name: isShowPrint
+ title: 是否展示打印区域
+ type: boolean
+ default: false
+ description: 是否显示打印区域
+ - name: paperSize
+ type: string
+ default: a4
+ title: 打印尺寸
+ options:
+ - value: a3
+ title: A3
+ - value: a4
+ title: A4
+ - value: a5
+ title: A5
+ - value: b3
+ title: B3
+ - value: b4
+ title: B4
+ - value: b5
+ title: B5
+ - value: custom
+ title: 自定义
+ description: 请选择打印纸张尺寸
+ - name: pageWidth
+ title: 纸张宽度
+ type: number
+ default: 794
+ dependency:
+ - paperSize: custom
+ - name: pageHeight
+ title: 纸张高度
+ type: number
+ default: 794
+ dependency:
+ - paperSize: custom
+ - name: pageDirection
+ type: string
+ default: v
+ title: 打印出纸方向
+ options:
+ - value: v
+ title: 纵向
+ - value: h
+ title: 横向
+ description: 请选择打印页面方向
+ - name: isRate
+ type: boolean
+ default: false
+ title: 是否按比例缩放打印
+ description: 开启等比例缩放,画布宽度跟所内容自动变宽
+ - name: showHeader
+ type: boolean
+ default: false
+ title: 是否显示页眉区域
+ description: 是否显示页眉区域
+ - name: showFooter
+ type: boolean
+ default: false
+ title: 是否显示页尾区域
+ description: 设置页脚区域高度,单位mm
+ - name: yBorder
+ type: number
+ default: 0
+ title: 垂直页边距
+ description: 设置垂直页边距,单位mm
+ - name: xBorder
+ type: number
+ default: 0
+ title: 水平页边距
+ description: 设置水平页边距,单位mm
+ slots:
+ - concept: Slot
+ name: content
+ title: 打印内容插槽
+ description: 打印内容插槽
+ - concept: Slot
+ name: header
+ title: 页眉插槽
+ description: 页眉插槽
+ - concept: Slot
+ name: footer
+ title: 页脚插槽
+ description: 页脚插槽
+ methods:
+ - name: print
+ title: 打印
+ description: 打印
+ params:
+ - name: pagerInHeader
+ type: string
+ description: 页眉页码
+ required: false
+ - name: pagerSizeInHeader
+ type: string
+ description: 页眉页码大小
+ required: false
+ - name: pagerSizeInFooter
+ type: string
+ description: 页脚页码大小
+ required: false
+ - name: pagerInFooter
+ type: string
+ description: 页脚页码
+ required: false
+ - name: itemElement
+ type: string
+ description: 避免分页的元素名
+ required: false
\ No newline at end of file
diff --git a/packages/cw/print_block_sdk/components/cw-print-designer/docs/blocks.md b/packages/cw/print_block_sdk/components/cw-print-designer/docs/blocks.md
new file mode 100644
index 00000000..df20c87a
--- /dev/null
+++ b/packages/cw/print_block_sdk/components/cw-print-designer/docs/blocks.md
@@ -0,0 +1,5 @@
+### 基本用法
+
+``` html
+
+```
diff --git a/packages/cw/print_block_sdk/components/cw-print-designer/docs/examples.md b/packages/cw/print_block_sdk/components/cw-print-designer/docs/examples.md
new file mode 100644
index 00000000..f6fbb7c1
--- /dev/null
+++ b/packages/cw/print_block_sdk/components/cw-print-designer/docs/examples.md
@@ -0,0 +1,32 @@
+### 基本用法
+
+``` vue
+
+
+
打印
+
+
+
+ Here might be a page title
+
+
+
统计日期:
打印日期:2024-03-12
制表人:
序号
日期
餐厅
消费次数
消费金额
撤单次数
撤单金额
实际消费金额
+
+
+ Here might be a page footer
+
+
+
+
+
+
+
+```
diff --git a/packages/cw/print_block_sdk/components/cw-print-designer/html2print.js b/packages/cw/print_block_sdk/components/cw-print-designer/html2print.js
new file mode 100644
index 00000000..6d629b75
--- /dev/null
+++ b/packages/cw/print_block_sdk/components/cw-print-designer/html2print.js
@@ -0,0 +1,386 @@
+import jsPDF from "jspdf"
+import html2canvas from 'html2canvas'
+import printJS from "print-js"
+
+/**
+ * 生成print文件
+ * @param {Object} param
+ * @param {HTMLElement} param.element - 需要转换的dom根节点
+ * @param {string} [param.direction='v'] - 纸张方向,h横向,v竖向
+ * @param {number} param.baseX - pdf页内容距页面左边的高度,默认居中显示,为(pager宽度 - contentWidth) / 2)
+ * @param {number} param.baseY - pdf页内容距页面上边的高度,默认 15px
+ * @param {HTMLElement} param.header - 页眉dom元素
+ * @param {HTMLElement} param.footer - 页脚dom元素
+ * @param {string} [param.format='a4'] - pdf格式
+ * @returns {Promise}
+ */
+
+export default class Html2Pdf {
+ constructor(element, param = {}) {
+ if (!(element instanceof HTMLElement)) {
+ throw new TypeError("element配置应为HTMLElement");
+ }
+ console.log("[ param ] >", param);
+
+ this._stores = {};
+
+ this.element = element;
+ // 缩放比例
+ this.contentWidth = param.contentWidth || 550;
+ this.fileName = "导出的pdf文件";
+ this.baseX = param.baseX;
+ this.baseY = param.baseY || 0;
+ this.format = param.format || "a4";
+
+ this.header = param.header;
+ this.footer = param.footer;
+
+ this.contentWidth = param.pagerWidth - 2 * this.baseX;
+ this.contentHeight = param.pagerHeight - 2 * this.baseY;
+
+ this.direction = param.direction || "v"; // 默认竖向,l横向
+ this.pagerWidth = param.pagerWidth;
+ this.pagerHeight = param.pagerHeight;
+ this.itemClass = 'print-view-split';
+
+ // 页眉页脚高度
+ this.pdfFooterHeight = 0;
+ this.pdfHeaderHeight = 0;
+
+ this.pdf = null;
+ this.rate = 1; // 缩放比率
+ this.pages = []; // 当前分页数据
+ this.elementTop = 0; // 根元素距离可视区域高度
+ this.preNode = null; // 记录遍历时候上一个节点
+ this.positionData = {}; // 计算位置保存的对象
+ }
+
+ /**
+ * 将元素转化为canvas元素
+ * @param {HTMLElement} element - 当前要转换的元素
+ * @param {width} width - 内容宽度
+ * @returns
+ */
+ async toCanvas(element, width) {
+ // canvas元素
+ let canvas = await html2canvas(element, {
+ allowTaint: true, // 允许渲染跨域图片
+ scale: 1, // 增加清晰度
+ useCORS: true, // 允许跨域
+ logging: true,
+ ignoreElements: (e) => {
+ if (e.contains(element) || element.contains(e) || e.tagName === 'STYLE' || e.tagName === 'LINK' || e.tagName === 'HEAD') {
+ return false;
+ }
+
+ return true;
+ }
+ });
+ // 获取canvas转化后的宽度
+ const canvasWidth = canvas.width;
+ // 获取canvas转化后的高度
+ const canvasHeight = canvas.height;
+ // 高度转化为PDF的高度
+ const height = (width / canvasWidth) * canvasHeight;
+ // 转化成图片Data
+ const canvasData = canvas.toDataURL("image/jpeg", 1.0);
+ // 释放canvas
+ canvas = null;
+ return { width, height, data: canvasData };
+ }
+
+ /**
+ * 生成打印文件,并调用打印机接口
+ * @returns {Promise} 返回一个promise
+ */
+ async print() {
+ // jsPDF实例
+ const pdf = new jsPDF({
+ unit: "pt", // mm,pt,in,cm
+ format: this.format,
+ orientation: this.pagerWidth > this.pagerHeight ? "l" : "p",
+ });
+
+ this.pdf = pdf;
+ let pdfFooterHeight = 0;
+ let pdfHeaderHeight = 0;
+ // 每一页的分页坐标, PDF高度, 初始值为根元素距离顶部的距离
+ this.elementTop = this.getElementTop(this.element)
+
+ // 元素在网页页面的宽度
+ const elementWidth = this.element.offsetWidth;
+
+ // PDF内容宽度 和 在HTML中宽度 的比, 用于将 元素在网页的高度 转化为 PDF内容内的高度, 将 元素距离网页顶部的高度 转化为 距离Canvas顶部的高度
+ const rate = this.contentWidth / elementWidth;
+ this.rate = rate;
+
+ // 距离PDF 页眉和页脚的间距, 留白留空
+ let baseY = this.baseY;
+ // 距离PDF左边的距离,/ 2 表示居中 ,,预留空间给左边, 右边,也就是左右页边距
+ let baseX = this.baseX;
+
+ // 页脚元素 经过转换后在PDF页面的高度
+ if (this.footer) {
+ pdfFooterHeight = (await this.toCanvas(this.footer, this.contentWidth))
+ .height;
+ this.pdfFooterHeight = pdfFooterHeight;
+ }
+
+ // 页眉元素 经过转换后在PDF的高度
+ if (this.header) {
+ pdfHeaderHeight = (await this.toCanvas(this.header, this.contentWidth))
+ .height;
+ this.pdfHeaderHeight = pdfHeaderHeight;
+ }
+
+ // 一页的高度, 转换宽度为一页元素的宽度
+ const { width, height, data } = await this.toCanvas(
+ this.element,
+ this.contentWidth
+ );
+
+ this.height = height;
+ // 除去页头、页眉、还有内容与两者之间的间距后 每页内容的实际高度
+ const originalPageHeight = this.pagerHeight - pdfFooterHeight - pdfHeaderHeight - 2 * baseY;
+ this.originalPageHeight = originalPageHeight;
+
+ // 每一页的分页坐标, PDF高度, 初始值为根元素距离顶部的距离
+ this.pages = [rate * this.getElementTop(this.element)]; // 要从0开始
+
+ // 深度遍历节点的方法
+ this.traversingNodes(this.element.childNodes);
+ // 对pages进行一个值的修正,因为pages生成是根据根元素来的,根元素并不是我们实际要打印的元素,而是element,
+ // 所以要把它修正,让其值是以真实的打印元素顶部节点为准
+ const newPages = this.pages.map((item) => item - this.pages[0]);
+
+ const pages = this.pages;
+
+ // 根据分页位置 开始分页生成pdf
+ for (let i = 0; i < newPages.length; ++i) {
+ // 页眉高度
+ let pdfHeaderH = pdfHeaderHeight;
+ // 页脚高度
+ let pdfFooterH = pdfFooterHeight;
+
+ // 根据分页位置新增图片,要排除页眉和顶部留白
+ this.addImage(
+ baseX,
+ baseY + pdfHeaderH - newPages[i],
+ pdf,
+ data,
+ width,
+ height
+ );
+ // 将 顶部 与 页眉之间留空留白的部分进行遮白处理
+ this.addBlank(0, 0, this.pagerWidth, baseY, pdf);
+ // 将 页脚 与 底部之间留空留白的部分进行遮白处理
+ this.addBlank(0, this.pagerHeight - baseY, this.pagerWidth, baseY, pdf);
+
+ // 对于除最后一页外,对 内容 的多余部分进行遮白处理
+ if (i < newPages.length - 1) {
+ // 获取当前页面需要的内容部分高度
+ const imageHeight = newPages[i + 1] - newPages[i];
+ // 对多余的内容部分进行遮白
+ this.addBlank(
+ 0,
+ imageHeight + pdfHeaderH + baseY,
+ this.pagerWidth,
+ this.pagerHeight - imageHeight - baseY,
+ pdf
+ );
+ }
+
+ // 添加页眉
+ await this.addHeader(i + 1, this.header, pdf, this.contentWidth);
+
+ // 添加页脚
+ await this.addFooter(
+ pages.length,
+ i + 1,
+ this.footer,
+ pdf,
+ this.contentWidth
+ );
+
+ // 若不是最后一页,则分页
+ if (i !== newPages.length - 1) {
+ // 增加分页
+ pdf.addPage();
+ }
+ }
+
+ try {
+ const result = await this.printFile(pdf);
+ return {
+ positionData: this.positionData,
+ pdfResult: result,
+ };
+ } catch (error) {
+ console.error("生成pdf出错", error);
+ throw new Error(error);
+ }
+ }
+
+ printFile(pdf) {
+ const data = pdf.output("blob");
+ const blobUrl = URL.createObjectURL(data);
+ const result = new File([data], this.fileName, {
+ type: "application/pdf",
+ lastModified: Date.now(),
+ });
+ printJS(blobUrl);
+ return result
+ }
+ /**
+ * 遍历正常的元素节点
+ * @param {HTMLElement} nodes - 当前要遍历的节点数组
+ * @returns
+ */
+ traversingNodes(nodes) {
+ for (const element of nodes) {
+ const one = element;
+ // 深度终点
+ const isItem = one.classList && one.classList.contains(this.itemClass)
+ // 对需要处理分页的元素,计算是否跨界,若跨界,则直接将顶部位置作为分页位置,进行分页,且子元素不需要再进行判断
+ const { offsetHeight = 0 } = one;
+ // 计算出最终高度
+ const offsetTop = this.getElementTop(one);
+
+ // dom转换后距离顶部的高度
+ // 转换成canvas高度
+ const top = this.rate * offsetTop;
+ const rateOffsetHeight = this.rate * offsetHeight;
+
+ if (top && rateOffsetHeight) {
+ if (isItem) {
+ // dom高度转换成生成pdf的实际高度
+ // 代码不考虑dom定位、边距、边框等因素,需在slot里自行考虑,如将box-sizing设置为border-box
+ this.updateTablePos(rateOffsetHeight, top);
+ // one.classList.add("pdf-table-split-tr")
+ } else {
+ // 遍历子节点
+ this.traversingNodes(one.childNodes);
+ this.updateNormalElPos(top, rateOffsetHeight);
+ }
+ }
+ }
+ }
+
+ // 可能跨页元素位置更新的方法
+ // 需要考虑分页元素,则需要考虑两种情况
+ // 1. 普通达顶情况,如上
+ // 2. 当前距离顶部高度加上元素自身高度 大于 整页高度,则需要载入一个分页点
+ updateTablePos(eHeight, top) {
+ // 如果高度已经超过当前页,则证明可以分页了
+ const nowPageTop = this.pages[this.pages.length - 1];
+ if (top - nowPageTop >= this.originalPageHeight) {
+ this.pages.push(
+ nowPageTop + this.originalPageHeight
+ )
+ } else if (top + eHeight - nowPageTop > this.originalPageHeight && top !== nowPageTop) {
+ this.pages.push(top)
+ }
+ }
+ /**
+ * 普通元素更新位置
+ * 普通元素只需要考虑到是否到达了分页点,即当前距离顶部高度 - 上一个分页点的高度 大于 正常一页的高度,则需要载入分页点
+ * @param {Number} top - 当前元素在pdf中距离顶部可视区域高度(经过比例转换)
+ * @returns
+ */
+ updateNormalElPos(top, eleHeight) {
+ const latestPageTop = this.pages.length > 0 ? this.pages[this.pages.length - 1] : 0
+ if (top - latestPageTop >= this.originalPageHeight) {
+ this.pages.push(latestPageTop + this.originalPageHeight);
+ } else if (top + eleHeight - latestPageTop > this.originalPageHeight && top != latestPageTop) {
+ this.pages.push(latestPageTop + this.originalPageHeight);
+ }
+ }
+ /**
+ * 获取元素距离网页顶部的距离
+ */
+ getElementTop(element) {
+ if (element.getBoundingClientRect) {
+ const rect = element.getBoundingClientRect() || {}
+ const topDistance = rect.top;
+
+ return topDistance;
+ }
+ return 0
+ }
+
+ /**
+ * 添加页眉
+ * @returns
+ */
+ async addHeader(pageNo, header, pdf, contentWidth) {
+ if (!header || !(header instanceof HTMLElement)) {
+ return;
+ }
+
+ let pageNoDom = header.querySelector(".print-header-page");
+ let pageSizeDom = header.querySelector(".print-header-page-size");
+ if (pageNoDom) {
+ pageNoDom.innerText = pageNo;
+ }
+
+ if (pageSizeDom) {
+ pageSizeDom.innerText = this.pages.length;
+ }
+ if (pageNoDom || !this.__header) {
+ // 其他页 页头都是一样的,不需要每次都生成
+ this.__header = await this.toCanvas(header, contentWidth);
+ }
+
+ const { height, data } = this.__header;
+ pdf.addImage(data, "JPEG", this.baseX, this.baseY, contentWidth, height);
+ }
+
+ /**
+ * 添加页脚
+ */
+ async addFooter(pageSize, pageNo, footer, pdf, contentWidth) {
+ if (!footer || !(footer instanceof HTMLElement)) {
+ return;
+ }
+
+ // 页码元素,类名这里写死了
+ let pageNoDom = footer.querySelector(".print-footer-page");
+ let pageSizeDom = footer.querySelector(".print-footer-page-size");
+ if (pageNoDom) {
+ pageNoDom.innerText = pageNo;
+ }
+
+ if (pageSizeDom) {
+ pageSizeDom.innerText = pageSize;
+ }
+
+ // 如果设置了页码的才需要每次重新生成cavan
+ if (pageNoDom || !this.__footer) {
+ this.__footer = await this.toCanvas(footer, contentWidth);
+ }
+
+ const { height, data } = this.__footer;
+ // 高度位置计算:当前页面高度 - 页脚在pdf中的高度
+ pdf.addImage(
+ data,
+ "JPEG",
+ this.baseX,
+ this.pagerHeight - height - this.baseY,
+ contentWidth,
+ height
+ );
+ }
+
+ // 截取图片
+ addImage(_x, _y, pdf, data, width, height) {
+ pdf.addImage(data, "JPEG", _x, _y, width, height);
+ }
+
+ /**
+ * 添加空白遮挡
+ */
+ addBlank(x, y, width, height, pdf) {
+ pdf.setFillColor(255, 255, 255);
+ pdf.rect(x, y, Math.ceil(width), Math.ceil(height), "F");
+ }
+}
diff --git a/packages/cw/print_block_sdk/components/cw-print-designer/index.js b/packages/cw/print_block_sdk/components/cw-print-designer/index.js
new file mode 100644
index 00000000..cc444722
--- /dev/null
+++ b/packages/cw/print_block_sdk/components/cw-print-designer/index.js
@@ -0,0 +1,3 @@
+import CwPrintDesigner from "./index.vue"
+
+export default CwPrintDesigner
\ No newline at end of file
diff --git a/packages/cw/print_block_sdk/components/cw-print-designer/index.vue b/packages/cw/print_block_sdk/components/cw-print-designer/index.vue
new file mode 100644
index 00000000..70c002eb
--- /dev/null
+++ b/packages/cw/print_block_sdk/components/cw-print-designer/index.vue
@@ -0,0 +1,245 @@
+
+
+
+
+
+
+
+
diff --git a/packages/cw/print_block_sdk/components/cw-print-designer/utils.js b/packages/cw/print_block_sdk/components/cw-print-designer/utils.js
new file mode 100644
index 00000000..40279605
--- /dev/null
+++ b/packages/cw/print_block_sdk/components/cw-print-designer/utils.js
@@ -0,0 +1,25 @@
+export function px2mm(px, dpi) {
+ let radio = 4;
+ if (px == null) return 0;
+ dpi = dpi || printParams.dpi;
+ const ret = parseFloat(`${(px * 254) / (dpi * 10)}`);
+ radio = 10 ** radio;
+ return Math.ceil(Math.floor(ret * radio) / radio);
+}
+
+
+const getDeviceDPI = () => {
+ return (window.devicePixelRatio * 2 || 2) * 72;
+};
+
+export function mmToPx(mm, dpi = getDeviceDPI()) {
+ return Math.ceil(mm * 2.83);
+}
+
+export function mmToPt(mm) {
+ return mm / 25.4 * 72;
+}
+
+export function pxToPt(px) {
+ return px * 72 / 96;
+}
diff --git a/packages/cw/print_block_sdk/index.js b/packages/cw/print_block_sdk/index.js
index 2a8436b1..90e21bd6 100644
--- a/packages/cw/print_block_sdk/index.js
+++ b/packages/cw/print_block_sdk/index.js
@@ -1,6 +1,8 @@
import CwPrintView from './components/cw-print-view';
+import CwPrintDesigner from './components/cw-print-designer';
// COMPONENT IMPORTS
export {
CwPrintView,
+ CwPrintDesigner,
// COMPONENT EXPORTS
};
diff --git a/packages/cw/print_block_sdk/manifest b/packages/cw/print_block_sdk/manifest
index 4446156b..014f14d4 100644
--- a/packages/cw/print_block_sdk/manifest
+++ b/packages/cw/print_block_sdk/manifest
@@ -1,6 +1,10 @@
Plugin-Version: 1.0.0
Library-Type: Frontend
Metadata-File: usage.json
-packages/extension/print_block_sdk@1.0.0/dist-theme/demo.html: dist-theme/demo.html
-packages/extension/print_block_sdk@1.0.0/dist-theme/index.js: dist-theme/index.js
-packages/extension/print_block_sdk@1.0.0/dist-theme/index.js.map: dist-theme/index.js.map
\ No newline at end of file
+packages/extension/print_block_sdk@1.1.0/dist-theme/chunk-0a84b673.2a488f9b.js: dist-theme/chunk-0a84b673.2a488f9b.js
+packages/extension/print_block_sdk@1.1.0/dist-theme/chunk-0a84b673.2a488f9b.js.map: dist-theme/chunk-0a84b673.2a488f9b.js.map
+packages/extension/print_block_sdk@1.1.0/dist-theme/chunk-2d216214.016bb56b.js: dist-theme/chunk-2d216214.016bb56b.js
+packages/extension/print_block_sdk@1.1.0/dist-theme/chunk-2d216214.016bb56b.js.map: dist-theme/chunk-2d216214.016bb56b.js.map
+packages/extension/print_block_sdk@1.1.0/dist-theme/demo.html: dist-theme/demo.html
+packages/extension/print_block_sdk@1.1.0/dist-theme/index.js: dist-theme/index.js
+packages/extension/print_block_sdk@1.1.0/dist-theme/index.js.map: dist-theme/index.js.map
\ No newline at end of file
diff --git a/packages/cw/print_block_sdk/package.json b/packages/cw/print_block_sdk/package.json
index e70a5f77..ae541d56 100644
--- a/packages/cw/print_block_sdk/package.json
+++ b/packages/cw/print_block_sdk/package.json
@@ -2,7 +2,7 @@
"name": "print_block_sdk",
"title": "打印模块SDK",
"description": "",
- "version": "1.0.0",
+ "version": "1.3.0",
"main": "./index.js",
"author": "",
"repository": "",
@@ -30,11 +30,11 @@
},
"devDependencies": {
"@vue/cli-service": "^4.4.1",
+ "cloud-ui.vusion": "^0.11.20",
"core-js": "^3.6.5",
- "vue-loader": "15.9.8",
+ "vue": "^2.6.10",
"vue-cli-plugin-vusion": "0.14.2-beta",
- "cloud-ui.vusion": "^0.11.20",
- "vue": "^2.6.10"
+ "vue-loader": "15.9.8"
},
"peerDependencies": {
"cloud-ui.vusion": "^0.11.20",
@@ -47,5 +47,10 @@
"lcapVersion": "0.3.0",
"template": {
"inited": true
- }
+ },
+ "dependencies": {
+ "html2canvas": "^1.4.1",
+ "jspdf": "^2.5.1",
+ "print-js": "^1.6.0"
+ }
}
diff --git a/packages/cw/print_block_sdk/print_block_sdk@0.1.0.zip b/packages/cw/print_block_sdk/print_block_sdk@0.1.0.zip
deleted file mode 100644
index 70dd8922..00000000
Binary files a/packages/cw/print_block_sdk/print_block_sdk@0.1.0.zip and /dev/null differ
diff --git a/packages/cw/print_block_sdk/print_block_sdk@1.0.0/manifest b/packages/cw/print_block_sdk/print_block_sdk@1.0.0/manifest
deleted file mode 100644
index 4446156b..00000000
--- a/packages/cw/print_block_sdk/print_block_sdk@1.0.0/manifest
+++ /dev/null
@@ -1,6 +0,0 @@
-Plugin-Version: 1.0.0
-Library-Type: Frontend
-Metadata-File: usage.json
-packages/extension/print_block_sdk@1.0.0/dist-theme/demo.html: dist-theme/demo.html
-packages/extension/print_block_sdk@1.0.0/dist-theme/index.js: dist-theme/index.js
-packages/extension/print_block_sdk@1.0.0/dist-theme/index.js.map: dist-theme/index.js.map
\ No newline at end of file
diff --git a/packages/cw/print_block_sdk/vusion.config.js b/packages/cw/print_block_sdk/vusion.config.js
index 7e17cdd0..b877d2c2 100644
--- a/packages/cw/print_block_sdk/vusion.config.js
+++ b/packages/cw/print_block_sdk/vusion.config.js
@@ -3,6 +3,7 @@ module.exports = {
docs: {
components: [
{ group: '组件', name: 'cw-print-view',path: "./components/cw-print-view/api.yaml"},,
+ { group: '组件', name: 'cw-print-designer',path: "./components/cw-print-designer/api.yaml"},,
// Conponents Route List
],
},
diff --git a/yarn.lock b/yarn.lock
index 23325785..eeb0dbda 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,32 +2,37 @@
# yarn lockfile v1
-lodash.mergewith@^4.6.2:
- version "4.6.2"
- resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
- integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
+"dom-to-image@^2.6.0":
+ "integrity" "sha512-Dt0QdaHmLpjURjU7Tnu3AgYSF2LuOmksSGsUcE6ItvJoCWTBEmiMXcqBdNSAm9+QbbwD7JMoVsuuKX6ZVQv1qA=="
+ "resolved" "https://registry.npmjs.org/dom-to-image/-/dom-to-image-2.6.0.tgz"
+ "version" "2.6.0"
-node-fetch@2:
- version "2.7.0"
- resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
- integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
+"lodash.mergewith@^4.6.2":
+ "integrity" "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="
+ "resolved" "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz"
+ "version" "4.6.2"
+
+"node-fetch@2":
+ "integrity" "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="
+ "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz"
+ "version" "2.7.0"
dependencies:
- whatwg-url "^5.0.0"
+ "whatwg-url" "^5.0.0"
-tr46@~0.0.3:
- version "0.0.3"
- resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
- integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
+"tr46@~0.0.3":
+ "integrity" "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ "resolved" "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz"
+ "version" "0.0.3"
-webidl-conversions@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
- integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
+"webidl-conversions@^3.0.0":
+ "integrity" "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ "resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz"
+ "version" "3.0.1"
-whatwg-url@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
- integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
+"whatwg-url@^5.0.0":
+ "integrity" "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="
+ "resolved" "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz"
+ "version" "5.0.0"
dependencies:
- tr46 "~0.0.3"
- webidl-conversions "^3.0.0"
+ "tr46" "~0.0.3"
+ "webidl-conversions" "^3.0.0"