> 文章列表 > Vue(十七):利用 html2canvas、JsPDF 依赖实现打印功能

Vue(十七):利用 html2canvas、JsPDF 依赖实现打印功能

Vue(十七):利用 html2canvas、JsPDF 依赖实现打印功能

效果

Vue(十七):利用 html2canvas、JsPDF 依赖实现打印功能

主程序

<!-- 打印区域 -->
<el-container ref="PdfPage"><!-- 过滤打印按钮 --><el-button type="primary" data-html2canvas-ignore='true' @click="printPage">打印</el-button><el-main><!-- 滚动区域 --><el-row ref="Content" :gutter="20">......</el-row></el-main>
</el-container><script>
import html2canvas from 'html2canvas';
import JsPDF from 'jspdf';export default {name: "Home",methods: {printPage() {const elRef = this.$refs['PdfPage'].$el;const contentRef = this.$refs['Content'].$el;const options = {// width: elRef.clientWidth,// height: contentRef.clientHeight + 160,windowHeight: contentRef.clientHeight + 160,}html2canvas(elRef, options).then(canvas => {const [w, h] = [595.28, 841.89];const [cw, ch] = [canvas.width, canvas.height];const PDF = new JsPDF('p', 'pt', 'a4');const pageData = canvas.toDataURL('image/jpeg', 1.0);PDF.addImage(pageData, 'JPEG', 0, (h - ch / (cw / w)) / 2, w, ch / (cw / w));PDF.save('00.pdf');})},},
}
</script>

源码

<template><el-container class="Home"><el-aside width="240px"><el-menu default-active="1-4-1" background-color="transparent"><el-submenu index="1"><template slot="title"><i class="el-icon-location"></i><span>导航一</span></template><el-menu-item-group><template slot="title">分组一</template><el-menu-item index="1-1">选项1</el-menu-item><el-menu-item index="1-2">选项2</el-menu-item></el-menu-item-group><el-menu-item-group title="分组2"><el-menu-item index="1-3">选项3</el-menu-item></el-menu-item-group><el-submenu index="1-4"><template slot="title">选项4</template><el-menu-item index="1-4-1">选项1</el-menu-item></el-submenu></el-submenu><el-menu-item index="2"><i class="el-icon-menu"></i><span slot="title">导航二</span></el-menu-item><el-menu-item index="3"><i class="el-icon-document"></i><span slot="title">导航三</span></el-menu-item><el-menu-item index="4"><i class="el-icon-setting"></i><span slot="title">导航四</span></el-menu-item></el-menu></el-aside><el-container ref="PdfPage"><el-header><el-row type="flex" align="middle"><el-col :span="20"><el-page-header content="详情页面" /></el-col><el-col :span="4" align="right"><el-button type="primary" data-html2canvas-ignore='true' @click="printPage">打印</el-button></el-col></el-row></el-header><el-main><el-row ref="Content" :gutter="20"><el-col :span="12"><v-chart class="chart" :option="option1" autoresize /></el-col><el-col :span="12"><v-chart class="chart" :option="option2" autoresize /></el-col><el-col :span="24"><v-chart class="chart" :option="option3" autoresize /></el-col></el-row></el-main><el-footer>Hello Lee!!!</el-footer></el-container></el-container>
</template><script>
import { use } from "echarts/core";
import { CanvasRenderer } from "echarts/renderers";
import { PieChart, LineChart, BarChart } from "echarts/charts";
import {TitleComponent,TooltipComponent,LegendComponent,ToolboxComponent,GridComponent,
} from "echarts/components";
import VChart, { THEME_KEY } from "vue-echarts";import html2canvas from 'html2canvas';
import JsPDF from 'jspdf';export default {name: "Home",components: {VChart},provide: {[THEME_KEY]: "default"},data() {use([CanvasRenderer,LineChart,PieChart,BarChart,TitleComponent,TooltipComponent,LegendComponent,ToolboxComponent,GridComponent,]);return {option1: {title: {text: "Traffic Sources",left: "center"},tooltip: {trigger: "item",formatter: "{a} <br/>{b} : {c} ({d}%)"},legend: {orient: "vertical",left: "left",data: ["Direct","Email","Ad Networks","Video Ads","Search Engines"]},series: [{name: "Traffic Sources",type: "pie",radius: "55%",center: ["50%", "60%"],data: [{ value: 335, name: "Direct" },{ value: 310, name: "Email" },{ value: 234, name: "Ad Networks" },{ value: 135, name: "Video Ads" },{ value: 1548, name: "Search Engines" }],emphasis: {itemStyle: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: "rgba(0, 0, 0, 0.5)"}}}]},option2: {color: ['#80FFA5', '#00DDFF', '#37A2FF', '#FF0087', '#FFBF00'],title: {text: 'Gradient Stacked Area Chart'},tooltip: {trigger: 'axis',axisPointer: {type: 'cross',label: {backgroundColor: '#6a7985'}}},legend: {bottom: '0',data: ['Line 1', 'Line 2', 'Line 3', 'Line 4', 'Line 5']},toolbox: {feature: {saveAsImage: {}}},grid: {left: '3%',right: '4%',bottom: '5%',containLabel: true},xAxis: [{type: 'category',boundaryGap: false,data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']}],yAxis: [{type: 'value'}],series: [{name: 'Line 1',type: 'line',stack: 'Total',smooth: true,lineStyle: {width: 0},showSymbol: false,areaStyle: {opacity: 0.8,},emphasis: {focus: 'series'},data: [140, 232, 101, 264, 90, 340, 250]},{name: 'Line 2',type: 'line',stack: 'Total',smooth: true,lineStyle: {width: 0},showSymbol: false,areaStyle: {opacity: 0.8,},emphasis: {focus: 'series'},data: [120, 282, 111, 234, 220, 340, 310]},{name: 'Line 3',type: 'line',stack: 'Total',smooth: true,lineStyle: {width: 0},showSymbol: false,areaStyle: {opacity: 0.8,},emphasis: {focus: 'series'},data: [320, 132, 201, 334, 190, 130, 220]},{name: 'Line 4',type: 'line',stack: 'Total',smooth: true,lineStyle: {width: 0},showSymbol: false,areaStyle: {opacity: 0.8,},emphasis: {focus: 'series'},data: [220, 402, 231, 134, 190, 230, 120]},{name: 'Line 5',type: 'line',stack: 'Total',smooth: true,lineStyle: {width: 0},showSymbol: false,label: {show: true,position: 'top'},areaStyle: {opacity: 0.8,},emphasis: {focus: 'series'},data: [220, 302, 181, 234, 210, 290, 150]}]},option3: (function () {const builderJson = {all: 10887,charts: {map: 3237,lines: 2164,bar: 7561,line: 7778,pie: 7355,scatter: 2405,candlestick: 1842,radar: 2090,heatmap: 1762,treemap: 1593,graph: 2060,boxplot: 1537,parallel: 1908,gauge: 2107,funnel: 1692,sankey: 1568},components: {geo: 2788,title: 9575,legend: 9400,tooltip: 9466,grid: 9266,markPoint: 3419,markLine: 2984,timeline: 2739,dataZoom: 2744,visualMap: 2466,toolbox: 3034,polar: 1945},ie: 9743};const downloadJson = {'echarts.min.js': 17365,'echarts.simple.min.js': 4079,'echarts.common.min.js': 6929,'echarts.js': 14890};const themeJson = {'dark.js': 1594,'infographic.js': 925,'shine.js': 1608,'roma.js': 721,'macarons.js': 2179,'vintage.js': 1982};const waterMarkText = 'ECHARTS';const canvas = document.createElement('canvas');const ctx = canvas.getContext('2d');canvas.width = canvas.height = 100;ctx.textAlign = 'center';ctx.textBaseline = 'middle';ctx.globalAlpha = 0.08;ctx.font = '20px Microsoft Yahei';ctx.translate(50, 50);ctx.rotate(-Math.PI / 4);ctx.fillText(waterMarkText, 0, 0);let option = {backgroundColor: {type: 'pattern',image: canvas,repeat: 'repeat'},tooltip: {},title: [{text: '在线构建',subtext: '总计 ' + builderJson.all,left: '25%',textAlign: 'center'},{text: '各版本下载',subtext:'总计 ' +Object.keys(downloadJson).reduce(function (all, key) {return all + downloadJson[key];}, 0),left: '75%',textAlign: 'center'},{text: '主题下载',subtext:'总计 ' +Object.keys(themeJson).reduce(function (all, key) {return all + themeJson[key];}, 0),left: '75%',top: '50%',textAlign: 'center'}],grid: [{top: 50,width: '50%',bottom: '45%',left: 10,containLabel: true},{top: '55%',width: '50%',bottom: 0,left: 10,containLabel: true}],xAxis: [{type: 'value',max: builderJson.all,splitLine: {show: false}},{type: 'value',max: builderJson.all,gridIndex: 1,splitLine: {show: false}}],yAxis: [{type: 'category',data: Object.keys(builderJson.charts),axisLabel: {interval: 0,rotate: 30},splitLine: {show: false}},{gridIndex: 1,type: 'category',data: Object.keys(builderJson.components),axisLabel: {interval: 0,rotate: 30},splitLine: {show: false}}],series: [{type: 'bar',stack: 'chart',z: 3,label: {position: 'right',show: true},data: Object.keys(builderJson.charts).map(function (key) {return builderJson.charts[key];})},{type: 'bar',stack: 'chart',silent: true,itemStyle: {color: '#eee'},data: Object.keys(builderJson.charts).map(function (key) {return builderJson.all - builderJson.charts[key];})},{type: 'bar',stack: 'component',xAxisIndex: 1,yAxisIndex: 1,z: 3,label: {position: 'right',show: true},data: Object.keys(builderJson.components).map(function (key) {return builderJson.components[key];})},{type: 'bar',stack: 'component',silent: true,xAxisIndex: 1,yAxisIndex: 1,itemStyle: {color: '#eee'},data: Object.keys(builderJson.components).map(function (key) {return builderJson.all - builderJson.components[key];})},{type: 'pie',radius: [0, '30%'],center: ['75%', '25%'],data: Object.keys(downloadJson).map(function (key) {return {name: key.replace('.js', ''),value: downloadJson[key]};})},{type: 'pie',radius: [0, '30%'],center: ['75%', '75%'],data: Object.keys(themeJson).map(function (key) {return {name: key.replace('.js', ''),value: themeJson[key]};})}]};return option;})(),}},methods: {printPage() {const elRef = this.$refs['PdfPage'].$el;const contentRef = this.$refs['Content'].$el;const options = {// width: elRef.clientWidth,// height: contentRef.clientHeight + 160,windowHeight: contentRef.clientHeight + 160,}html2canvas(elRef, options).then(canvas => {const [w, h] = [595.28, 841.89];const [cw, ch] = [canvas.width, canvas.height];const PDF = new JsPDF('p', 'pt', 'a4');const pageData = canvas.toDataURL('image/jpeg', 1.0);PDF.addImage(pageData, 'JPEG', 0, (h - ch / (cw / w)) / 2, w, ch / (cw / w));PDF.save('00.pdf');})},},
}
</script><style lang="less" scoped>
.Home {position: relative;width: 100%;height: 100%;.el-header {background-color: #B3C0D1;.el-row {height: 100%;}}.el-footer {background-color: #B3C0D1;line-height: 60px;}.el-aside {background-color: #D3DCE6;}.el-main {background-color: #E9EEF3;}.chart {height: 500px;}
}
</style>