vue2使用jspdf插件實(shí)現(xiàn)頁(yè)面自定義塊pdf下載方式
實(shí)現(xiàn)pdf下載的環(huán)境

項(xiàng)目需求案例背景,點(diǎn)擊【pdf下載】按鈕,彈出pdf下載彈窗,顯示需要下載四個(gè)模塊的下載進(jìn)度,下載完成后,關(guān)閉彈窗即可!
- 項(xiàng)目使用的是Vue2,版本為^2.5.10;
- jspdf插件版本為^2.5.1
- html2canvas插件版本為^1.4.1
安裝jspdf插件
npm install jspdf@2.5.1 npm install html2canvas@1.4.1
在項(xiàng)目中使用
下面是在項(xiàng)目中的使用相關(guān)的代碼包括引入,狀態(tài),以及相關(guān)函數(shù),模版的代碼就直接省略掉了;僅供大家參考;
import JsPDF from "jspdf"; import html2Canvas from "html2canvas";
data(){
return {
pdfDownLoadStatus:false,
pdfDownLoadSteps:[],
}
}
點(diǎn)擊事件以及相關(guān)函數(shù)
//點(diǎn)擊pdf下載按鈕事件
downPdf(){
//pdf下載狀態(tài)開(kāi)啟
this.pdfDownLoadStatus = true;
//需要截屏的區(qū)域,用在渲染pdf下載彈窗進(jìn)度里面的內(nèi)容
//code為頁(yè)面下載區(qū)域的id
this.pdfDownLoadSteps = [
{ code: "idxxx1", name: "xx基本信息", status: "wait" },
{ code: "idxxx2", name: 'xx列表', status: "wait" },
{ code: "idxxx3", name: 'xx效果', status: "wait" },
{ code: "idxxx4", name: 'xx意見(jiàn)', status: "wait" },
];
//打開(kāi)pdf下載進(jìn)度彈框,這里就這個(gè)彈窗模版中代碼就省略掉了
this.$refs.pdfDownloadModal.open();
//pdf下載相關(guān)函數(shù)
this.getPdf('下載文件名稱(chēng)');
},
async getPdf(title){
let PDF = new JsPDF({
unit: 'pt',
format: 'a4',
orientation: 'p',
});
let A4_WIDTH = 595.28
let A4_HEIGHT = 841.89
//pdf添加內(nèi)容y軸起始位置
let position = 0
//判斷是否有下載內(nèi)容
if (this.pdfDownLoadSteps && this.pdfDownLoadSteps.length > 0) {
//y:pdf截屏區(qū)域的下標(biāo)
for (let y = 0 ; y < this.pdfDownLoadSteps.length ; y++) {
//折疊面板
let item = this.pdfDownLoadSteps[y];
//開(kāi)始
item.status = 'valid';
//將折疊面板轉(zhuǎn)為canvas元素添加到pdf實(shí)例
await this.toCanvasPanel(PDF, position, document.querySelector("#" + item.code), A4_WIDTH, A4_HEIGHT).then((data)=>{
position = data.pdfPosition;
this.generatePdf(item, this.pdfDownLoadSteps, y, title, PDF);
});
}
}
},
/**
* 生成PDF
* @param item 當(dāng)前區(qū)域下載狀態(tài)
* @param pdfDownLoadSteps 截屏的區(qū)域名
* @param y 當(dāng)前區(qū)域下標(biāo)
* @param title 文件標(biāo)題
* @param PDF
*/
generatePdf(item, pdfDownLoadSteps, y, title, PDF) {
//完成
item.status = 'success';
//最后一個(gè)截屏區(qū)域
if (y == this.pdfDownLoadSteps.length - 1) {
PDF.save(title + '.pdf');
//pdf下載狀態(tài)取消
this.pdfDownLoadStatus = false;
}
},
/**
* 將折疊面板轉(zhuǎn)為canvas元素添加到pdf實(shí)例
* @param PDF
* @param position 添加內(nèi)容的起始位置
* @param dom
* @param imgWidth 圖片寬度
* @param pdfHeight pdf頁(yè)高
* @returns {Promise<unknown>}
*/
toCanvasPanel(PDF, position, dom, imgWidth, pdfHeight){
var p = new Promise(function(resolve, reject){
html2Canvas(dom, {
background: "#FFF"
}).then(function (canvas) {
//獲取canavs轉(zhuǎn)化后的寬度
let contentWidth = canvas.width;
//獲取canavs轉(zhuǎn)化后的高度
let contentHeight = canvas.height;
//高度轉(zhuǎn)化為PDF的高度
let imgHeight = imgWidth / contentWidth * contentHeight;
//轉(zhuǎn)化成圖片Data
let pageData = canvas.toDataURL('image/jpeg', 1.0);
//PDF當(dāng)前頁(yè)剩余高度
let pageResidue = pdfHeight - position;
//添加圖片到pdf
PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
//圖片高度>PDF當(dāng)前頁(yè)剩余高度
if (imgHeight > pageResidue) {
//圖片剩余高度=圖片高度-當(dāng)前頁(yè)剩余高度
let imgResidue = imgHeight - pageResidue;
while (imgResidue > 0) {
//下一頁(yè)起始位置=圖片剩余高度-圖片高度
position = imgResidue - imgHeight;
//圖片剩余高度-PDF高度,獲取圖片剩余高度
imgResidue -= pdfHeight;
//增加分頁(yè)
PDF.addPage();
PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
}
}
//下次截屏的起始位置
position = position.add(imgHeight);
resolve({'state': false, 'pdfPosition': position});
})
});
return p;
},
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue后臺(tái)中優(yōu)雅書(shū)寫(xiě)狀態(tài)標(biāo)簽的方法實(shí)例
在Vue中,我們可以非常便捷地通過(guò)標(biāo)簽實(shí)現(xiàn)狀態(tài)的保存,這篇文章主要給大家介紹了關(guān)于Vue后臺(tái)中如何優(yōu)雅的書(shū)寫(xiě)狀態(tài)標(biāo)簽的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-08-08
解決Vue中引入swiper,在數(shù)據(jù)渲染的時(shí)候,發(fā)生不滑動(dòng)的問(wèn)題
今天小編就為大家分享一篇解決Vue中引入swiper,在數(shù)據(jù)渲染的時(shí)候,發(fā)生不滑動(dòng)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
關(guān)于vue使用ant design vue,打包后a-date-picker控件無(wú)法選擇日期的問(wèn)題
這篇文章主要介紹了關(guān)于vite .env.test環(huán)境使用ant design vue,打包后a-date-picker控件無(wú)法選擇日期的問(wèn)題,本文針對(duì)這個(gè)問(wèn)題提供了解決方法,需要的朋友可以參考下2023-04-04
vue監(jiān)聽(tīng)鍵盤(pán)事件的快捷方法【推薦】
這篇文章主要介紹了vue監(jiān)聽(tīng)鍵盤(pán)事件的快捷方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07
vue實(shí)現(xiàn)簡(jiǎn)單的登錄彈出框
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)簡(jiǎn)單的登錄彈出框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10
Vue data的數(shù)據(jù)響應(yīng)式到底是如何實(shí)現(xiàn)的
這篇文章主要介紹了Vue data的數(shù)據(jù)響應(yīng)式到底是如何實(shí)現(xiàn)的,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
vue項(xiàng)目中?jsconfig.json概念及使用步驟
這篇文章主要介紹了vue項(xiàng)目中?jsconfig.json是什么,本文僅僅簡(jiǎn)單介紹了?jsconfig?.json?的一些基本配置,而?jsconfig?.json提供了大量能使我們快速便捷提高代碼效率的方法,需要的朋友可以參考下2022-07-07
vue.js 子組件無(wú)法獲取父組件store值的解決方式
今天小編就為大家分享一篇vue.js 子組件無(wú)法獲取父組件store值的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11
vue用復(fù)選框?qū)崿F(xiàn)組件且支持單選和多選操作方式
這篇文章主要介紹了vue用復(fù)選框?qū)崿F(xiàn)組件且支持單選和多選操作方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04

