You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

719 lines
17 KiB
Vue

<template>
<div style="width: 100%;height: 100vh;overflow: hidden">
<div class="left">
<div id="printInfo" ref="printRef">
<div class="content" v-for=" pageData in pageDatas"
:style="{pageBreakAfter: 'always',width: cmToPx(pageWidth)+'px',height: cmToPx(pageHeight)+'px',marginBottom:'4px'}">
<div v-for="i in nodes" class="node" :style="{left:i.position?.x+'px',top: i.position?.y+'px'}">
<template v-if="i.type === 'text'">
<TextNode v-bind="i" :isView="true" :isPrint="isPrint" :pageData="pageData"
:pageSize="{width: cmToPx(pageWidth) ,height: cmToPx(pageHeight) }"></TextNode>
</template>
<template v-if="i.type === 'image'">
<ImageNode v-bind="i" :isView="true" :isPrint="isPrint" :pageData="pageData"
:pageSize="{width: cmToPx(pageWidth) ,height: cmToPx(pageHeight) }"></ImageNode>
</template>
<template v-if="i.type === 'barCode'">
<BarCodeNode v-bind="i" :isView="true" :isPrint="isPrint" :pageData="pageData"
:pageSize="{width: cmToPx(pageWidth) ,height: cmToPx(pageHeight) }"></BarCodeNode>
</template>
<template v-if="i.type === 'QRCode'">
<QRCodeNode v-bind="i" :isView="true" :isPrint="isPrint" :pageData="pageData"
:pageSize="{width: cmToPx(pageWidth) ,height: cmToPx(pageHeight) }"></QRCodeNode>
</template>
<template v-if="i.type === 'dateTime'">
<TimeNode v-bind="i" :isView="true" :isPrint="isPrint" :pageData="pageData"
:pageSize="{width: cmToPx(pageWidth) ,height: cmToPx(pageHeight) }"></TimeNode>
</template>
<template v-if="i.type === 'select'">
<SelectNode :isView="true" :isPrint="isPrint" :pageData="pageData"
:pageSize="{width: cmToPx(pageWidth) ,height: cmToPx(pageHeight) }"
v-bind="i"></SelectNode>
</template>
</div>
</div>
</div>
</div>
<div class="right">
<el-dropdown split-button type="primary" @click="printFun" @command="switchPrinter" style="margin-right: 8px;">
{{ printName() }}
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item :command="-1">导出PDF</el-dropdown-item>
<el-dropdown-item divided :command="0"></el-dropdown-item>
<el-dropdown-item :divided="k===0" :command="i.id" v-for=" (i,k) in printers">{{ i.name }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
<div id="printArea" v-if="printPngList.length>0">
<div
v-for="(url, index) in printPngList"
:key="index"
class="print-page"
>
<img :src="url" class="print-image" />
</div>
</div>
</template>
<script setup>
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
import { options } from '@/views/print/tool.js';
import TextNode from '@/views/print/nodes/textNode.vue';
import ImageNode from '@/views/print/nodes/image.vue';
import BarCodeNode from './nodes/barCodeNode.vue';
import QRCodeNode from './nodes/QRCodeNode.vue';
import TimeNode from './nodes/timeNode.vue';
import SelectNode from './nodes/selectNode.vue';
import { useRoute } from 'vue-router';
import { isJSON } from '@/utils/scrin.js';
const route = useRoute();
const printType = ref(0);
const printers = ref([
{
id: 1,
name: '网络打印机1'
},
{
id: 2,
name: '网络打印机2'
},
{
id: 3,
name: '网络打印机3'
}
]);
const printPngList = ref([]);
const isView = ref(true);
const isPrint = ref(false);
const printRef = ref();
const pageWidth = ref(21);
const pageHeight = ref(29.7);
const pageDatas = ref([{}, {}]);
const { cmToPx } = options;
const nodes = ref([]);
let printNode = `[
{
"id": "area_d14a13ad_1a78_4171_b54f_93d18abd528d",
"type": "area",
"dimensions": {
"width": 794,
"height": 1123
},
"computedPosition": {
"x": 0,
"y": 0,
"z": 0
},
"handleBounds": {
"source": null,
"target": null
},
"selected": false,
"dragging": false,
"resizing": false,
"initialized": false,
"isParent": true,
"position": {
"x": 0,
"y": 0
},
"data": {},
"events": {},
"name": "area"
},
{
"id": "text_1902a5ff_d7fc_4750_b634_8a88868f3ddb",
"type": "text",
"dimensions": {
"width": 94,
"height": 19
},
"computedPosition": {
"x": 151.1811023622047,
"y": 37.79527559055118,
"z": 1
},
"handleBounds": {
"source": null,
"target": null
},
"selected": false,
"dragging": false,
"resizing": false,
"initialized": false,
"isParent": false,
"position": {
"x": 151.1811023622047,
"y": 37.79527559055118
},
"data": {
"options": {
"default": "供应商",
"border": [
{
"type": "top",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "right",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "bottom",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "left",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
}
]
},
"outputData": {}
},
"events": {},
"name": "text",
"parentNode": "area_d14a13ad_1a78_4171_b54f_93d18abd528d",
"extent": "parent",
"style": {
"width": "94px",
"height": "19px"
}
},
{
"id": "text_899234fc_9ace_49c3_8127_fadeabcbd23d",
"type": "text",
"dimensions": {
"width": 94,
"height": 19
},
"computedPosition": {
"x": 150.97637795275588,
"y": 56.69291338582677,
"z": 1
},
"handleBounds": {
"source": null,
"target": null
},
"selected": false,
"dragging": false,
"resizing": false,
"initialized": false,
"isParent": false,
"position": {
"x": 150.97637795275588,
"y": 56.69291338582677
},
"data": {
"options": {
"default": "客户名称",
"border": [
{
"type": "top",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "right",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "bottom",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "left",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
}
]
},
"outputData": {}
},
"events": {},
"name": "text",
"parentNode": "area_d14a13ad_1a78_4171_b54f_93d18abd528d",
"extent": "parent",
"style": {
"width": "94px",
"height": "19px"
}
},
{
"id": "text_8da299d4_a35b_4ba9_bfac_860c200b6cf3",
"type": "text",
"dimensions": {
"width": 94,
"height": 19
},
"computedPosition": {
"x": 245.66929133858267,
"y": 56.69291338582677,
"z": 1
},
"handleBounds": {
"source": null,
"target": null
},
"selected": false,
"dragging": false,
"resizing": false,
"initialized": false,
"isParent": false,
"position": {
"x": 245.66929133858267,
"y": 56.69291338582677
},
"data": {
"options": {
"field": "name",
"default": "",
"border": [
{
"type": "top",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "right",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "bottom",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "left",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
}
]
},
"outputData": {}
},
"events": {},
"name": "text",
"parentNode": "area_d14a13ad_1a78_4171_b54f_93d18abd528d",
"extent": "parent",
"style": {
"width": "94px",
"height": "19px"
}
},
{
"id": "text_5a3a87dd_1697_43a1_9678_f20421e1f3df",
"type": "text",
"dimensions": {
"width": 396,
"height": 19
},
"computedPosition": {
"x": 245.66929133858267,
"y": 37.79527559055118,
"z": 1
},
"handleBounds": {
"source": null,
"target": null
},
"selected": false,
"dragging": false,
"resizing": false,
"initialized": false,
"isParent": false,
"position": {
"x": 245.66929133858267,
"y": 37.79527559055118
},
"data": {
"options": {
"field": "DONGLONG HOME TEXTILE CO..,LTD.",
"default": "DONGLONG HOME TEXTILE CO..,LTD.",
"border": [
{
"type": "top",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "right",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "bottom",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "left",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
}
]
},
"outputData": {}
},
"events": {},
"name": "text",
"parentNode": "area_d14a13ad_1a78_4171_b54f_93d18abd528d",
"extent": "parent",
"style": {
"width": "396px",
"height": "19px"
}
},
{
"id": "text_e9bde955_7c37_44d0_8c37_265ad44fdd9d",
"type": "text",
"dimensions": {
"width": 75,
"height": 19
},
"computedPosition": {
"x": 170.0787401574803,
"y": 302.3622047244094,
"z": 1
},
"handleBounds": {
"source": null,
"target": null
},
"selected": false,
"dragging": false,
"resizing": false,
"initialized": false,
"isParent": false,
"position": {
"x": 170.0787401574803,
"y": 302.3622047244094
},
"data": {
"options": {
"field": "deviceName",
"default": "",
"border": [
{
"type": "top",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "right",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "bottom",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
},
{
"type": "left",
"isShow": false,
"width": 1,
"color": "#000",
"borderType": "solid"
}
]
},
"outputData": {}
},
"events": {},
"name": "text",
"parentNode": "area_d14a13ad_1a78_4171_b54f_93d18abd528d",
"extent": "parent",
"style": {
"width": "75px",
"height": "19px"
}
},
{
"id": "QRCode_94877b0d_0e26_4a8e_b159_8d99120725a0",
"type": "QRCode",
"dimensions": {
"width": 189,
"height": 189
},
"computedPosition": {
"x": 415.74803149606294,
"y": 264.56692913385825,
"z": 1001
},
"handleBounds": {
"source": null,
"target": null
},
"selected": true,
"dragging": false,
"resizing": false,
"initialized": false,
"isParent": false,
"position": {
"x": 415.74803149606294,
"y": 264.56692913385825
},
"data": {
"options": {
"default": "123123121"
},
"outputData": {}
},
"events": {},
"name": "QRCode",
"parentNode": "area_d14a13ad_1a78_4171_b54f_93d18abd528d",
"extent": "parent"
}
]`;
window.addEventListener('message', (event) => {
if (isJSON(event.data)) {
let data = JSON.parse(event.data);
if (data.type === 'print') {
printFun();
}
if (data.type === 'setData') {
if (typeof data.value === 'object' && data.value !== null && !Array.isArray(data.value)) {
pageDatas.value = [data.value];
}
if (Array.isArray(data.value)) {
pageDatas.value = data.value;
}
}
if (data.type === 'setTemplate') {
nodes.value = JSON.parse(printNode || '[]');
}
}
});
onMounted(() => {
// nodes.value = JSON.parse(localStorage.getItem('printNodes') || '[]');
nodes.value = JSON.parse(printNode || '[]');
const param = route.query.data;
if (isJSON(param)) {
let data = JSON.parse(param);
if (Array.isArray(data)) {
}
// if()
}
});
const printInfoObj = {
id: 'printInfo',
preview: false, // 是否开启预览
beforeOpenCallback(vue) {
console.log('触发打印工具打开前回调');
},
openCallback(vue) {
console.log('触发打印工具打开的回调');
},
closeCallback() {
console.log('触发关闭打印工具回调');
},
previewBeforeOpenCallback() {
console.log('触发预览前回调');
},
previewOpenCallback() {
console.log('触发预览的回调');
}
};
const switchPrinter = (e) => {
console.log(e);
printType.value = e;
};
const printFun = (e) => {
if (printType.value === -1) {
isPrint.value = true;
nextTick(() => {
const element = printRef.value;
let eles = element.querySelectorAll('.content');
const pros = [];
eles.forEach((ele, index) => {
pros.push(
html2canvas(ele).then(canvas => {
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF();
pdf.addImage(imgData, 'PNG', 0, 0);
pdf.save(`${new Date().getTime()}-${index}.pdf`);
})
);
});
Promise.all(pros).then((values) => {
isPrint.value = false;
});
});
} else if (printType.value === 0) {
isPrint.value = true;
printPngList.value = [];
nextTick(() => {
const element = printRef.value;
let eles = element.querySelectorAll('.content');
const pros = [];
eles.forEach((ele, index) => {
pros.push(
html2canvas(ele).then(canvas => {
const imgData = canvas.toDataURL('image/png');
printPngList.value.push(imgData);
})
);
});
Promise.all(pros).then((values) => {
window.print();
isPrint.value = false;
printPngList.value = [];
});
});
} else {
}
};
const closePrint = () => {
isView.value = false;
};
const openPrint = (pages, templateId) => {
isView.value = false;
nextTick(() => {
nodes.value = JSON.parse(localStorage.getItem('printNodes') || '[]');
isView.value = true;
let pageData = [];
if (Array.isArray(pages)) {
pageData = pages;
}
if (typeof pages !== 'object' || pages === null) {
pageData = [pages];
}
console.log(pageData);
pageDatas.value = pageData || [];
});
};
const printName = () => {
if (printType.value === -1) {
return '导出PDF';
} else if (printType.value === 0) {
return '本地打印';
} else {
let name = printers?.value?.find(e => e.id === printType?.value)?.name;
return name || '';
}
};
defineExpose({
openPrint
// closePrint
});
</script>
<style scoped>
.content {
position: relative;
overflow: hidden;
background-repeat: no-repeat;
background-size: 100% 100%;
border: 1px solid #ccc;
}
.node {
position: absolute;
}
.left {
display: inline-block;
width: calc(100% - 200px);
}
.right {
vertical-align: top;
display: inline-block;
width: 200px;
}
</style>
<style>
.print-page {
page-break-after: always;
text-align: center;
padding: 20px;
background: white;
}
.print-image {
max-width: 100%;
height: auto;
}
/* 打印样式:仅显示图片区域 */
@media print {
body * {
visibility: hidden !important;
}
#printArea,
#printArea * {
visibility: visible !important;
}
#printArea {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.print-page {
page-break-after: always;
}
}
</style>