先看结果
代码如下:
<template>
<el-button @click="handlerPrinterCustom" icon="el-icon-printer" plain type="primary"
>打 印
</el-button>
</template>
<script setup>
import { VXETable } from 'vxe-table';
const handlerPrinterCustom = () => {
let $print = VXETable.print;
// 模拟的数据
const items = Array.from({ length: 10 }, (_, i) => ({
index: i + 1,
materialName: `物料${i + 1}`,
boringNumber: `编号${i + 1}`,
materialType: `类型${i + 1}`,
unit: '单位',
quantity: (i + 1) * 10,
price: (i + 1) * 10,
total: (i + 1) * 100,
remark: '备注',
}));
// 每页显示的数据条数
const itemsPerPage = 8;
// 计算总页数
const totalPages = Math.ceil(items.length / itemsPerPage);
$print({
sheetName: '出库单打印',
style: `
.invoice-page {
margin: 10px;
height: 500px; // 调整页面高度以适应打印
font-family: Arial, sans-serif;
}
.invoice-header {
text-align: center;
font-size: 24px;
font-weight: bold;
}
.invoice-info {
display: flex;
justify-content: space-between;
align-items: center;
}
.invoice-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
}
.invoice-table th, .invoice-table td {
border: 1px solid #000;
text-align: center;
}
.invoice-table tr {
height: 30px; // 设置行高
}
.invoice-footer {
display: flex;
justify-content: space-around;
font-size: 14px;
}
`,
content: Array.from(
{ length: totalPages },
(_, pageIndex) => `
<div class="invoice-page">
<div class="invoice-header">北京重装智慧矿山工程技术有限公司</div>
<div class="invoice-info">
<div style="font-size: 24px;padding-left:20px;">出库单</div>
<div style="align-self:flex-end;padding-bottom:15px;">日期:2022-01-01</div>
<div>
<p>项目编号:YJXM2023-001No. 2024-03-043</p>
<p>合同编号:CG202302-003</p>
</div>
</div>
<div class="invoice-info">
<div style="padding-bottom:6px;">项目名称:黄陵——号矿设备全生命周期管理项目(西安汇创)</div>
<div style="padding-bottom:6px;">客户名称:陕西界域科技有限公司</div>
</div>
<table class="invoice-table">
<thead>
<tr>
<th>序号</th>
<th>物资编号</th>
<th>材料名称</th>
<th>规格型号</th>
<th>单位</th>
<th>数量</th>
<th>单价/元</th>
<th>金额/元</th>
<th>备注</th>
<th></th>
</tr>
</thead>
<tbody>
${items
.slice(pageIndex * itemsPerPage, (pageIndex + 1) * itemsPerPage)
.map(
item => ` <tr> <td>${item.index}</td> <td>${item.boringNumber}</td> <td>${item.materialName}</td> <td>${item.materialType}</td> <td>${item.unit}</td> <td>${item.quantity}</td> <td>${item.price}</td> <td>${item.total}</td> <td>${item.remark}</td> ${item.index % 8 == 1 ? `<td rowspan="9" style="writing-mode: vertical-rl; text-align: center;"><span style="margin-bottom:3px;">①</span>存根(白)<span style="margin-bottom:4px;"></span><span style="margin-bottom:3px;">②</span>记账(红)<span style="margin-bottom:4px;"></span><span style="margin-bottom:3px;">③</span>回执(黄)</td>` : ''} </tr> `
)
.join('')}
${Array(itemsPerPage - items.slice(pageIndex * itemsPerPage, (pageIndex + 1) * itemsPerPage).length).fill().map(() => ` <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> `).join('')}
<tr>
<td>合计</td>
<td colspan="6"></td>
<td>${items.reduce((sum, item) => sum + item.total, 0)}</td>
<td></td>
</tr>
</tbody>
</table>
<div class="invoice-footer">
<div>保管:</div>
<div>验收:</div>
<div>制单:</div>
</div>
</div>
`
).join(''),
});
};
</script>
效果和代码如上,有需要的朋友可以试试,下面啰嗦几句如何使用vxe-table的自定义打印,和这个demo的实现细节。
一. 如何在vue3中使用vxe-table的自定义打印功能
1.首先安装vxe-table
npm install vxe-table
2.引入
<script setup>
import { VXETable } from 'vxe-table';
</script>
3.自定义打印方法
let $print = VXETable.print;
$print({
sheetName: '打印自定义模板',
style: `.page{margin:10px;height:2000px}`,
content: `我是合同`
});
VXETable.print
可以接受一个配置对象作为参数。这个配置对象可以包含以下属性:
sheetName:打印的工作表名称。
style:自定义的CSS样式。
content:打印的内容。
二、上述发票demo的需求和实现细节
要求一页纵向可以打印两张发票,每一张表格数据只能是8条,比如9条数据,第9条数据就需要再第二张发票打印
注意:这里画打印页面的html标签需要原生的html标签,不能是第三发库的,比如表格需要用<table/>,不能使用<el-table/>
这需要前端实现分页,并且第二张发票除了表格数据外 的其他信息也要呈现出来,比如标题,日期等。
这个我是使用Array.from 加上 join方法实现的
这段代码的作用是生成一个数组,数组的长度等于总页数(totalPages),数组的每个元素是一个字符串,这个字符串代表一个打印页面的HTML内容。
Array.from({length: totalPages}, (_, pageIndex) => {…}) 这段代码会创建一个新的数组,数组的长度等于 totalPages。数组的每个元素是由提供的函数生成的,这个函数接受两个参数:当前元素的值(在这里我们用 _ 忽略它)和当前元素的索引(在这里我们用 pageIndex 表示它)。
在这个函数中,我们返回一个字符串,这个字符串是一个HTML片段,代表一个打印页面的内容。这个HTML片段包含一个
这样,最终生成的数组的每个元素都是一个代表一个打印页面的HTML片段,当我们将这个数组连接起来(通过 .join(‘’)),就得到了所有打印页面的HTML内容。
表格分页
填充空行,一张发票的数据不够8条时,填充空行
表格右侧备注栏处理,每一张的第一行设置纵向单元格合并
合计
好啦,以上就是关于vue3项目中使用vxe-table的自定义打印方法实现打印发票功能的分享啦,欢迎留言讨论