前言: 目前模板套打的工具不多,个人参与的项目恰好需要使用到模板套打功能,于是查了一下最后选择了 C-LODOP 。其常见的功能都覆盖到了,尤其用户本地直接接打印机打印是免费的。

套打:简单的理解就是,纸上的网格线、表头等信息都有了,现在要做的就是将内容动态填充上去。如:快递单、银行小票等。

先看下大致效果:

1.未检测到 c-lodop 服务,进行提示

2. 打印预览页面(蓝色字体是动态打上去的,表格绿色字体等是图片背景)

下面来说下大致的实现步骤,以及遇到的一些难点:

1.先下载安装 C-LODOP 

c-lodop下载地址

文件不大,解压之后,点击如下 exe 文件启用服务。

2. 将上述的 LodopFuncs.js 文件放到工程某个文件下

并对该文件做一点点小的处理,以下是自己的处理。

该插件可直接放在前端工程文件下,当提示的时候,用户可以直接下载。

.....// 下载loadLodop
function loadLodop() {const lodopurl = '../lodop/CLodop_Setup_for_Win32NT.exe'window.location.href= lodopurl
}......

​​​​​​​

/* eslint-disable */
import { MessageBox } from 'element-ui'
var CreatedOKLodop7766 = null//====判断是否需要安装CLodop云打印服务器:====
export function needCLodop() {try {var ua = navigator.userAgentif (ua.match(/Windows\sPhone/i) != null) return trueif (ua.match(/iPhone|iPod/i) != null) return trueif (ua.match(/Android/i) != null) return trueif (ua.match(/Edge\D?\d+/i) != null) return truevar verTrident = ua.match(/Trident\D?\d+/i)var verIE = ua.match(/MSIE\D?\d+/i)var verOPR = ua.match(/OPR\D?\d+/i)var verFF = ua.match(/Firefox\D?\d+/i)var x64 = ua.match(/x64/i)if (verTrident == null && verIE == null && x64 !== null) return trueelse if (verFF !== null) {verFF = verFF[0].match(/\d+/)if (verFF[0] >= 42 || x64 !== null) return true} else if (verOPR !== null) {verOPR = verOPR[0].match(/\d+/)if (verOPR[0] >= 32) return true} else if (verTrident == null && verIE == null) {var verChrome = ua.match(/Chrome\D?\d+/i)if (verChrome !== null) {verChrome = verChrome[0].match(/\d+/)if (verChrome[0] >= 42) return true}}return false} catch (err) {return true}
}//====页面引用CLodop云打印必须的JS文件:====
if (needCLodop()) {var head =document.head ||document.getElementsByTagName('head')[0] ||document.documentElementvar oscript = document.createElement('script')oscript.src = 'http://localhost:8000/CLodopfuncs.js?priority=1'head.insertBefore(oscript, head.firstChild)//引用双端口(8000和18000)避免其中某个被占用:oscript = document.createElement('script')oscript.src = 'http://localhost:18000/CLodopfuncs.js?priority=0'head.insertBefore(oscript, head.firstChild)
}// 下载loadLodop
function loadLodop() {const lodopurl = '../lodop/CLodop_Setup_for_Win32NT.exe'window.location.href= lodopurl
}//====获取LODOP对象的主过程:====
export function getLodop(oOBJECT, oEMBED) {var strHtmInstall ="<br><font color='#FF00FF'>打印控件未安装!点击这里<a href='install_lodop32.exe' target='_self'>执行安装</a>,安装后请刷新页面或重新进入。</font>"var strHtmUpdate ="<br><font color='#FF00FF'>打印控件需要升级!点击这里<a href='install_lodop32.exe' target='_self'>执行升级</a>,升级后请重新进入。</font>"var strHtm64_Install ="<br><font color='#FF00FF'>打印控件未安装!点击这里<a href='install_lodop64.exe' target='_self'>执行安装</a>,安装后请刷新页面或重新进入。</font>"var strHtm64_Update ="<br><font color='#FF00FF'>打印控件需要升级!点击这里<a href='install_lodop64.exe' target='_self'>执行升级</a>,升级后请重新进入。</font>"var strHtmFireFox ="<br><br><font color='#FF00FF'>(注意:如曾安装过Lodop旧版附件npActiveXPLugin,请在【工具】->【附加组件】->【扩展】中先卸它)</font>"var strHtmChrome ="<br><br><font color='#FF00FF'>(如果此前正常,仅因浏览器升级或重安装而出问题,需重新执行以上安装)</font>"var strCLodopInstall ="<br><font color='#FF00FF'>CLodop云打印服务(localhost本地)未安装启动!点击这里<a href='http://www.c-lodop.com/download/CLodop_Setup_for_Win32NT_https_3.008Extend.zip' target='_self'>执行安装</a>,安装后请刷新页面。</font>"var strCLodopUpdate ="<br><font color='#FF00FF'>CLodop云打印服务需升级!点击这里<a href='CLodop_Setup_for_Win32NT.exe' target='_self'>执行升级</a>,升级后请刷新页面。</font>"var LODOPtry {var isIE =navigator.userAgent.indexOf('MSIE') >= 0 ||navigator.userAgent.indexOf('Trident') >= 0if (needCLodop()) {try {LODOP = getCLodop()} catch (err) {MessageBox({title: '温馨提示',type: 'warning',showCancelButton: true,confirmButtonText: '下载',cancelButtonText: '取消',message: '检测到您还未安装C-LODOP套打控件,请确认启用后再打印。或您可点击下载该套打控件,安装成功后刷新页面再进行打印',callback: res => {if (res === 'confirm') {loadLodop()}}})}if (!LODOP && document.readyState !== 'complete') {alert('C-Lodop没准备好,请稍后再试!')return}if (!LODOP) {// if (isIE) document.write(strCLodopInstall); else// document.documentElement.innerHTML=strCLodopInstall+document.documentElement.innerHTML;// return;} else {if (CLODOP.CVERSION < '3.0.0.2') {if (isIE) document.write(strCLodopUpdate)elsedocument.documentElement.innerHTML =strCLodopUpdate + document.documentElement.innerHTML}if (oEMBED && oEMBED.parentNode) oEMBED.parentNode.removeChild(oEMBED)if (oOBJECT && oOBJECT.parentNode)oOBJECT.parentNode.removeChild(oOBJECT)}} else {var is64IE = isIE && navigator.userAgent.indexOf('x64') >= 0//=====如果页面有Lodop就直接使用,没有则新建:==========if (oOBJECT != undefined || oEMBED != undefined) {if (isIE) LODOP = oOBJECTelse LODOP = oEMBED} else if (CreatedOKLodop7766 == null) {LODOP = document.createElement('object')LODOP.setAttribute('width', 0)LODOP.setAttribute('height', 0)LODOP.setAttribute('style','position:absolute;left:0px;top:-100px;width:0px;height:0px;')if (isIE)LODOP.setAttribute('classid','clsid:2105C259-1E0C-4534-8141-A753534CB4CA')else LODOP.setAttribute('type', 'application/x-print-lodop')document.documentElement.appendChild(LODOP)CreatedOKLodop7766 = LODOP} else LODOP = CreatedOKLodop7766//=====Lodop插件未安装时提示下载地址:==========if (LODOP == null || typeof LODOP.VERSION == 'undefined') {if (navigator.userAgent.indexOf('Chrome') >= 0)document.documentElement.innerHTML =strHtmChrome + document.documentElement.innerHTMLif (navigator.userAgent.indexOf('Firefox') >= 0)document.documentElement.innerHTML =strHtmFireFox + document.documentElement.innerHTMLif (is64IE) document.write(strHtm64_Install)else if (isIE) document.write(strHtmInstall)elsedocument.documentElement.innerHTML =strHtmInstall + document.documentElement.innerHTMLreturn LODOP}}if (LODOP.VERSION < '6.0') {if (!needCLodop()) {if (is64IE) document.write(strHtm64_Update)else if (isIE) document.write(strHtmUpdate)elsedocument.documentElement.innerHTML =strHtmUpdate + document.documentElement.innerHTML}return LODOP}//===如下空白位置适合调用统一功能(如注册语句、语言选择等):===//LODOP.SET_LICENSES("北京XXXXX公司","8xxxxxxxxxxxxx5","","");//===========================================================return LODOP} catch (err) {// alert('getLodop出错:' + err)console.error('getLodop出错:' + err)}
}

3. 调用的方法

import { getLodop } from '@/util/lodop/LodopFuncs'

4. 一些细节点

4.1 背景图引入以及 lodop 设置大小

import imgsrc from '@/assets/images/lodop/taoda.jpg'data() {return {imgsrc,......}},LODOP.ADD_PRINT_SETUP_BKIMG(`"<img border='0' src=${this.imgsrc}>"`) //背景图LODOP.SET_SHOW_MODE('BKIMG_LEFT', '0mm') // 左边距离LODOP.SET_SHOW_MODE('BKIMG_TOP', '0mm') // 顶部距离LODOP.SET_SHOW_MODE('BKIMG_WIDTH', '197mm') // 宽度LODOP.SET_SHOW_MODE('BKIMG_HEIGHT', '210mm') // 高度 这句可不加,因宽高比例固定按原图的LODOP.SET_SHOW_MODE('BKIMG_IN_PREVIEW', 1) // 预览的时候带背景

4.2 对要打印出来的表格数据,记得在页面上用原生的 table 、thead、th 、tr、td等,并对表格加上 display:none,因为有时并不需要在页面上看到这个表格的内容。

    <div id="stReport" style="display: none;"><tableid="stTable"border="0"align="center"cellpadding="0"cellspacing="0"style="border:solid 0px black;width: 95%; height: 100%;">
........

5. 完整的 demo案例

<template><div><el-button type="primary" @click="printPdf">打 印</el-button><div id="stReport" style="display: none;"><tableid="stTable"border="0"align="center"cellpadding="0"cellspacing="0"style="border:solid 0px black;width: 95%; height: 100%;"><tbody style="height: 82%;"><trv-for="(item, index) in tableData2":key="index"style="height: 60px;"><tdwidth="31%"style="word-break:break-all; word-wrap:break-word; font-size: 18px; color: blue;">{{item.label === '123'? '': '摘要摘要摘要摘要摘要摘要摘要摘要摘要摘要摘要摘要摘要摘要摘要'}}</td><tdwidth="31%"style="word-break:break-all; word-wrap:break-word; font-size: 18px; color: blue;padding-left: 15px;">{{item.label === '123'? '': '会计科目会计科目会计科目会计科目会计科目会计科目会计科目会计科目'}}</td><tdwidth="6%"align="right"style="word-wrap: nowarp; font-size: 18px;":style="{ color: item.label === '123' ? 'white' : 'blue' }">{{ item.label === '123' ? 0 : 10056700.98 }}</td><tdwidth="6%"align="right"style="word-wrap: nowarp; font-size: 18px;":style="{ color: item.label === '123' ? 'white' : 'blue' }">{{ item.label === '123' ? 0 : 1000.23 }}</td></tr></tbody><!-- absolute fixed --><tfoot style="height: 8%; bottom: 0px;"><tr><tdwidth="15%"tdata="Sum"tindex="3"format="#,##0.00"align="right"><font color="white" id="sum1">¥###</font></td><tdwidth="15%"tdata="Sum"tindex="4"format="#,##0.00"align="right"><font color="white" id="sum2">¥###</font></td></tr><tr><tdwidth="60%"align="left"colspan="2"style="padding-left: 80px;"><font color="blue" tdata="(sum1 + sum2)" format="UpperMoney">#####<br /></font></td><tdwidth="16.7%"tdata="Sum"tindex="3"format="#,##0.00"align="right"style="padding-left: 10px;"><font color="blue" id="sum3">¥###</font></td><tdwidth="16.7%"tdata="Sum"tindex="4"format="#,##0.00"align="right"><font color="blue" id="sum4">¥###</font></td></tr><tr><!-- <tdwidth="66.7%"tdata="AllSum"tindex="3"format="#,##0.00"align="left"colspan="2"><font color="blue" id="id02">所有5-¥###</font></td><td width="16.7%" tindex="3" tdata="SubSum">####</td><td width="16.7%" tindex="3" tdata="SubSum" format="UpperMoney">####</td> --></tr></tfoot></table></div></div>
</template><script>
import { getLodop } from '@/util/lodop/LodopFuncs'
import imgsrc from '@/assets/images/lodop/taoda.jpg'
export default {data() {return {tableData2: [],imgsrc}},created() {this.initData()},methods: {initData() {this.tableData2 = []for (let index = 0; index < 50; index++) {this.tableData2.push({ label: index, value: index })}const printNum = 9 // 表格一页打印9条const printPage = Math.ceil(this.tableData2.length / printNum) // 有多少页const expectNum = printNum * printPage //  期望占满页数 printPage 需要的数据条数const tabledataNum = this.tableData2.length // 当前已有的数据// 不够使用空白的来顶替,保证合计数一直在底部显示for (let index = 0; index < expectNum - tabledataNum; index++) {this.tableData2.push({ label: '', value: 0 })}},printPdf() {let LODOP = getLodop()LODOP.SET_PRINT_STYLE('FontSize', 12)LODOP.SET_PRINT_PAGESIZE(2, '297mm', '210mm', 'A4') // 纸张方向大小LODOP.SET_PRINT_STYLEA(0, 'TableHeightScope', 3) //高度包含页尾LODOP.ADD_PRINT_SETUP_BKIMG(`"<img border='0' src=${this.imgsrc}>"`) //背景图LODOP.SET_SHOW_MODE('BKIMG_LEFT', '0mm')LODOP.SET_SHOW_MODE('BKIMG_TOP', '0mm')LODOP.SET_SHOW_MODE('BKIMG_WIDTH', '197mm')LODOP.SET_SHOW_MODE('BKIMG_HEIGHT', '210mm') //这句可不加,因宽高比例固定按原图的LODOP.SET_SHOW_MODE('BKIMG_IN_PREVIEW', 1)// LODOP.SET_SHOW_MODE('BKIMG_IN_PREVIEW', 1) //预览包含背景图// LODOP.SET_PRINT_PAGESIZE(2, 2970, 2100, 'a4') // 纸张方向大小// //  ADD_PRINT_HTM(intTop,intLeft,intWidth,intHeight,strHtml)增加超文本项LODOP.SET_PRINT_COPIES(1) // 份数// LODOP.PRINTSETUP_PAGE_COUNT(2) // 2页// LODOP.SET_PRINT_PAGE_COUNT(2) // 2页LODOP.SET_PREVIEW_WINDOW(0, 0, 0, 0, 0, '') // 演示设置各种样式的打印预览窗口:LODOP.SET_SHOW_MODE('LANDSCAPE_DEFROTATED', 1) //横向时的正向显示// LODOP.SET_PRINT_STYLE('Bold', 1)LODOP.SET_PRINT_STYLE('FontColor', '#0000FF')LODOP.ADD_PRINT_TEXT('20mm', '115mm', '40mm', '5mm', '记账凭证')LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1) // ->放在某处后面表示每一页都有这个内容LODOP.ADD_PRINT_TEXT('28mm', '115mm', '40mm', '5mm', '2019年')LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1) // ->放在某处后面表示每一页都有这个内容LODOP.ADD_PRINT_TEXT('36mm','60mm','55mm','5mm','社会保险事业管理中心')LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)LODOP.ADD_PRINT_TEXT('36mm', '115mm', '40mm', '5mm', '中央调剂金账套')LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)LODOP.ADD_PRINT_TEXT('28mm', '242mm', '40mm', '5mm', '3月29日')LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)LODOP.ADD_PRINT_TEXT('36mm', '242mm', '40mm', '5mm', '编号:记账1')LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)// 表格部分// LODOP.ADD_PRINT_HTM(//   '59mm',//   '40mm',//   '245mm',//   '117mm',//   document.getElementById('stReport').innerHTML// )LODOP.ADD_PRINT_TABLE('59mm','38mm','245mm','117mm',document.getElementById('stReport').innerHTML)// 页码LODOP.ADD_PRINT_HTM('200mm','48%','100mm',100,"<font color='#000'><span tdata='pageNO'>第##页</span>/<span tdata='pageCount'> 共##页</span></font>")LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)// 张数LODOP.ADD_PRINT_HTM('77mm','284mm','2mm','5mm',"<font color='0000FF'><span tdata='pageNO'>##</span></font>") // 打印页码LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)// 合计部分// LODOP.ADD_PRINT_TEXT('180mm', '60mm', '140mm', '5mm', '2323.23')// LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)// LODOP.ADD_PRINT_TEXT('180mm', '200mm', '40mm', '5mm', '2,020,202.00')// LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)// LODOP.ADD_PRINT_TEXT('180mm', '250mm', '40mm', '5mm', '2,020,202.00')// LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)// 人员部分LODOP.ADD_PRINT_TEXT('191mm', '55mm', '30mm', '5mm', '财务主管xx')LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)LODOP.ADD_PRINT_TEXT('191mm', '100mm', '30mm', '5mm', '记账人xx')LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)LODOP.ADD_PRINT_TEXT('191mm', '140mm', '30mm', '5mm', '复核人xx')LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)LODOP.ADD_PRINT_TEXT('191mm', '177mm', '30mm', '5mm', '出纳xx')LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)LODOP.ADD_PRINT_TEXT('191mm', '217mm', '30mm', '5mm', '制单人xx')LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)LODOP.ADD_PRINT_TEXT('191mm', '260mm', '30mm', '5mm', '经办人xx')LODOP.SET_PRINT_STYLEA(0, 'ItemType', 1)// LODOP.PRINT() // 直接打印// LODOP.PRINT_SETUP() // 手动维护LODOP.PREVIEW()}}
}
</script><style lang="scss" scoped></style>

用到的背景图:

自己在研究中花了很多的时间怎么使用,怎么统计,怎么计数。以下是自己收藏的博客,希望能帮助到您:(提示:若是您看不到实际的代码咋设置的,可打开浏览器控制台查看例子的源码 javascript 部分函数,就可以知道咋弄的了~~~我就是这么干的哈哈哈)

1.演示打印Table的分页小计和合计

2.LODOP中ADD_PRINT_TABLE、HTM、HTML表格自动分页测试

Lodop如何设置预览后导出带背景的图,打印不带背景图

第十八篇 难点突破之-VUE中使用 C-LODOP 实现模板的套打相关推荐

  1. “约见”面试官系列之常见面试题之第八十八篇之什么是vue生命周期(建议收藏)

    我们知道vue是一个构建数据驱动的 web 界面的渐进式框架,那么vue生命周期是什么呢?本篇文章就给大家来介绍一下vue生命周期的内容,希望可以帮助到有需要的朋友. vue生命周期是什么? Vue生 ...

  2. 2021年安全生产工作总结及2022年思路计划(二十八篇)PPTX(附下载)

    摘要:2021年安全生产工作总结及2022年思路计划(二十八篇) 公众号:安全生产星球

  3. “约见”面试官系列之常见面试题第二十八篇之vue中的混合(minix)实例理解

    minix 是个什么东西, 就是混合,把你混合给我 浅显表述就是 你说 : '我叫李四', 我说 : '我叫张三', 然后把你 混合给我, 就成了 我说 : '我叫张三我叫李四', 所有解说都在例子里 ...

  4. 实习日志_实习律师实习日志第十八篇(连载30篇)

    提供实习律师实习日记相关的文章资讯,希望我的分享能让您感到满意! 这个月接触最多的是人身损害赔偿的一些案件,交通事故.工伤的一些案件最多.起初,以为这些案件就是走走法律流程便可了事,最简单不过,可当完 ...

  5. 【手写 Vue2.x 源码】第二十八篇 - diff 算法-问题分析与 patch 优化

    一,前言 首先,对 6 月的更文内容做一下简单回顾: Vue2.x 源码环境的搭建 Vue2.x 初始化流程介绍 对象的单层.深层劫持 数组的单层.深层劫持 数据代理的实现 对象.数组数据变化的观测 ...

  6. 怎么将vue模板转换为html,vue中自定义html文件的模板

    如果默认生成的 HTML 文件不适合需求,可以创建/使用自定义模板. 一是通过 inject 选项,然后传递给定制的 HTML 文件.html-webpack-plugin 将会自动注入所有需要的 C ...

  7. pug模板语法在vue中的使用--HTML的模板引擎

    一. 介绍 pug,原名jade,是流行的HTML模板引擎,,最大的特色是使用缩进排列替代成对标签.它简化了HTML的成对标签的写法,使代码更加简洁.开发效率更高,但是同时它也带来了一些副作用:可移植 ...

  8. 第六十八篇:从ADAS到自动驾驶(一):自动驾驶发展及分级

    作者:liaojiacai     邮箱: ljc_v2x_adas@foxmail.com 从ADAS到自动驾驶(一):自动驾驶的发展及分级 从今天起,我将根据自己所接触的ADAS和无人驾驶技术,来 ...

  9. 【手写 Vue2.x 源码】第十八篇 - 根据 render 函数,生成 vnode

    一,前言 上篇,介绍了 render 函数的生成,主要涉及以下两点: 使用 with 对生成的 code 进行一次包装 将包装后的完整 code 字符串,通过 new Function 输出为 ren ...

  10. 第十八篇,Simulink with Git

    一.综述 本篇以MATLAB R2021b为基础讲解如何对Simulink模型做Git管理,mdl与slx均可. Git并非只能对手写代码做版本管理,它的应用十分广泛,囊括了各种使用编程语言编写的代码 ...

最新文章

  1. linux wchar t char,linux 下 Linux 下char转换为wchar_t
  2. HDU4055 - number string(DP)
  3. MFC程序打开控制台
  4. java importgeopoint_如何在地图上显示更多点(GeoPoint)?
  5. (转)Redis研究(一)—简介
  6. 创造黑科技,守护新未来 | 360公司2019年春季校园招聘正式启动!
  7. 70多个国家地区免费享受wifi
  8. lync登录时一直停留在登录界面
  9. shared_ptr四宗罪
  10. 王者荣耀不同服务器能显示微信好友吗,王者荣耀怎么看微信好友在那个区
  11. 轻松了解Spring中的控制反转和依赖注入(一) --[转]http://www.cnblogs.com/xxzhuang/p/5948902.html...
  12. 计算机英语词汇 沪江,常用计算机英语词汇学习
  13. Java SE 007 循环控制语句
  14. a标签去下划线或文字添加下修饰_a标签去掉下划线_百度经验
  15. oracle 手动添加分区,Oracle 分区表怎么添加分区
  16. 展望|人脸识别技术发展现状及未来趋势
  17. 炒黄金短线交易如何放大收益
  18. Prompt-Guided Injection of Conformation to Pre-trained Protein Model
  19. 【openEuler】x2openEuler工具使用
  20. 第四部分:NoSQL实践

热门文章

  1. 左耳朵耗子:疫情下的远程办公,聊聊我的经验和实践
  2. 关于HD-SDI原理设计、PCB设计汇总
  3. CentOS7更换阿里yum源
  4. 基于python 爬虫网络舆情分析系统_基于Python的网络爬虫系统
  5. Python绘图实例24:三层嵌套正方形绘制
  6. linux环境文件或者文件夹打包
  7. c语言sinx幂级数展开,求幂级数展开式的方法
  8. DevOps落地实践:通讯行业系列:NTT COMWARE之Devaas
  9. 云优CMS批量翻译插件
  10. Active Directory攻防实验室环境搭建教程(一)