美文网首页
VUE使用富文本自定义打印模板

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

作者: 小雄_Milo | 来源:发表于2020-12-16 14:48 被阅读0次

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

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

    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]]
    })

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/ttnngktx.html