当面对千千万万的打印格式需求时,这时可能需要使用打印模板。
但是后端使用客户提供的模板,往往需要进行“二次加工”。
所以
本文是提供给用户的打印模板编辑器,用户自定义模板,系统动态取值替换即可。
减少设计,开发,测试,运维等一系列的时间成本。
用户也是自己动手(系统还是要给初始模板),丰衣足食。
vue.config.js 或index.html 引入js
https://cdn.jsdelivr.net/npm/vue-ueditor-wrap@latest/lib/vue-ueditor-wrap.min.js
当然也可以npm install vue-ueditor-wrap
main.js 注册组件
Vue.component('vue-ueditor-wrap', window.VueUeditorWrap)
引入UEditor包到public/static 或者放在某个cdn目录 下方配置引入即可
<template>
<div>
<div id="app">
<div class="tembtn">
<a-button type="primary" @click="print()">打印内容</a-button>
<a-button type="primary" @click="showTemplate()">显示模板</a-button>
<a-popconfirm
title="请勿将生成的示例作为模板,是否确认保存模板?"
ok-text="确认"
cancel-text="返回"
@confirm="saveTemplate">
<a-button type="primary">保存模版</a-button>
</a-popconfirm>
<a-button type="primary" @click="showData()">控制台输出数据</a-button>
<a-button type="primary" @click="genTemplate()">按模板生成示例</a-button>
</div>
<br/>
<div>
<div style="width: 150px;float: left;">
<div v-for="t in printFmt" :key="t">
<input style="width: 140px;border: 1px solid #dddddd;margin-bottom: -1px;height: 33px;" @click="selectAll($event)" :value="t.name"/>
</div>
</div>
<div style="width: 820px;float: left;" >
<vue-ueditor-wrap ref="template" @mousedown="checkTag" v-model="msg" :config="myConfig"></vue-ueditor-wrap>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "setPrintTemplate",
data() {
return {
msg: '',
printFmt:[
{name:"【供应商名称】",value:'obj1.coustomName'},
{name:"【供应商联系人】",value:'obj1.coustomUserName'},
{name:"【供应商手机】",value:'obj1.coustomPhone'},
{name:"【面料名称-多行】",value:'tableData1.name'},
{name:"【面料规格-多行】",value:'tableData1.size'},
{name:"【面料单价-多行】",value:'tableData1.price'},
{name:"【面料数量-多行】",value:'tableData1.num'},
{name:"【面料金额-多行】",value:'tableData1.totalPrice'},
{name:"【面料数量合计】",value:'obj1.allTotalNum'},
{name:"【面料金额合计】",value:'obj1.allTotalPrice'},
{name:"【辅料名称-多行】",value:'tableData2.name'},
{name:"【辅料规格-多行】",value:'tableData2.size'},
{name:"【辅料单价-多行】",value:'tableData2.price'},
{name:"【辅料数量-多行】",value:'tableData2.num'},
],
data:{
obj1:{
coustomName:'广州服饰有限公司',
coustomPhone:'15112345678',
coustomUserName:'张三',
allTotalNum:'60',
allTotalPrice:'910.00',
},
tableData1:[
{name:'面料A',size:'20m*10',price:'10.50',num:'20',totalPrice:'210.00'},
{name:'面料b',size:'20m*10',price:'15.00',num:'20',totalPrice:'300.00'},
{name:'面料c',size:'20m*10',price:'20.00',num:'20',totalPrice:'400.00'}
],
tableData2:[
{name:'辅料A',size:'20m*10',price:'10.50',num:'20'},
{name:'辅料b',size:'20m*10',price:'15.00',num:'20'},
]
},
myConfig: {
//工具栏 详情查看 static/UEditor/ueditor.config.js
toolbars: [
[
'fullscreen', 'source', '|', 'undo', 'redo', '|',
'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|',
'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
'directionalityltr', 'directionalityrtl', 'indent', '|',
'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'touppercase', 'tolowercase', '|',
'link', 'unlink', 'anchor', '|',
'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts', '|',
'print', 'preview', 'searchreplace'
]
],
// 编辑器不自动被内容撑高
autoHeightEnabled: false,
// 初始容器高度
initialFrameHeight: 620,
// 初始容器宽度
initialFrameWidth: '100%',
// 上传文件接口
serverUrl: '',
enableAutoSave: false,
elementPathEnable: false,
wordCount: false,
// UEditor 资源文件的存放路径,建议使用远程单独的cdn 格式可以是网络路径 UEDITOR_HOME_URL: 'http://test.com/static/UEditor/'
UEDITOR_HOME_URL: '/static/UEditor/'
}
}
},
mounted() {
this.msg = localStorage.setPrintTemplate || ''
},
methods: {
checkTag(){
console.log(123)
},
selectAll(e){
e.currentTarget.select()
},
saveTemplate() {
localStorage.setPrintTemplate = this.msg;
this.$message.success("保存成功!")
},
showTemplate(){
this.msg = localStorage.setPrintTemplate;
this.$message.success("获取模板成功!")
},
showData(){
console.log(this.data)
},
genTemplate(){
var that = this;
//获取模板内容
// console.log(that.msg)
//获取数据键值对
const map = new Map();
for(var i=0;i<that.printFmt.length;i++){
var f = that.printFmt[i];
map.set(f.name,f.value);
if(f.name.indexOf("多行")==-1){//替换简单键值对
that.msg = that.msg.replace(RegExp(f.name, "g"),this.data[f.value.split(".")[0]][f.value.split(".")[1]])//多级需要单独的方法进行处理
}
}
//替换表格键值对,考虑变成多行
//1.获取tr行并 生成表格数据对应的行数
var regTable= /<\/tbody>.*?/g;
var regTr = /<tr>.*?<\/tr>/g;
var tagTr = /【.*?】/g;
var tables = that.msg.split(regTable)
for(var j=0;j<tables.length;j++){
var table = tables[j]
if(table.indexOf("多行")!=-1){
var newTable = table.replace(regTr, function(str) {
if(str.indexOf("多行")!=-1){
//根据第一个【xxx】获取对应的表格
var tagName = str.substr(str.indexOf("【"),str.indexOf("】")-str.indexOf("【")+1)
//获取表格数据
var tableData = that.data[map.get(tagName).split(".")[0]]
//动态数据行
var dynamicRows = "";
for(var l=0;l<tableData.length;l++){
var s = str.replace(tagTr, function(s1) {
return tableData[l][map.get(s1).split(".")[1]]
})
dynamicRows+=s;
}
//按数据替换并组装表格
return dynamicRows;
}else{
return str;
}
})
that.msg = that.msg.replace(table,newTable);
}
}
},
print() {
var that = this;
var ue = that.$refs.template.editor;
ue.execCommand('print');
}
},
}
</script>
<style>
.tembtn button{
margin-top: 10px;
margin-right: 10px;
}
</style>
测试模板
image.png
打印效果(打印需要取消显示头部)
image.png image.png
模板数据
<p style="text-align: center;">
<span style="font-family: 宋体, SimSun;"><strong style="font-size: 36px;">入库单</strong><strong style="font-size: 36px;"></strong></span>
</p>
<table align="center">
<tbody>
<tr class="firstRow">
<td valign="top" colspan="1" rowspan="1" width="126" style="word-break: break-all; border-width: 1px; border-style: solid;">
<span style="font-size: 14px; font-family: 宋体, SimSun;"><strong>供应商名称</strong></span>
</td>
<td valign="top" style="word-break: break-all; border-width: 1px; border-style: solid;" rowspan="1" colspan="3" width="587">
<span style="font-family: 宋体, SimSun; font-size: 14px;">【供应商名称】</span><br/>
</td>
</tr>
<tr>
<td valign="top" colspan="1" rowspan="1" width="126" style="word-break: break-all; border-width: 1px; border-style: solid;">
<span style="font-family: 宋体, SimSun;"><strong><span style="font-family: 宋体, SimSun; font-size: 14px;">联系人</span></strong></span>
</td>
<td width="285" valign="top" style="word-break: break-all; border-width: 1px; border-style: solid;">
<p>
<span style="font-family: 宋体, SimSun; font-size: 14px;">【供应商联系人】<br/></span>
</p>
</td>
<td width="132" valign="top" style="word-break: break-all; border-width: 1px; border-style: solid;">
<span style="font-size: 14px; font-family: 宋体, SimSun;"><strong>联系方式</strong></span>
</td>
<td width="128" valign="top" style="word-break: break-all; border-width: 1px; border-style: solid;">
<span style="font-family: 宋体, SimSun;"><strong style="font-family: 宋体, SimSun;"><span style="font-size: 14px; font-family: 隶书, SimLi;"> </span></strong><span style="font-size: 14px; font-family: 宋体, SimSun;">【供应商手机】</span><br/></span>
</td>
</tr>
</tbody>
</table>
<p>
<span style="font-family: 宋体, SimSun;">表1</span>
</p>
<table style="" align="center">
<tbody>
<tr class="firstRow">
<td width="130" valign="top" style="border-width: 1px; border-style: solid;">
<span style="font-family: 宋体, SimSun; font-size: 14px;"><strong>面料名称</strong></span>
</td>
<td width="130" valign="top" style="border-width: 1px; border-style: solid;">
<span style="font-size: 14px; font-family: 宋体, SimSun;"><strong>面料规格<br/></strong></span>
</td>
<td width="132" valign="middle" style="word-break: break-all; border-width: 1px; border-style: solid;" align="right">
<span style="font-size: 14px; font-family: 宋体, SimSun;"><strong>单价(元)</strong></span>
</td>
<td width="131" valign="middle" style="word-break: break-all; border-width: 1px; border-style: solid;" align="right">
<span style="font-size: 14px; font-family: 宋体, SimSun;"><strong>数量</strong></span>
</td>
<td width="129" valign="middle" align="right" style="border-width: 1px; border-style: solid;">
<span style="font-size: 14px; font-family: 宋体, SimSun;"><strong>金额</strong></span>
</td>
</tr>
<tr>
<td width="130" valign="top" style="word-break: break-all; border-width: 1px; border-style: solid;">
<span style="font-family: 宋体, SimSun; font-size: 14px;">【面料名称-多行】<br/></span>
</td>
<td width="130" valign="top" style="word-break: break-all; border-width: 1px; border-style: solid;">
<span style="font-family: 宋体, SimSun; font-size: 14px;">【面料规格-多行】<br/></span>
</td>
<td width="132" valign="middle" style="word-break: break-all; border-width: 1px; border-style: solid;" align="right">
<span style="font-family: 宋体, SimSun; font-size: 14px;">【面料单价-多行】<br/></span>
</td>
<td width="131" valign="middle" style="word-break: break-all; border-width: 1px; border-style: solid;" align="right">
<span style="font-family: 宋体, SimSun; font-size: 14px;">【面料数量-多行】<br/></span>
</td>
<td width="129" valign="middle" style="word-break: break-all; border-width: 1px; border-style: solid;" align="right">
<span style="font-family: 宋体, SimSun; font-size: 14px;">【面料金额-多行】<br/></span>
</td>
</tr>
<tr>
<td valign="middle" colspan="3" rowspan="1" style="border-width: 1px; border-style: solid; word-break: break-all;" align="right">
<span style="font-size: 14px; font-family: 宋体, SimSun;"><strong>合计</strong><br/></span>
</td>
<td valign="middle" colspan="1" rowspan="1" align="right" style="border-width: 1px; border-style: solid; word-break: break-all;">
<span style="font-family: 宋体, SimSun; font-size: 14px;">【面料数量合计】<br/></span>
</td>
<td valign="middle" colspan="1" rowspan="1" align="right" style="border-width: 1px; border-style: solid;" width="129">
<span style="font-family: 宋体, SimSun; font-size: 14px;">【面料金额合计】<br/></span>
</td>
</tr>
</tbody>
</table>
<p>
<span style="font-family: 宋体, SimSun;">表2</span>
</p>
<table align="center" width="-149">
<tbody>
<tr class="firstRow">
<td width="130" valign="top" style="border-width: 1px; border-style: solid;">
<span style="font-family: 宋体, SimSun; font-size: 14px;"><strong>辅料名称</strong></span>
</td>
<td width="130" valign="top" style="border-width: 1px; border-style: solid; word-break: break-all;">
<span style="font-size: 14px; font-family: 宋体, SimSun;"><strong><strong style="white-space: normal;">辅</strong>料规格<br/></strong></span>
</td>
<td width="132" valign="middle" style="word-break: break-all; border-width: 1px; border-style: solid;" align="right">
<span style="font-size: 14px; font-family: 宋体, SimSun;"><strong>单价(元)</strong></span>
</td>
<td valign="middle" colspan="1" rowspan="1" width="131" align="right" style="border-width: 1px; border-style: solid;">
<span style="font-size: 14px; font-family: 宋体, SimSun;"><strong style="white-space: normal;">数量</strong></span>
</td>
</tr>
<tr>
<td width="130" valign="top" style="word-break: break-all; border-width: 1px; border-style: solid;">
<span style="font-family: 宋体, SimSun; font-size: 14px;">【辅料名称-多行】<br/></span>
</td>
<td width="130" valign="top" style="word-break: break-all; border-width: 1px; border-style: solid;">
<span style="font-family: 宋体, SimSun; font-size: 14px;">【辅料规格-多行】<br/></span>
</td>
<td width="132" valign="middle" style="word-break: break-all; border-width: 1px; border-style: solid;" align="right">
<span style="font-family: 宋体, SimSun; font-size: 14px;">【辅料单价-多行】<br/></span>
</td>
<td valign="middle" colspan="1" rowspan="1" width="131" align="right" style="border-width: 1px; border-style: solid;">
<span style="font-family: 宋体, SimSun; font-size: 14px;">【辅料数量-多行】<br/></span>
</td>
</tr>
</tbody>
</table>
<p>
<span style="font-family: 宋体, SimSun;"><strong style="font-size: 14px;"><span style="font-family: 宋体, SimSun; color: rgb(255, 0, 0);">收货签字</span></strong><br/></span>
</p>
利用关键字“多行”,寻找对应数组的条数,动态插入数据行,叠加返回
1.需要了解split
把常用的逗号换成了关键字table一样,切不同的表数据进行处理“多行”
var regTable= /</tbody>.*?/g;
切分后包含tbody的数组 = that.msg.split(regTable)
2.需要了解replace
转换后的值 = str.replace(正则表达式, function(符合正则的每一个数据) {
返回替换后的新数据
return tableData[l][map.get(s1).split(".")[1]]
})
网友评论