html2canvas把dom生成图片 然后通过jspdf生成pdf去打印
<template>
<div class="body">
<div style="width: 100%;display:flex;justify-content: center;">
<a-button @click="onPrintSubmit" class="printBtn" type="primary" shape="round" size="large">
确认打印
</a-button>
</div>
<div class="receipt" ref="receipt">
<div class="shopName">
{{ printData?.shopName }}
</div>
<div class="totalIncome">
汇总收入
</div>
<div class="prinitTime">
<div class="label"><span>开始时间:</span><span>{{ starTime }}</span></div>
<div class="label"><span>结束时间:</span><span>{{ endTime }}</span></div>
<div class="label"><span>制单时间:</span><span>{{ currenTime }}</span></div>
</div>
<div class="line"></div>
<div>
<div class="section items">
<div class="table">
<div class="title">
<div class="label1">菜品</div>
<div class="label2">数量</div>
<div class="label3">实收金额</div>
</div>
<div class="column" v-for="item in printData?.singleProductSummaryDataList">
<div class="label1">{{ item.productName }}</div>
<div class="label2">{{ item.salesVolume }}</div>
<div class="label3">{{ item.salesAmount }}</div>
</div>
</div>
</div>
<div class="prinitTime">
<div class="label">营业应收总额:{{ printData?.totalReceivables }}</div>
<div class="label">营业实际收入: {{ printData?.realTotalAmountReceived }}元</div>
</div>
<div class="line"></div>
<div class="section items">
<div class="table">
<div class="title">
<div class="label1"> </div>
<div class="label2">订单数量</div>
<div class="label3">总额</div>
</div>
<!-- <div class="column">
<div class="label1">订单原价</div>
<div class="label2">{{ printData?.orderOriginalPrice }}</div>
<div class="label3">{{ printData?.orderOriginalPrice }}</div>
</div> -->
<div class="column">
<div class="label1">微信支付</div>
<div class="label2">{{ printData?.wechatOrderTotal }}</div>
<div class="label3">{{ printData?.wechatOrderTotalAmount }}</div>
</div>
<div class="column">
<div class="label1">余额支付</div>
<div class="label2">{{ printData?.personalBalancePayOrderTotal }}</div>
<div class="label3">{{ printData?.personalBalancePayOrderTotalAmount }}</div>
</div>
<div class="column">
<div class="label1">餐卡支付</div>
<div class="label2">{{ printData?.mealCardPayOrderTotal }}</div>
<div class="label3">{{ printData?.mealCardPayOrderTotalAmount }}</div>
</div>
<div class="column">
<div class="label1">优惠券优惠</div>
<div class="label2">{{ printData?.redPacketOrderTotal }}</div>
<div class="label3">{{ printData?.redPacketTotalAmount }}</div>
</div>
<div class="column">
<div class="label1">员工优惠</div>
<div class="label2">{{ printData?.employeeDiscountOrderTotal }}</div>
<div class="label3">{{ printData?.employeeDiscountOrderTotalAmount }}</div>
</div>
<div class="column">
<div class="label1">退款总额</div>
<div class="label2"></div>
<div class="label3">{{ printData?.refundTotalAmount }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { getCurrentDateTime, getCurrentYYMMDD } from "/src/utils/utils.js"
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
const receipt = ref(null);
const props = defineProps({
printData: {
type: Object,
default: {},
},
starTime: {
type: Object,
default: getCurrentYYMMDD() + ' 00:00:00',
},
endTime: {
type: Object,
default: getCurrentYYMMDD() + ' 23:59:59',
},
});
const currenTime = ref(null)
onMounted(() => {
currenTime.value = getCurrentDateTime()
})
const onPrintSubmit = async () => {
const element = receipt.value;
const elementWidth = element.offsetWidth;
const elementHeight = element.offsetHeight;
const scale = 12; // 缩小比例 我是在小票机上打印的 应该是 缩放比例越小打印的越清晰 当然了 加载的时候就会略慢一下
const canvasWidth = elementWidth * scale;
const canvasHeight = elementHeight * scale;
html2canvas(element, { scale }).then((canvas) => {
const imgData = canvas.toDataURL("image/png");
const pdf = new jsPDF({
orientation: "p",
unit: "px",
});
const pageWidth = pdf.internal.pageSize.getWidth();
const pageHeight = pdf.internal.pageSize.getHeight();
// 计算比例,保持图片等比例缩放
const ratio = Math.min(pageWidth / canvasWidth, pageHeight / canvasHeight);
const imgWidth = canvasWidth * ratio;
const imgHeight = canvasHeight * ratio;
// 居中显示图片
const x = (pageWidth - imgWidth) / 2;
const y = (pageHeight - imgHeight) / 2;
// X Y
pdf.addImage(imgData, "PNG", 15, 20, imgWidth / 2.8, imgHeight / 2.8);
// 解释一下为什么这里要/2.8 比如 打印在A4上面 W是21 但是图片是41的话 这时候 你就要自己去等比的缩放了
pdf.autoPrint();
const pdfURL = pdf.output("bloburl");
const printWindow = window.open(pdfURL, "_blank");
printWindow.focus();
}).catch((error) => {
console.error("打印失败:", error);
});
}
</script>
<style scoped>
.body {
margin: 0;
}
.printBtn {
margin: 0 auto;
}
.line {
margin-top: 6px;
width: 100%;
height: 1px;
border-bottom: 1px dotted #000000;
}
.shopName {
width: 260px;
text-align: center;
font-weight: bold;
font-size: 20px
}
.totalIncome {
padding: 0;
width: 260px;
margin: 0 auto 0;
text-align: center;
font-size: 14px
}
.prinitTime {
font-size: 16PX;
margin-top: 4px;
}
.receipt {
font-family: Microsoft Sans-serif;
color: #000;
width: 100%;
max-height: 700px;
}
.receipt h2 {
text-align: center;
margin-bottom: 20px;
}
.receipt .section {
margin-bottom: 20px;
}
.receipt .section .label {
font-weight: bold;
}
.receipt .section .value {
margin-left: 10px;
}
.receipt .total {
font-weight: bold;
font-size: 1.2em;
}
.receipt .items .table {
margin-top: 20px;
width: 100%;
border-collapse: collapse;
}
.table .title,
.table .column {
font-family: Microsoft Sans-serif;
display: flex;
}
.table .label1 {
width: 160px;
font-size: 16px;
}
.table .label2,
.table .label3 {
width: 90px;
font-size: 16px;
text-align: right;
}
/* 打印样式 */
@media print {
.print-button {
display: none;
}
.receipt {
width: 100%;
padding: 0;
margin: 0;
border: none;
font-size: 12px;
/* 调整字体大小 */
}
.receipt .items table th,
.receipt .items table td {
padding: 2px;
}
.receipt .section {
margin-bottom: 10px;
}
}
</style>