这次需要批量打印样品标识卡(多个table表格),尺寸要求是100*60,遇到了很多问题。 一个table占满一张纸,不换纸,大小刚刚好,需要:
- 配置打印机纸张尺寸正确:100*60
- window.open()的新页面的默认margin需要清除掉:
body{margin:0}
- 设置一个table外面有一个不显示的标签,刚好占满整张纸:
.card{width:100vw;height:100vh}
打印机配置
打印机纸张尺寸配置:100*60,配置步骤: (先装打印机驱动) 控制面板\硬件和声音\设备和打印机: 右键-> 打印机属性 -> (现在又出现提示驱动没装,已经能打印了,之后再更新)
代码实现
1. 打印的步骤
- 获取字符串:
let codeHtml = getCodeHtml()
- 打开新页面 :
win = window.open('', 'printwindow')
- 新页面内容渲染:
win.document.write(codeHtml)
- 打印
win.print()
- 关闭页面
win.close()
代码如下:
import { htmlTemplate } from './htmlTemplate';
const getCodeHtml=()=>{ // 获取打印模板
return htmlTemplate(list)
}
const handlePrint = () =>{ // 打印
let codeHtml = getCodeHtml()
const win = window.open('', 'printwindow')
win.document.write(codeHtml)
win.print()
win.close() // 不调用这个方法会导致后续write页面追加,每次不是重新打印
}
2、根据数据 获取打印字符串
htmlTemplate.js 打印模板
import {htmlTemplateStyle} from './htmlTemplateStyle.js'
export const htmlTemplate = (arr) =>{
// <img class="logo" src='http://srtest.weiputech.com/erpImg/logo.png' alt="" />
let header = `
<div class="tr_title">
<div class="logo_wrapper">
<img class="logo" src='./logo.png' alt="" />
</div>
<div class="title">
样品标识卡
</div>
</div>
`
let trList = (tData)=>{
let textStr = (item)=>{
let strt = ''
strt += `
<div class="tr">
<div class="th">${item.th}</div>
<div class="td">`
if(item.type==='input'){
strt +=`<div class="input td_text">${item.value}</div>`
}else if(item.type === 'text'){
strt += `<div class="td_text">${item.value}</div>`
}
strt += `</div>
</div>
`
return strt
}
let listStr = (item)=>{
let checkItemStr = (item)=>{
// let checkedImgStr = item.isChecked && `<img class="icon_checked" src="http://srtest.weiputech.com/erpImg/check.png" alt="" />` || ''
let checkedImgStr = item.isChecked && `<img class="icon_checked" src="./check.png" alt="" />` || ''
return `
<div class="group_check">
<div class="icon_check_table">
${checkedImgStr}
</div>
<div>
${item.label}
</div>
</div>
`
}
let inputItemStr = (item)=>{
return `
<div class="group_check">
${item.type==='inputCheck' && checkItemStr(item) || ''}
${item.type==='input' && item.label||''}
<div class="input ${item.type}">${item.value}</div>
<div>${item.unit}</div>
</div>
`
}
let res = `
<div class="tr">
<div class="th">${item.th}</div>
<div class="group_td">
`
item.value.forEach(td=>{
res += `<div class="td">
<div class="td_list">
`
td.forEach(tdItem=>{
switch(tdItem.type){
case 'check':
// res += 'test'
res += checkItemStr(tdItem)
break
case 'input':
case 'inputCheck':
res += inputItemStr(tdItem)
break;
default:
res += tdItem.type
break;
}
})
res += `</div>
</div>`
})
res += `
</div>
</div>
`
return res
}
// trLists.forEach(tData=>{
let str = ``
Object.keys(tData).forEach(key=>{
let tdObj = tData[key]
const { type} = tdObj
switch(type){
case 'input':
case 'text':
str += textStr(tdObj)
break;
case 'list':
str += listStr(tdObj)
break;
default:
break
}
})
// })
return str
}
let content=htmlTemplateStyle+'<div>'
arr.forEach(tData=>{
content += `
<div class="card">
<div class="table">
${header}
${trList(tData)}
</div>
</div>
`
})
content += '</div>'
// content = getReplacedStr(content)
return content
}
3、获取打印页样式
样式可以通过style标签内嵌
最终是:
<style> //...样式 </style>
下面是htmlTemplateStyle.js
export const htmlTemplateStyle= `<style>
body{
margin:0;
}
.card{
width:100vw;
height:100vh;
overflow:hidden;
box-sizing:border-box;
padding:8px 0;
}
.table{
margin:0 auto;
width: 340px;
height:208px;
border: 1px solid;
border-bottom: none;
font-size: 1px;
color: rgba(0,0,0,0.85);
line-height: 19px;
overflow:hidden;
}
.input{
width: 110px;
border: none;
border-bottom: 1px solid;
height: 16px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tr_title{
height: 28px;
line-height: 28px;
font-size: 15px;
color: rgba(0,0,0,0.85);
display: flex;
justify-content: flex-start;
align-items: center;
border-bottom: 1px solid;
}
.logo_wrapper{
box-sizing: border-box;
width: 70px;
}
.logo{
width:70px;
}
.title{
flex: 1;
text-align: center;
}
.tr{
width: 100%;
border-bottom: 1px solid;
display: flex;
justify-content: flex-start;
align-items: center;
}
.th{
box-sizing: border-box;
padding-left: 5px;
width: 70px;
height: 100%;
flex-shrink:0;
}
.group_td{
flex: 1;
}
.td{
width: 100%;
flex: 1;
box-sizing: border-box;
height: 19px;
display: flex;
justify-content: flex-start;
align-items: center;
}
.td_text{
text-align:center;
width:100%;
}
.input.td_text{
border: none;
height: 16px;
padding: 0;
width: 100%;
text-align: center;
}
.input.inputCheck{
width: 40px;
}
.td_list{
width: 100%;
display: flex;
align-items: center;
justify-content: flex-start;
}
.group_check{
padding-left: 10px;
display: flex;
flex: left;
align-items: center;
}
.icon_check_table{
margin-right: 5px;
width: 10px;
height: 10px;
border: 1px solid;
position: relative;
}
.icon_checked{
width: 8px;
height: 8px;
position: absolute;
left: 1px;
}
</style>`
这次想要打印的页面结构是这样的
// <div>
// <div class="card">
// <div class="table">
// {/* 第一行 */}
// <div class="tr_title">
// <div class="logo_wrapper">
// <img class="logo" src={require('./c68e43d49351935632ed5cb46c358f5.png')} alt="" />
// </div>
// <div class="title">
// 样品标识卡
// </div>
// </div>
// {/* 行 */}
// {/* type : text input */}
// <div class="tr">
// <div class="th"></div>
// <div class="td"></div>
// </div>
// {/* 行 */}
// {/* type:;list */}
// <div class="tr">
// <div class="th"></div>
// <div class="group_td">
// <div class="td">
// <div class="td_list">
// {/* type: check */}
// {/* 遍历 开始 */}
// <div class="group_check">
// <div class="icon_check_table">
// {/* 需要判断 isChecked */}
// <img class="icon_checked" src="" alt="" />
// </div>
// <div>
// {/* tdItem.label */}
// </div>
// </div>
// {/* 遍历 结束 */}
// {/* type:input 、inputCheck */}
// <div class="group_check">
// {/* type: inputCheck */}
// <div class="icon_check_table">
// <img class="icon_checked" src="" alt="" />
// </div>
// {/* end */}
// <div>
// {/* tdItem.label */}
// </div>
// <div>
// {/* tdItem.value */}
// </div>
// <div>
// {/* tdItem.unit */}
// </div>
// </div>
// </div>
// </div>
// </div>
// </div>
// </div>
// </div>
// </div>