vue2前端導(dǎo)出pdf文件實(shí)例demo
1、安裝依賴
導(dǎo)出PDF通常涉及將HTML內(nèi)容轉(zhuǎn)換為圖片(截圖),然后將這些圖片插入到PDF文檔中。這個(gè)過程可以通過使用 html2canvas 和 jspdf 這兩個(gè)庫來實(shí)現(xiàn):
npm install jspdf html2canvas 或 cnpm install jspdf html2canvas
安裝完成后,package.json文件生成如下:


2、demo

2.1 demo1導(dǎo)出效果
源碼中 【導(dǎo)出PDF】導(dǎo)出時(shí),不會(huì)分頁導(dǎo)出。

2.2 demo2導(dǎo)出效果
源碼中 【導(dǎo)出PDF2】導(dǎo)出時(shí),會(huì)分頁導(dǎo)出。

2.3 demo3導(dǎo)出效果
源碼中 【導(dǎo)出PDF3】導(dǎo)出時(shí),會(huì)分頁導(dǎo)出。

3、源碼
<template>
<div>
<div style="margin-top: 50px;text-align: center" >
<el-button type="primary" @click="exportPDF">導(dǎo)出PDF</el-button>
<el-button type="primary" @click="exportPDF2">導(dǎo)出PDF2</el-button>
<el-button type="primary" @click="getPdf()" >導(dǎo)出PDF3</el-button>
</div>
<div style="margin-left: 200px;margin-top: 10px;margin-right: 150px" ref="pdfContent" id="pdfDom" class="mmm" >
<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>
<h1>1Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>2Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>3Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
<h1>4Element 默認(rèn)提供一套主題,CSS 命名采用 BEM 的風(fēng)格,方便使用者覆蓋樣式。</h1>
</div>
</div>
</template>
<script>
import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';
export default {
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀區(qū)金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀區(qū)金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀區(qū)金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀區(qū)金沙江路 1516 弄'
}],
htmlTitle:"PDF測試"
}
},
methods: {
async exportPDF() {
const content = this.$refs.pdfContent;
const canvas = await html2canvas(content);
const imgData = canvas.toDataURL('image/png');
const doc = new jsPDF({
orientation: 'portrait',
unit: 'px',
format: 'a4',
});
const imgProps= doc.getImageProperties(imgData);
const pdfWidth = doc.internal.pageSize.getWidth();
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
doc.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
doc.save('導(dǎo)出pdf測試1.pdf');
},
exportPDF2() {
html2canvas(document.querySelector('#pdfDom'), {
allowTaint: false, // 是否允許跨域圖像。會(huì)污染畫布,導(dǎo)致無法使用canvas.toDataURL 方法
backgroundColor: '#fff', // 畫布背景色(如果未在DOM中指定)。設(shè)置null為透明
useCORS: true, // 是否嘗試使用CORS從服務(wù)器加載圖像
dpi: 500, // 導(dǎo)出pdf清晰度
scale: window.devicePixelRatio, // 用于渲染的比例。默認(rèn)為瀏覽器設(shè)備像素比率。
}
).then(function (canvas) {
var imageData = canvas.toDataURL('image/jpeg', 1.0); // html生成圖片的數(shù)據(jù)
const canvasWidth = canvas.width; // 原本的html頁面的寬高
const canvasHeight = canvas.height;
// 當(dāng)分辨率是72像素/英寸時(shí),A4紙像素長寬分別是842×595
var a4Width = 595; // A4 寬度
var a4Height = (595 / canvasWidth) * canvasHeight; // A4總高度
let pageHeight = canvasWidth / 595 * 842; // 生成pdf的一頁顯示html的高度
let restHeight = canvasHeight; // 未生成pdf的html頁面高度,最初是整體的高度
var position = 0; // 頁面上下偏移的大小
/**
* 參數(shù)1:方向:l:橫向 p:縱向
* 參數(shù)2:單位:"pt"、"mm"、"cm"、"m"、"in"、"px"
* 參數(shù)3:格式:默認(rèn)為a4
*/
var pdf = new jsPDF('p', 'pt', 'a4');
if (restHeight < pageHeight) { // 當(dāng)內(nèi)容未超過pdf一頁顯示的范圍,無需分頁
/**
* 將圖像添加到PDF中
* 參數(shù)1:圖片的url
* 參數(shù)2:圖片的格式
* 參數(shù)3:圖片上下偏移的大小
* 參數(shù)4:原始寬度
* 參數(shù)5:原始高度
*/
pdf.addImage(imageData, 'JPEG', 0, position, a4Width, a4Height);
} else {
while (restHeight > 0) {
pdf.addImage(imageData, 'JPEG', 0, position, a4Width, a4Height)
restHeight -= pageHeight;
position -= 842;
if (restHeight > 0) {
pdf.addPage(); // 在PDF文檔中添加新頁面
}
}
}
pdf.save("導(dǎo)出pdf測試2" + '.pdf')
}
)
},
},
};
</script>
<style>
.mmm {
background: linear-gradient(to right, #39fad7, #f9faa1,#39fad7); /* 標(biāo)準(zhǔn)的語法 */
}
</style>
3.1 demo1
源碼中 【導(dǎo)出PDF】按鈕,不會(huì)分頁導(dǎo)出,會(huì)截?cái)鄶?shù)據(jù),適用于只需要導(dǎo)出一頁的數(shù)據(jù),如證件、行數(shù)少的表格數(shù)據(jù)等。
3.2 demo2
源碼中 【導(dǎo)出PDF2】按鈕,會(huì)分頁導(dǎo)出,實(shí)際應(yīng)用中根據(jù)需求進(jìn)行處理、設(shè)置。
3.3 demo3
源碼中 【導(dǎo)出PDF3】按鈕,會(huì)分頁導(dǎo)出,封裝了方法,本質(zhì)和【導(dǎo)出PDF2】按鈕一樣。
<el-button type="primary" @click="getPdf()" >導(dǎo)出PDF3</el-button>
此按鈕為封裝方法,所以當(dāng)前源碼搜不到。
1)、在utils文件夾中創(chuàng)建htmlToPdf.js的文件,如下:

