<template><div><divref="pdfContent"style="position: relative; width: 800px; margin: 0 auto"><!-- ECharts 圖表 --><div id="chart" style="width: 100%; height: 400px" /><!-- Element UI 表格 --><el-tableref="myTable":data="tableData"style="width: 100%; margin-top: 20px"borderstripe><el-table-column prop="date" label="日期" width="180" /><el-table-column prop="name" label="姓名" width="180" /><el-table-column prop="address" label="地址" /></el-table></div><button @click="exportPDF">導出PDF</button></div>
</template><script>
import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'
import * as echarts from 'echarts'
import 'element-ui/lib/theme-chalk/index.css' // 確保引入了Element UI的樣式export default {data() {return {tableData: [{date: '2016-05-02',name: '王小虎',address: '上海市普陀區金沙江路 1518 弄'},{date: '2016-05-02',name: '王小虎',address: '上海市普陀區金沙江路 1518 弄'},{date: '2016-05-02',name: '王小虎',address: '上海市普陀區金沙江路 1518 弄'},{date: '2016-05-02',name: '王小虎',address: '上海市普陀區金沙江路 1518 弄'},{date: '2016-05-02',name: '王小虎',address: '上海市普陀區金沙江路 1518 弄'},{date: '2016-05-02',name: '王小虎',address: '上海市普陀區金沙江路 1518 弄'},{date: '2016-05-02',name: '王小虎',address: '上海市普陀區金沙江路 1518 弄'},{date: '2016-05-02',name: '王小虎',address: '上海市普陀區金沙江路 1518 弄'},{date: '2016-05-02',name: '王小虎',address: '上海市普陀區金沙江路 1518 弄'},{date: '2016-05-02',name: '王小虎',address: '上海市普陀區金沙江路 1518 弄'},{date: '2016-05-02',name: '王小虎',address: '上海市普陀區金沙江路 1518 弄'}],tableDataeer: [{date: '2016-05-02',name: [{ add: '數據', cs: '23' },{ add: '數據1', cs: '23' }],address: '上海市普陀區金沙江路 1518 弄'},{date: '2016-05-02',name: [{ add: '數據1', cs: '231' },{ add: '數據11', cs: '231' }],address: '上海市普陀區金沙江路 1518 弄'}]}},mounted() {this.initChart()},methods: {initChart() {const chartDom = document.getElementById('chart')const myChart = echarts.init(chartDom)const option = {title: {text: 'Referer of a Website',subtext: 'Fake Data',left: 'center'},tooltip: {trigger: 'item'},legend: {orient: 'vertical',left: 'right',overflow: 'truncate', // 超出部分截斷ellipsis: '...' // 顯示省略號},series: [{name: 'Access From',type: 'pie',radius: '50%',data: [{ value: 1048, name: 'Search Engine' },{ value: 735, name: 'Direct' },{ value: 580, name: 'Email' },{ value: 484, name: 'Union Ads' },{ value: 300, name: 'Video Ads' }],emphasis: {itemStyle: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)'}}}]}myChart.setOption(option)},exportPDF() {const element = this.$refs.pdfContenthtml2canvas(element).then((canvas) => {const imgData = canvas.toDataURL('image/png')// eslint-disable-next-line new-capconst pdf = new jsPDF({orientation: 'portrait',unit: 'pt',format: 'a4'})const imgProps = pdf.getImageProperties(imgData)const margin = 20 // 設置頁邊距const pdfWidth = pdf.internal.pageSize.getWidth() - margin * 2 // 減去左右邊距const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width // 按比例計算高度let position = margin // 初始Y位置(頂部邊距)let remainingHeight = pdfHeight // 剩余需要渲染的高度while (remainingHeight > 0) {// 當前頁可用的高度(減去上下邊距)const pageHeight = pdf.internal.pageSize.getHeight() - margin// 計算本次渲染的高度(不能超過頁面剩余高度)const renderHeight = Math.min(remainingHeight, pageHeight - position)// 添加圖像部分pdf.addImage(imgData,'PNG',margin, // x位置(左邊距)position - (remainingHeight - pdfHeight), // y位置(考慮偏移)pdfWidth,renderHeight,null,'FAST' // 使用FAST模式提高性能)remainingHeight -= renderHeightposition += renderHeight// 如果還有內容未渲染,添加新頁面if (remainingHeight > 0) {pdf.addPage()position = margin // 新頁面從頂部邊距開始}}pdf.save('chart_and_table.pdf')})}}
}
</script><style scoped>
/* 你的樣式 */
</style>
主要需要處理的問題:
-
內容截斷問題:
-
當內容超過一頁時,分頁邏輯可能會導致內容被截斷在頁面中間
-
特別是表格行可能會被不自然地分割在兩頁之間
-
-
樣式完整性問題:
-
Element UI表格的樣式可能在PDF中顯示不完整
-
ECharts圖表在高分辨率導出時可能模糊
-
-
性能優化:
-
對于大量數據,html2canvas渲染可能較慢
-
PDF生成過程可能阻塞UI
-
-
布局適應性:
-
固定寬度(800px)可能在不同設備上顯示不一致
-
邊距控制需要更精細
-