子组件
<template>
<!-- ref绑定打印dom节点名称 -->
<div id="printArea" class="printAsset">
<table class="assetPrintTable">
<!-- 重点--一定要写thead -->
<thead>
<tr>
<td v-for="(item, index) in tableTitle" :key="index">{{ item.name }}</td>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in tableData" :key="index">
<template v-for="(ele, i) in tableTitle" :key="i">
<td>{{ item[ele.value] }}</td>
</template>
</tr>
</tbody>
</table>
<div class="footer">
<div class="makeTable">制表人:</div>
<div class="makeTable">制表人:</div>
</div>
</div>
</template>
<script setup>
import Print from 'print-js'
import dayjs from "dayjs";
const props = defineProps({
tableTitle: {
type: Array,
default: []
},
tableData: {
type: Array,
default: []
},
printObj: {
type: Object,
default: {
tableHeade: '打印测试',
unit: ''
}
}
})
const state = reactive({
pageIndex: 0
})
const removeField = (data = []) => {
const fields = props.tableTitle.map(({ value }) => value);
return data.map((item) => {
return fields.map((field) => {
const value = item?.[field];
return item;
});
});
};
const result = removeField(props.tableData)
const workOrderStyle = () => {
return `
@page{margin:8mm};
.printAsset {
width: 100%;
}
.printAsset .assetPrintTable {
width: 100%;
border-collapse: collapse;
border-spacing: 0;
border-left: 1px solid #e4e7ed;
border-top: 1px solid #e4e7ed;
}
.printAsset .assetPrintTable tr {
page-break-inside: avoid;
}
.printAsset .assetPrintTable td, .printAsset .assetPrintTable th {
border-right: 1px solid #e4e7ed;
border-bottom: 1px solid #e4e7ed;
padding: 10px;
text-align: center;
}
.printAsset .assetPrintTable th {
background-color: #f5f7fa;
}
.footer{
margin-top:30px;
}
.makeTable{
line-height:35px
}
`
}
const handlePrint = (params) => {
printJS({
printable: 'printArea',
type: "html",
header: `<div style='text-align: center;margin-bottom:15px'>
<h3>${props.printObj.tableHeade}</h3>
<div style="display:flex;justify-content:space-between">
<span >打印时间: ${dayjs().format('YYYY.MM.DD HH:mm:ss')}</span>
<span >${props.printObj.subTitle || `共${props.tableData.length || 0}条数据`}</span>
</div>
</div>`, // '表单',
style: workOrderStyle(),
scanStyles: false,
onStart: () => {
console.log("打印开始");
},
onEnd: () => {
console.log("打印完成");
},
})
}
setTimeout(() => {
nextTick(() => {
handlePrint()
})
}, 0);
</script>
<style lang="scss">
.printAsset {
width: 100%;
// 表格基本样式
.assetPrintTable {
width: 100%;
border-collapse: collapse;
border-spacing: 0;
border-left: 1px solid #e4e7ed;
border-top: 1px solid #e4e7ed;
// 实现分页,行不撕裂的关键
tr {
page-break-inside: avoid;
}
// 单元格样式
td,
th {
border-right: 1px solid #e4e7ed;
border-bottom: 1px solid #e4e7ed;
padding: 10px;
text-align: center;
}
//表头添加背景色
th {
background-color: #f5f7fa;
}
}
}
// 媒体查询print,只在打印和打印预览的时候生效
@media print {
.printAsset {
width: 100%;
// 表格基本样式
.assetPrintTable {
width: 100%;
border-collapse: collapse;
border-spacing: 0;
border-left: 1px solid #e4e7ed;
border-top: 1px solid #e4e7ed;
// 实现分页,行不撕裂的关键
tr {
page-break-inside: avoid;
}
// 单元格样式
td,
th {
border-right: 1px solid #e4e7ed;
border-bottom: 1px solid #e4e7ed;
padding: 10px;
text-align: center;
}
//表头添加背景色
th {
background-color: #f5f7fa;
}
}
}
}
</style>
父组件
<template>
<print :tableTitle="pageDataTitle" :tableData="tableData" :printObj="printObj"></print>
</template>
<script setup >
import print from '@/components/print.vue'
//存放表头
let pageDataTitle = reactive([{
name: '姓名',
width: '',
value: 'name'
}, {
name: '地址',
width: '',
value: 'address'
}])
let tableData = []
for (let i = 0; i < 400; i++) {
tableData.push({
name: `Tom${i}`,
address: 'No. 189, Grove St, Los Angeles',
})
}
const printObj = ref({
subTitle:`共${tableData.length}个成员`,
tableHeade:'打印测试'
})
</script>
<style scoped lang='scss'></style>