代码demo:
<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>
页面效果:
导出效果: