代码demo:
javascript
<template>
<el-dialog class="storageExportDialog" :fullscreen="true" title="" :visible.sync="visible" v-if="visible" width="600px">
<div id="exportContainer" class="exportContainer">
<div id="exportContent0" class="exportContent" ref="exportContent0">
<div class="header">
<div class="left">{{ `Order: ${orderNmae}` }}</div>
<div class="right">{{ `1/${dataSlices.length+1}` }}</div>
</div>
<div class="data1">
<el-row>
<el-col :span="4" class="label">Wire End ID :</el-col>
<el-col :span="4" class="value">1</el-col>
<el-col :span="4" class="label">Wire ID :</el-col>
<el-col :span="4" class="value">2</el-col>
<el-col :span="4" class="label">Operator :</el-col>
<el-col :span="4" class="value">3</el-col>
</el-row>
<el-row>
<el-col :span="4" class="label">Wire End Description :</el-col>
<el-col :span="4" class="value">4</el-col>
<el-col :span="4" class="label">Wire Description :</el-col>
<el-col :span="4" class="value">5</el-col>
<el-col :span="4" class="label">Good :</el-col>
<el-col :span="4" class="value">6</el-col>
</el-row>
<el-row>
<el-col :span="4" class="label">Terminal ID :</el-col>
<el-col :span="4" class="value">7</el-col>
<el-col :span="4" class="label">Seal ID :</el-col>
<el-col :span="4" class="value">8</el-col>
<el-col :span="4" class="label">Bad :</el-col>
<el-col :span="4" class="value">9</el-col>
</el-row>
<el-row>
<el-col :span="4" class="label">Terminal Description : </el-col>
<el-col :span="4" class="value">10</el-col>
<el-col :span="4" class="label">Seal Description :</el-col>
<el-col :span="4" class="value">11</el-col>
<el-col :span="4" class="label">Total :</el-col>
<el-col :span="4" class="value">12</el-col>
</el-row>
</div>
<div class="data2">
<el-row>
<el-col :span="6" class="title">Tolerance</el-col>
</el-row>
<el-row>
<el-col :span="3" class="label">ATOL+: </el-col>
<el-col :span="3" class="value">5.0 %</el-col>
<el-col :span="3" class="label">STOL+: </el-col>
<el-col :span="3" class="value">10 %</el-col>
<el-col :span="3" class="label">ZONE 1:</el-col>
<el-col :span="3" class="value">20 pts</el-col>
<el-col :span="3" class="label">Z1TOL+:</el-col>
<el-col :span="3" class="value">25 %</el-col>
</el-row>
<el-row>
<el-col :span="3" class="label">ATOL-: </el-col>
<el-col :span="3" class="value">3.0 %</el-col>
<el-col :span="3" class="label">STOL-: </el-col>
<el-col :span="3" class="value">4 %</el-col>
<el-col :span="3" class="label">Filter: </el-col>
<el-col :span="3" class="value">35 %</el-col>
<el-col :span="3" class="label">Z1TOL-:</el-col>
<el-col :span="3" class="value">90 %</el-col>
</el-row>
</div>
<div class="data3">
<el-row>
<el-col :span="6" class="title">Tolerance</el-col>
</el-row>
<el-row>
<el-col :span="4" class="label">Crimp Height:</el-col>
<el-col :span="20" class="value">0.000 mm (+0.000 mm/-0.000 mm)</el-col>
</el-row>
<el-row>
<el-col :span="4" class="label">Crimp Height:</el-col>
<el-col :span="20" class="value">0.000 mm (+0.000 mm/-0.000 mm)</el-col>
</el-row>
<el-row>
<el-col :span="4" class="label">Min Pull Force:</el-col>
<el-col :span="20" class="value">0.0 N</el-col>
</el-row>
</div>
<div class="data4">
<el-row>
<el-col :span="6" class="title">Quality Verification</el-col>
<el-col :span="6">(Samples: 0)</el-col>
</el-row>
<el-row>
<el-col :span="1" class="label"></el-col>
<el-col :span="3" class="label">Crimp Height</el-col>
<el-col :span="3" class="label">Crimp Width</el-col>
<el-col :span="3" class="label">Pull Force</el-col>
</el-row>
</div>
<div class="data5">
<div class="chart1" ref="chart1"></div>
<div class="chart2" ref="chart2"></div>
</div>
<div class="data6">
<div class="chart3" ref="chart3"></div>
</div>
<div class="data7">
<div class="chart4" ref="chart4"></div>
</div>
</div>
<div v-for="(slice, index) in dataSlices" :key="index" :id="`exportContent${index+1}`" class="exportContent" :ref="`exportContent${index+1}`">
<div class="header">
<div class="left">{{ `Order: ${orderNmae}` }}</div>
<div class="right">{{ `${index+2}/${dataSlices.length+1}` }}</div>
</div>
<el-table class="dataTable" ref="dataTable" :data="slice" style="width: 100%;" stripe>
<el-table-column align="center" prop="index" label="No."></el-table-column>
<el-table-column align="center" prop="x" label="X Val"></el-table-column>
<el-table-column align="center" prop="date" label="Date"></el-table-column>
<el-table-column align="center" prop="time" label="Time"></el-table-column>
</el-table>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="success" @click="exportFn" icon="el-icon-printer" plain>导出</el-button>
<el-button type="danger" @click="visible = false" icon="el-icon-close" plain>关闭</el-button>
</div>
</el-dialog>
</template>
<script>
import { getCurrentDateTime } from "@/utils/common.js"
import * as echarts from "echarts";
import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'
export default {
name: 'storageExport',
data() {
return {
orderNmae: "test",
chunkSize: 44, // 表格每页行数
loading: null,
chart1: null,
chart2: null,
chart3: null,
chart4: null,
visible: false,
printTableData: [],
}
},
watch: {
visible() {
if (this.visible == true) {
this.initDataChart();
} else {
this.chart.dispose();
this.chart = null;
}
}
},
computed: {
dataSlices() {
const slices = [];
for (let i = 0; i < this.printTableData.length; i += this.chunkSize) {
slices.push(this.printTableData.slice(i, i + this.chunkSize));
}
return slices;
}
},
mounted() {
for (let i = 1; i <= 100; i++) {
this.printTableData.push({ index: i, date: "2024-09-09", time: "15:13:15", x: "1.5" },)
}
},
beforeDestroy() {
},
methods: {
initDataChart() {
this.$nextTick(() => {
this.chart1 = echarts.init(this.$refs['chart1']);
this.chart2 = echarts.init(this.$refs['chart2']);
this.chart3 = echarts.init(this.$refs['chart3']);
this.chart4 = echarts.init(this.$refs['chart4']);
let option = {
grid: {
left: '10%',
right: '10%',
bottom: '10%',
top: '10%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
smooth: true
}
]
};
this.chart1.setOption(option);
this.chart2.setOption(option);
this.chart3.setOption(option);
this.chart4.setOption(option);
})
},
exportFn() {
this.showLoading();
console.log("导出");
try {
const pdf = new jsPDF('p', 'mm', 'a4');
let imgs = [];
let list = document.querySelectorAll('.exportContent');
let addPromises = [];
for (let i = 0; i < list.length; i++) {
let img = list[i];
let addPromise = new Promise((resolve, reject) => {
html2canvas(img, { scale: 2 }).then((canvas) => {
imgs.push(canvas)
resolve();
})
});
addPromises.push(addPromise);
}
Promise.all(addPromises).then(() => {
console.log("imgs", imgs);
imgs.forEach((img, index) => {
const imgData = img.toDataURL('image/webp');
pdf.addImage(imgData, 'WEBP', 0, 0, 210, 297);
if (index < imgs.length - 1) {
pdf.addPage();
}
})
this.savePdfFile(pdf);
}).finally(() => {
this.closeLoading();
})
} catch (e) {
console.log("导出失败", e);
this.closeLoading();
}
},
showLoading() {
this.loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.5)'
});
},
closeLoading() {
this.loading.close();
},
savePdfFile(pdf) {
const pdfBlob = pdf.output('blob');
const pdfUrl = URL.createObjectURL(pdfBlob);
const fileName = `${getCurrentDateTime()}.pdf`; // 自定义文件名
const link = document.createElement('a');
link.href = pdfUrl;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
let timer = setTimeout(() => {
URL.revokeObjectURL(pdfUrl);
clearTimeout(timer);
}, 1000 * 10); // 10s 后释放 URL
}
}
}
</script>
<style lang="scss" scoped>
::v-deep.storageExportDialog {
.el-dialog__footer {
position: fixed;
top: 0;
right: 0;
padding: 5px;
}
}
::v-deep.exportContainer {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.exportContent {
width: 210mm;
height: 297mm;
border: 0.1px solid #ccc;
overflow: scroll;
.header {
width: 100%;
height: 10mm;
display: flex;
justify-content: space-between;
align-items: center;
border: 0.1px solid #ccc;
.left {
padding: 1mm;
font-size: 18px;
font-weight: bold;
}
.right {
padding: 1mm;
font-size: 12px;
}
}
.data1 {
width: 100%;
height: 30mm;
border: 0.1px solid #ccc;
font-size: 12px;
font-weight: bolder;
.label {
height: 7.5mm;
line-height: 7.5mm;
text-align: right;
}
.value {
height: 7.5mm;
line-height: 7.5mm;
padding-left: 2mm;
text-align: left;
}
}
.data2 {
width: 100%;
height: 20mm;
font-size: 12px;
.title {
height: 5mm;
padding-left: 3mm;
line-height: 5mm;
font-weight: bolder;
}
.label {
height: 7.5mm;
line-height: 7.5mm;
text-align: right;
}
.value {
height: 7.5mm;
line-height: 7.5mm;
padding-left: 2mm;
text-align: left;
}
}
.data3 {
width: 100%;
height: 25mm;
font-size: 12px;
.title {
height: 4mm;
padding-left: 3mm;
line-height: 4mm;
font-weight: bolder;
}
.label {
height: 7mm;
line-height: 7mm;
text-align: right;
}
.value {
height: 7mm;
line-height: 7mm;
padding-left: 2mm;
text-align: left;
}
}
.data4 {
width: 100%;
height: 10mm;
font-size: 12px;
.title {
height: 4mm;
padding-left: 3mm;
line-height: 4mm;
font-weight: bolder;
}
.label {
height: 6mm;
line-height: 6mm;
text-align: center;
}
}
.data5 {
height: 65mm;
width: 100%;
display: flex;
border-bottom: 0.1px solid #ccc;
.chart1,
.chart2 {
height: 65mm;
width: 50%;
}
}
.data6 {
height: 65mm;
width: 100%;
.chart3 {
height: 65mm;
width: 100%;
}
}
.data7 {
height: 65mm;
width: 100%;
.chart4 {
height: 65mm;
width: 100%;
}
}
.dataTable {
.el-table__cell {
padding: 0;
font-size: 12px;
}
}
}
}
</style>
页面效果:
导出效果: