VUE使用富文本自定义打印模板

当面对千千万万的打印格式需求时,这时可能需要使用打印模板。
但是后端使用客户提供的模板,往往需要进行“二次加工”。
所以
本文是提供给用户的打印模板编辑器,用户自定义模板,系统动态取值替换即可。
减少设计,开发,测试,运维等一系列的时间成本。

用户也是自己动手(系统还是要给初始模板),丰衣足食。

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;">&nbsp;</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]]
})

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容