<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)可能在不同设备上显示不一致
-
边距控制需要更精细
-