4 changed files with 681 additions and 24 deletions
@ -0,0 +1,437 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-button @click="generateAndPrintPDF">打印</el-button> |
||||||
|
<div id="printArea" class="report"> |
||||||
|
<h2 class="title">北京比塔技术服务有限公司</h2> |
||||||
|
<h3 class="subtitle">出厂检验报告</h3> |
||||||
|
|
||||||
|
<table class="table"> |
||||||
|
<tr> |
||||||
|
<td>产品名称</td> |
||||||
|
<td>边缘控制器</td> |
||||||
|
<td>报告编号</td> |
||||||
|
<td>20240311-M001</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td>规格型号</td> |
||||||
|
<td>BICON-CCU-M</td> |
||||||
|
<td>日期</td> |
||||||
|
<td>2024.3.11</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td>本批检验数量</td> |
||||||
|
<td>1</td> |
||||||
|
<td>设备编号</td> |
||||||
|
<td>CCU-M-01-2403-020026</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
|
||||||
|
<h4 class="result">检查结果</h4> |
||||||
|
<table class="table result-table"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th class="index">项次</th> |
||||||
|
<th class="project">检验项目</th> |
||||||
|
<th class="content">检验内容</th> |
||||||
|
<th class="consequence">检验结果</th> |
||||||
|
<th class="decide">判定</th> |
||||||
|
<th class="remark">备注</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr> |
||||||
|
<td>1</td> |
||||||
|
<td>外观</td> |
||||||
|
<td>表面光滑无划伤,无明显凹凸不平,无污渍,腐蚀点及一致均匀,无色差</td> |
||||||
|
<td>✔</td> |
||||||
|
<td>合格</td> |
||||||
|
<td></td> |
||||||
|
</tr> |
||||||
|
|
||||||
|
<tr> |
||||||
|
<!-- rowspan="3" 动态生成 --> |
||||||
|
<td rowspan="3">2</td> |
||||||
|
<td rowspan="3">电气性能</td> |
||||||
|
<td>尺寸与图纸要求一致</td> |
||||||
|
<td>103*147*41mm</td> |
||||||
|
<td>合格</td> |
||||||
|
<td></td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td>通信测试:电源电压正常指示灯指示</td> |
||||||
|
<td>✔</td> |
||||||
|
<td>合格</td> |
||||||
|
<td></td> |
||||||
|
</tr> |
||||||
|
|
||||||
|
<tr> |
||||||
|
<td>通信测试:电源电压正常指示灯指示</td> |
||||||
|
<td>✔</td> |
||||||
|
<td>合格</td> |
||||||
|
<td></td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
<table class="table res-table"> |
||||||
|
<tr> |
||||||
|
<td class="conclusion" rowspan="2">建议结论</td> |
||||||
|
<td colspan="4">边缘控制器</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td class="inspector">检验员</td> |
||||||
|
<td class="value">xs</td> |
||||||
|
<td class="data">检验日期</td> |
||||||
|
<td class="value">2024.12.2</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
<table class="table res-table"> |
||||||
|
<tr> |
||||||
|
<td class="conclusion" rowspan="2">建议结论</td> |
||||||
|
<td colspan="4">边缘控制器</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td class="inspector">检验员</td> |
||||||
|
<td class="value">xs</td> |
||||||
|
<td class="data">检验日期</td> |
||||||
|
<td class="value">2024.12.2</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
<table class="table res-table"> |
||||||
|
<tr> |
||||||
|
<td class="conclusion" rowspan="2">建议结论</td> |
||||||
|
<td colspan="4">边缘控制器</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td class="inspector">检验员</td> |
||||||
|
<td class="value">xs</td> |
||||||
|
<td class="data">检验日期</td> |
||||||
|
<td class="value">2024.12.2</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
<table class="table res-table"> |
||||||
|
<tr> |
||||||
|
<td class="conclusion" rowspan="2">建议结论</td> |
||||||
|
<td colspan="4">边缘控制器</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td class="inspector">检验员</td> |
||||||
|
<td class="value">xs</td> |
||||||
|
<td class="data">检验日期</td> |
||||||
|
<td class="value">2024.12.2</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
<table class="table res-table"> |
||||||
|
<tr> |
||||||
|
<td class="conclusion" rowspan="2">建议结论</td> |
||||||
|
<td colspan="4">边缘控制器</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td class="inspector">检验员</td> |
||||||
|
<td class="value">xs</td> |
||||||
|
<td class="data">检验日期</td> |
||||||
|
<td class="value">2024.12.2</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
<table class="table res-table"> |
||||||
|
<tr> |
||||||
|
<td class="conclusion" rowspan="2">建议结论</td> |
||||||
|
<td colspan="4">边缘控制器</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td class="inspector">检验员</td> |
||||||
|
<td class="value">xs</td> |
||||||
|
<td class="data">检验日期</td> |
||||||
|
<td class="value">2024.12.2</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
<table class="table res-table"> |
||||||
|
<tr> |
||||||
|
<td class="conclusion" rowspan="2">建议结论</td> |
||||||
|
<td colspan="4">边缘控制器</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td class="inspector">检验员</td> |
||||||
|
<td class="value">xs</td> |
||||||
|
<td class="data">检验日期</td> |
||||||
|
<td class="value">2024.12.2</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
<table class="table res-table"> |
||||||
|
<tr> |
||||||
|
<td class="conclusion" rowspan="2">建议结论</td> |
||||||
|
<td colspan="4">边缘控制器</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td class="inspector">检验员</td> |
||||||
|
<td class="value">xs</td> |
||||||
|
<td class="data">检验日期</td> |
||||||
|
<td class="value">2024.12.2</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
<table class="table res-table"> |
||||||
|
<tr> |
||||||
|
<td class="conclusion" rowspan="2">建议结论</td> |
||||||
|
<td colspan="4">边缘控制器</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td class="inspector">检验员</td> |
||||||
|
<td class="value">xs</td> |
||||||
|
<td class="data">检验日期</td> |
||||||
|
<td class="value">2024.12.2</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
<table class="table res-table"> |
||||||
|
<tr> |
||||||
|
<td class="conclusion" rowspan="2">建议结论</td> |
||||||
|
<td colspan="4">边缘控制器</td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td class="inspector">检验员</td> |
||||||
|
<td class="value">xs</td> |
||||||
|
<td class="data">检验日期</td> |
||||||
|
<td class="value">2024.12.2</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
<div class="footer"> |
||||||
|
<span>电话: 010 - 82736682</span> |
||||||
|
<span>地址: 北京市海淀区信息路28号上地信息大厦B座901</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script setup lang="ts"> |
||||||
|
import html2canvas from 'html2canvas' |
||||||
|
import jsPDF from 'jspdf' |
||||||
|
|
||||||
|
async function generateAndPrintPDF() { |
||||||
|
const printArea = document.getElementById('printArea') |
||||||
|
if (!printArea) { |
||||||
|
console.error('打印区域未找到') |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
// 将 HTML 内容转为 Canvas |
||||||
|
const canvas = await html2canvas(printArea, { |
||||||
|
scale: window.devicePixelRatio * 2, |
||||||
|
}) |
||||||
|
|
||||||
|
// 获取 Canvas 的宽高 |
||||||
|
const canvasWidth = canvas.width |
||||||
|
const canvasHeight = canvas.height |
||||||
|
|
||||||
|
// 将 Canvas 转为图片数据 |
||||||
|
const imgData = canvas.toDataURL('image/jpeg', 1.0) |
||||||
|
|
||||||
|
// 创建 jsPDF 实例 |
||||||
|
const pdf = new jsPDF('p', 'mm', 'a4') |
||||||
|
const pdfWidth = pdf.internal.pageSize.getWidth() // PDF 页面的宽度 |
||||||
|
const pdfHeight = pdf.internal.pageSize.getHeight() // PDF 页面的高度 |
||||||
|
|
||||||
|
const headerHeight = 20 // Header 高度 |
||||||
|
const footerHeight = 20 // Footer 高度 |
||||||
|
const contentHeight = pdfHeight - headerHeight - footerHeight // 内容区域高度 |
||||||
|
|
||||||
|
// 计算 PDF 中图片的等比例高度 |
||||||
|
const imgHeight = (canvasHeight * pdfWidth) / canvasWidth |
||||||
|
|
||||||
|
// 如果内容高度小于一页,直接添加到 PDF |
||||||
|
if (imgHeight <= contentHeight) { |
||||||
|
pdf.text('Header Title', pdfWidth / 2, headerHeight / 2, { align: 'center' }) // 添加 Header |
||||||
|
pdf.addImage(imgData, 'JPEG', 0, headerHeight, pdfWidth, imgHeight) |
||||||
|
pdf.text('Footer Text', pdfWidth / 2, pdfHeight - footerHeight / 2, { |
||||||
|
align: 'center', |
||||||
|
}) // 添加 Footer |
||||||
|
} else { |
||||||
|
// 分页逻辑 |
||||||
|
let position = 0 // 当前绘制的起始位置 |
||||||
|
while (position < canvasHeight) { |
||||||
|
const pageCanvas = document.createElement('canvas') |
||||||
|
pageCanvas.width = canvasWidth |
||||||
|
pageCanvas.height = (contentHeight * canvasWidth) / pdfWidth |
||||||
|
|
||||||
|
const pageCtx = pageCanvas.getContext('2d') |
||||||
|
pageCtx?.drawImage( |
||||||
|
canvas, |
||||||
|
0, |
||||||
|
position, // 从 Canvas 的哪部分开始截取 |
||||||
|
canvasWidth, |
||||||
|
pageCanvas.height, |
||||||
|
0, |
||||||
|
0, |
||||||
|
canvasWidth, |
||||||
|
pageCanvas.height |
||||||
|
) |
||||||
|
|
||||||
|
const pageImgData = pageCanvas.toDataURL('image/jpeg', 1.0) |
||||||
|
|
||||||
|
// 添加 Header |
||||||
|
pdf.text(' ', pdfWidth / 2, headerHeight / 2, { align: 'center' }) |
||||||
|
|
||||||
|
// 添加当前页到 PDF |
||||||
|
pdf.addImage(pageImgData, 'JPEG', 0, headerHeight, pdfWidth, contentHeight) |
||||||
|
|
||||||
|
// 添加 Footer |
||||||
|
pdf.text(' ', pdfWidth / 2, pdfHeight - footerHeight / 2, { |
||||||
|
align: 'center', |
||||||
|
}) |
||||||
|
|
||||||
|
position += pageCanvas.height // 更新绘制起点 |
||||||
|
|
||||||
|
// 如果还有内容未绘制,添加新页 |
||||||
|
if (position < canvasHeight) { |
||||||
|
pdf.addPage() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 打开 PDF 打印对话框 |
||||||
|
pdf.autoPrint() |
||||||
|
window.open(pdf.output('bloburl'), '_blank') |
||||||
|
} catch (error) { |
||||||
|
console.error('生成 PDF 时出错:', error) |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped lang="scss"> |
||||||
|
.report { |
||||||
|
width: 940px; |
||||||
|
margin: 0 auto; |
||||||
|
padding: 40px 20px; |
||||||
|
box-sizing: border-box; |
||||||
|
background-color: #fff; |
||||||
|
|
||||||
|
.title { |
||||||
|
text-align: center; |
||||||
|
font-size: 24px; |
||||||
|
margin-bottom: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
h1, |
||||||
|
h2, |
||||||
|
h3, |
||||||
|
h4 { |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.subtitle { |
||||||
|
font-size: 20px; |
||||||
|
height: 60px; |
||||||
|
line-height: 60px; |
||||||
|
text-align: center; |
||||||
|
border: 1px solid #000; |
||||||
|
border-bottom: none; |
||||||
|
} |
||||||
|
|
||||||
|
.table { |
||||||
|
width: 100%; |
||||||
|
border-collapse: collapse; |
||||||
|
|
||||||
|
thead, |
||||||
|
tbody { |
||||||
|
th, |
||||||
|
td { |
||||||
|
border: 1px solid #000; |
||||||
|
padding: 12px 18px; |
||||||
|
text-align: center; |
||||||
|
box-sizing: border-box; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.result { |
||||||
|
text-align: center; |
||||||
|
border: 1px solid #000; |
||||||
|
border-top: none; |
||||||
|
border-bottom: none; |
||||||
|
height: 50px; |
||||||
|
line-height: 50px; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
.result-table { |
||||||
|
width: 100%; |
||||||
|
border-collapse: collapse; |
||||||
|
|
||||||
|
thead, |
||||||
|
tbody { |
||||||
|
th, |
||||||
|
td { |
||||||
|
border: 1px solid #000; |
||||||
|
padding: 12px 18px; |
||||||
|
text-align: center; |
||||||
|
box-sizing: border-box; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
tr { |
||||||
|
.index { |
||||||
|
min-width: 40px; |
||||||
|
} |
||||||
|
|
||||||
|
.project { |
||||||
|
min-width: 80px; |
||||||
|
} |
||||||
|
|
||||||
|
.content { |
||||||
|
width: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.consequence { |
||||||
|
min-width: 40px; |
||||||
|
} |
||||||
|
|
||||||
|
.decide { |
||||||
|
min-width: 40px; |
||||||
|
} |
||||||
|
|
||||||
|
.remark { |
||||||
|
min-width: 120px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.res-table { |
||||||
|
width: 100%; |
||||||
|
border-collapse: collapse; |
||||||
|
|
||||||
|
thead, |
||||||
|
tbody { |
||||||
|
td { |
||||||
|
border: 1px solid #000; |
||||||
|
padding: 12px 18px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.conclusion { |
||||||
|
width: 63px; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
.value { |
||||||
|
width: 32%; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.footer { |
||||||
|
width: 100%; |
||||||
|
text-align: center; |
||||||
|
margin-top: 20px; |
||||||
|
font-size: 14px; |
||||||
|
line-height: 1.5; |
||||||
|
border-top: none; |
||||||
|
|
||||||
|
span { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
:last-child { |
||||||
|
margin-left: auto; |
||||||
|
margin-right: auto; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
Loading…
Reference in new issue