實際開發(fā)需求:vue項目中,根據(jù)數(shù)據(jù)結(jié)構(gòu)生成echarts圖表組件,生成帶有樣式的圖表以后,點擊下載按鈕,把圖表以pdf格式的文件下載到本地
實現(xiàn)思路:將vue界面的echarts組件生成圖片,然后使用插件將生成的圖片放入pdf中,再實現(xiàn)pdf文件的下載
涉及框架以及插件:vue、echarts、html2canvas、dom-to-image、jspdf
插件介紹:
vue、echarts 不用多說,vue前端的框架,echarts用來根據(jù)數(shù)據(jù)生成的帶有樣式效果的圖表;html2canvas與dom-to-image都是將界面上的dom生成圖片。
html2canvas
能夠?qū)崿F(xiàn)在用戶瀏覽器端直接對整個或部分頁面進行生成圖片,主要是將選中的頁面或者整個頁面渲染成一個canvas圖片,通過讀取DOM并將不同的樣式應(yīng)用到這些元素上實現(xiàn)??梢酝ㄟ^獲取HTML的某個元素,然后生成Canvas,從而生成圖片。
安裝
npm install --save html2canvas
或 yarn add html2canvas
引入
import html2canvas from 'html2canvas';
用法:
<div class="container" id="myDom1">
測試
</div>
<style>
.container {
width:100px;
height:100px;
background:red;
color: #ffffff;
}
</style>
methods(){
getImage(){
html2canvas(document.querySelector("#myDom1")).then(canvas => {
console.logo(canvas)
document.body.appendChild(canvas);
var dataUrl = canvas.toDataURL("image/png")
});
}
}
參數(shù)名稱 | 類型 | 默認(rèn)值 | 描述 |
---|---|---|---|
allowTaint | boolean | false | 允許跨域 |
background | string | #fff | canvas的背景顏色,如果沒有設(shè)定默認(rèn)透明 |
height | number | null | canvas高度設(shè)定 |
letterRendering | boolean | false | 在設(shè)置了字間距的時候有用 |
logging | boolean | false | 輸出信息 |
proxy | string | undefined | 代理地址 |
taintTest | boolean | true | 是否在渲染前測試圖片 |
timeout | number | 0 | 圖片加載延遲,默認(rèn)延遲為0,單位毫秒 |
width | number | null | canvas的寬度 |
useCORS | boolean | false | 圖片跨域問題 |
dom-to-image
它可以將任意DOM節(jié)點轉(zhuǎn)換成用JavaScript編寫的矢量(SVG)或光柵(PNG或JPEG)圖像。
安裝
npm install dom-to-image
或 yarn add dom-to-image
引入
import domtoimage from 'dom-to-image';
或 var domtoimage = require('dom-to-image');
基本用法:
<template>
<div id=""myDom>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
......
</div>
</template>
methods(){
getDomToImage(){
let dom = document.getElementById('myDom');
domtoimage.toPng(dom).then(function (dataUrl) {
var img = new Image();
img.src = dataUrl;
document.body.appendChild(img);
})
.catch(function (error) {
console.error('wrong!', error);
});
}
}
獲取一個png的blob:
domtoimage.toBlob(document.getElementById('myDom')).then(function (blob) {
console.log(blob)
});
jspdf
jsPDF 是一個使用 Javascript 語言生成 PDF 的開源庫。你可以在 Firefox 插件,服務(wù)端腳本或是瀏覽器腳本中使用它。
安裝:
npm install jspdf
或 yarn add jspdf
引入
import jsPDF from "jspdf"
基本用法:
let pdf = new jsPDF('p', 'pt', 'a4);
參數(shù)1:l:橫向 p:縱向
參數(shù)2:單位("pt","mm", "cm", "m", "in" or "px")
參數(shù)3:格式,默認(rèn)為“a4”
常用方法:文章來源:http://www.zghlxwxcb.cn/news/detail-822977.html
pdf.addPage() 在PDF文檔中添加新頁面,參數(shù)如下,也可以不設(shè)置,默認(rèn)a4
pdf.addImage() 將圖像添加到PDF中
pdf.save(`保存的PDF文件.pdf`); 保存為pdf格式的文件
回到需求:vue項目中,根據(jù)數(shù)據(jù)結(jié)構(gòu)生成echarts圖表組件,生成帶有樣式的圖表以后,點擊下載按鈕,把圖表以pdf格式的文件下載到本地(帶分頁),部分代碼如下(思路)文章來源地址http://www.zghlxwxcb.cn/news/detail-822977.html
1.使用html2canvas
<template>
<div id="pdfDom" ref="pdfDom">
// 此處存放界面中顯示的內(nèi)容區(qū)域,生成pdf的內(nèi)容區(qū)域......
</div>
</template>
methods(){
let node = document.getElementById('pdfDom');
html2canvas(document.getElementById('pdfDom'), {
scale: 2
}).then(function (canvas) {
var pdfWidth = canvas.width;
var pdfHeight = canvas.height;
var pageHeight = pdfWidth / 592.28 * 841.89;
var leftHeight = pdfHeight;
var position = 0;
var imgWidth = 595.28;
var imgHeight = 595.28 / pdfWidth * pdfHeight;
var pageData = canvas.toDataURL("img/jpeg", 1.0);
var pdf = new jsPDF('', 'pt', 'a4');
// 判斷打印dom高度是否需要分頁,如果需要進行分頁處理
if (leftHeight < pageHeight) {
pdf.addImage(pageData, "JPEG", 0, 0, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
pdf.addImage(pageData, "JPEG", 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
if (leftHeight > 0) {
pdf.addPage()
}
}
}
const aLink = document.createElement('a')
document.body.appendChild(aLink)
const url = URL.createObjectURL(_this.toBlob(pdf.output('datauristring')))
aLink.href = url
let date = new Date()
let year = date.getFullYear()
let month = (date.getMonth() + 1).toString().padStart(2, 0)
let day = date.getDate().toString().padStart(2, 0)
let hour = date.getHours().toString().padStart(2, 0)
let minutes = date.getMinutes().toString().padStart(2, 0)
let seconds = date.getSeconds().toString().padStart(2, 0)
aLink.download = '保存的PDF文件-' + '.pdf'
aLink.click()
window.URL.revokeObjectURL(url)
})
}
2.使用dom-to-image
<template>
<div id="pdfDom" ref="pdfDom">
// 此處存放界面中顯示的內(nèi)容區(qū)域,生成pdf的內(nèi)容區(qū)域......
</div>
</template>
methods(){
let node = document.getElementById('pdfDom');
domtoimage.toJpeg(node, {
width: node.clientWidth,
height: node.clientHeight,
cacheBust: true,
style: {
margin: 0,
background: '#fff',
}
}).then(function (dataUrl) {
console.log(node.clientWidth)
that.canvasWidth = node.clientWidth;
that.canvasHeight = node.clientHeight;
let imgObj = new Image()
imgObj.src = dataUrl;
document.documentElement.scrollTop = 0
//待圖片加載完后,將其顯示在canvas上
imgObj.onload = function (img) {
let canvas = document.getElementById("canvasDom");
console.log(canvas.width, canvas.height, 'canvas.width')
canvas.getContext("2d").drawImage(imgObj, 0, 0, that.canvasWidth, that.canvasHeight); //將圖片繪制到canvas中
let contentWidth = canvas.width
let contentHeight = canvas.height
let pageHeight = contentWidth / 592.28 * 841.89
let leftHeight = contentHeight
let position = 0
let imgWidth = 595.28
let imgHeight = 592.28 / contentWidth * contentHeight
let pageData = canvas.toDataURL('image/jpeg', 1.0)
let PDF = new jsPDF('', 'pt', 'a4')
if (leftHeight < pageHeight) {
PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight) // 大于1頁高度時分頁
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
if (leftHeight > 0) {
PDF.addPage()
}
}
}
const aLink = document.createElement('a')
document.body.appendChild(aLink)
const url = URL.createObjectURL(that.toBlob(PDF.output('datauristring')))
aLink.href = url
let date = new Date()
let year = date.getFullYear()
let month = (date.getMonth() + 1).toString().padStart(2, 0)
let day = date.getDate().toString().padStart(2, 0)
let hour = date.getHours().toString().padStart(2, 0)
let minutes = date.getMinutes().toString().padStart(2, 0)
let seconds = date.getSeconds().toString().padStart(2, 0)
aLink.download = '保存的PDF文件-' + '.pdf'
aLink.click()
window.URL.revokeObjectURL(url)
}
return dataUrl
})
.catch(function (error) {
console.error('wrong!', error);
});
}
到了這里,關(guān)于vue前端實現(xiàn)將頁面顯示內(nèi)容生成pdf文件的幾種方法,html2canvas、dom-to-image、jspdf(帶分頁)基本使用以及介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!