前言: 目前模板套打的工具不多,个人参与的项目恰好需要使用到模板套打功能,于是查了一下最后选择了 C-LODOP 。其常见的功能都覆盖到了,尤其用户本地直接接打印机打印是免费的。
套打:简单的理解就是,纸上的网格线、表头等信息都有了,现在要做的就是将内容动态填充上去。如:快递单、银行小票等。
先看下大致效果:
1.未检测到 c-lodop 服务,进行提示
2. 打印预览页面(蓝色字体是动态打上去的,表格绿色字体等是图片背景)
下面来说下大致的实现步骤,以及遇到的一些难点:
1.先下载安装 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.userAgent
if (ua.match(/Windows\sPhone/i) != null) return true
if (ua.match(/iPhone|iPod/i) != null) return true
if (ua.match(/Android/i) != null) return true
if (ua.match(/Edge\D?\d+/i) != null) return true
var 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 true
else 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.documentElement
var 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 LODOP
try {
var isIE =
navigator.userAgent.indexOf('MSIE') >= 0 ||
navigator.userAgent.indexOf('Trident') >= 0
if (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)
else
document.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 = oOBJECT
else 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.innerHTML
if (navigator.userAgent.indexOf('Firefox') >= 0)
document.documentElement.innerHTML =
strHtmFireFox + document.documentElement.innerHTML
if (is64IE) document.write(strHtm64_Install)
else if (isIE) document.write(strHtmInstall)
else
document.documentElement.innerHTML =
strHtmInstall + document.documentElement.innerHTML
return LODOP
}
}
if (LODOP.VERSION < '6.0') {
if (!needCLodop()) {
if (is64IE) document.write(strHtm64_Update)
else if (isIE) document.write(strHtmUpdate)
else
document.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;">
<table
id="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;">
<table
id="stTable"
border="0"
align="center"
cellpadding="0"
cellspacing="0"
style="border:solid 0px black;width: 95%; height: 100%;"
>
<tbody style="height: 82%;">
<tr
v-for="(item, index) in tableData2"
:key="index"
style="height: 60px;"
>
<td
width="31%"
style="word-break:break-all; word-wrap:break-word; font-size: 18px; color: blue;"
>
{{
item.label === '123'
? ''
: '摘要摘要摘要摘要摘要摘要摘要摘要摘要摘要摘要摘要摘要摘要摘要'
}}
</td>
<td
width="31%"
style="word-break:break-all; word-wrap:break-word; font-size: 18px; color: blue;padding-left: 15px;"
>
{{
item.label === '123'
? ''
: '会计科目会计科目会计科目会计科目会计科目会计科目会计科目会计科目'
}}
</td>
<td
width="6%"
align="right"
style="word-wrap: nowarp; font-size: 18px;"
:style="{ color: item.label === '123' ? 'white' : 'blue' }"
>
{{ item.label === '123' ? 0 : 10056700.98 }}
</td>
<td
width="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>
<td
width="15%"
tdata="Sum"
tindex="3"
format="#,##0.00"
align="right"
>
<font color="white" id="sum1">¥###</font>
</td>
<td
width="15%"
tdata="Sum"
tindex="4"
format="#,##0.00"
align="right"
>
<font color="white" id="sum2">¥###</font>
</td>
</tr>
<tr>
<td
width="60%"
align="left"
colspan="2"
style="padding-left: 80px;"
>
<font color="blue" tdata="(sum1 + sum2)" format="UpperMoney"
>#####<br />
</font>
</td>
<td
width="16.7%"
tdata="Sum"
tindex="3"
format="#,##0.00"
align="right"
style="padding-left: 10px;"
>
<font color="blue" id="sum3">¥###</font>
</td>
<td
width="16.7%"
tdata="Sum"
tindex="4"
format="#,##0.00"
align="right"
>
<font color="blue" id="sum4">¥###</font>
</td>
</tr>
<tr>
<!-- <td
width="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 部分函数,就可以知道咋弄的了~~~我就是这么干的哈哈哈)