import { nextTick, computed } from 'vue'; import { useMainStore } from '@/store'; import { ElLoading } from 'element-plus'; import html2canvas from 'html2canvas'; import jsPDF from 'jspdf'; import { showMessage } from './common'; const mainStore = useMainStore(); const expanded = computed(() => mainStore.getExpanded); const isLoadOver = computed(() => mainStore.getIsLoadOver); export const downloadPDF = async (pdfContent?: HTMLElement) => { if (!isLoadOver.value) { showMessage({ type: 'warning', message: '数据加载中,请稍后再试' }); return; } const loading = ElLoading.service({ lock: true, text: '生成中...', background: 'rgba(0,0,0,0.7)', }); try { if (!pdfContent) pdfContent = document.querySelector('.record') as HTMLElement; if (!expanded.value) { mainStore.setExpanded(true); await nextTick(); } await nextTick(); // 高分辨率 canvas const canvas = await html2canvas(pdfContent, { scale: 2, useCORS: true, backgroundColor: '#fff' }); const canvasWidth = canvas.width; const canvasHeight = canvas.height; const pdf = new jsPDF('p', 'mm', 'a4'); const pageWidth = pdf.internal.pageSize.getWidth(); const pageHeight = pdf.internal.pageSize.getHeight(); const ratio = pageWidth / canvasWidth; // 宽度缩放比例 const pagePixelHeight = pageHeight / ratio; // PDF 一页对应 canvas 的高度 let positionY = 0; while (positionY < canvasHeight) { const h = Math.min(pagePixelHeight, canvasHeight - positionY); // 创建临时 canvas 截取当前页 const pageCanvas = document.createElement('canvas'); pageCanvas.width = canvasWidth; pageCanvas.height = h; const ctx = pageCanvas.getContext('2d'); ctx?.drawImage(canvas, 0, positionY, canvasWidth, h, 0, 0, canvasWidth, h); const imgData = pageCanvas.toDataURL('image/jpeg', 0.95); pdf.addImage(imgData, 'JPEG', 0, 0, pageWidth, h * ratio); positionY += h; if (positionY < canvasHeight) pdf.addPage(); } pdf.save('analysis.pdf'); } catch (error) { console.error(error); showMessage({ type: 'error', message: '生成失败,请稍后再试' }); } finally { mainStore.setExpanded(false); setTimeout(() => loading.close(), 500); } };