// 導(dǎo)出頁面為PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default{
install (Vue, options) {
Vue.prototype.getPdf = function () {
var title = this.htmlTitle
html2Canvas(document.querySelector('#pdfDom'), {
allowTaint: true
}).then(function (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('p', 'pt', 'a4')
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()
}
}
}
PDF.save(title + '.pdf')
}
)
}
}
}
2)、在main.js中注冊(cè)自定義的插件htmlToPdf.js

3)、方法、屬性解釋及導(dǎo)出文件
getPdf()是我們?cè)趍ain.js中綁定在Vue中的,直接調(diào)用即可,無需在methods中寫方法; htmlTitle:"PDF測試" //主頁面中定義文件名稱,htmlToPdf.js中獲取。

總結(jié)
到此這篇關(guān)于vue2前端導(dǎo)出pdf文件的文章就介紹到這了,更多相關(guān)vue2導(dǎo)出pdf文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用Vue-cli搭建Vue項(xiàng)目框架的教程詳解
這篇文章主要為大家詳細(xì)介紹了利用Vue-cli搭建Vue項(xiàng)目框架的相關(guān)資料,對(duì)大家深入了解Vue有一定的幫助,感興趣的小伙伴可以了解一下2023-02-02
Vue 實(shí)現(xiàn)對(duì)quill-editor組件中的工具欄添加title
這篇文章主要介紹了Vue 實(shí)現(xiàn)對(duì)quill-editor組件中的工具欄添加title,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08
Vue3父子組件傳參有關(guān)sync修飾符的用法詳解
這篇文章主要給大家介紹關(guān)于前端Vue3父子組件傳參有關(guān)sync修飾符的用法詳細(xì)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-09-09
基于Vue-cli的一套代碼支持多個(gè)項(xiàng)目
這篇文章主要介紹了基于Vue-cli的一套代碼支持多個(gè)項(xiàng)目的方案,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下2021-03-03
mpvue中使用flyjs全局?jǐn)r截的實(shí)現(xiàn)代碼
這篇文章主要介紹了mpvue中使用flyjs全局?jǐn)r截的實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09
Element el-checkbox-group v-model不支持對(duì)象(object)解決方案
本文主要介紹了Element el-checkbox-group v-model不支持對(duì)象(object)解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05

