在Vue項(xiàng)目中實(shí)現(xiàn)HTML轉(zhuǎn)PDF功能的詳細(xì)步驟
前言
在如今的項(xiàng)目開(kāi)發(fā)過(guò)程中,將 HTML 頁(yè)面轉(zhuǎn)換為 PDF 格式是一種常見(jiàn)的需求。無(wú)論是出于保存、打印還是分享的目的,這一功能都能為我們帶來(lái)諸多便利。今天,就讓我們一起深入探討如何在 Vue 項(xiàng)目中借助 html2canvas 和 jspdf 這兩個(gè)強(qiáng)大的工具,輕松實(shí)現(xiàn) HTML 轉(zhuǎn) PDF 的功能,并確保內(nèi)容能夠完整地呈現(xiàn)在一頁(yè) PDF 中。
一、前期準(zhǔn)備:搭建環(huán)境
在開(kāi)始之前,我們需要確保開(kāi)發(fā)環(huán)境中已經(jīng)安裝了必要的依賴庫(kù)。打開(kāi)終端,進(jìn)入到項(xiàng)目的根目錄,然后運(yùn)行以下命令來(lái)安裝 html2canvas 和 jspdf:
npm install html2canvas jspdf
這兩個(gè)庫(kù)分別負(fù)責(zé)將 HTML 元素轉(zhuǎn)換為 canvas 圖像,以及將 canvas 圖像進(jìn)一步處理并生成 PDF 文件。
二、封裝轉(zhuǎn) PDF 工具:核心邏輯的實(shí)現(xiàn)
為了使代碼更加模塊化和易于維護(hù),我們可以在項(xiàng)目的 utils 目錄下創(chuàng)建一個(gè)名為 htmlToPdf.js 的文件。在這個(gè)文件中,我們將封裝 HTML 轉(zhuǎn) PDF 的核心邏輯。
import html2canvas from 'html2canvas';
import { jsPDF } from 'jspdf';
export default {
install(Vue, options) {
Vue.prototype.ExportSavePdf = function (domId, fileName = 'download') {
const element = document.getElementById(domId);
html2canvas(element, {
logging: false,
scale: 2, // 縮放因子,提高圖片清晰度
}).then((canvas) => {
const contentWidth = element.offsetWidth; // 獲取元素寬度
const contentHeight = element.offsetHeight; // 獲取元素高度
const pageData = canvas.toDataURL('image/jpeg', 1.0); // 將 canvas 轉(zhuǎn)換為 base64 圖片格式
// 設(shè)置 PDF 的尺寸
const pdfWidth = (contentWidth * 0.75) / 2; // 轉(zhuǎn)換為 pt 單位
const pdfHeight = (contentHeight * 0.75) / 2 + 15; // 加上一定的底部留白
// 初始化 jsPDF
const pdf = new jsPDF('', 'pt', [pdfWidth, pdfHeight]);
// 計(jì)算圖片在 PDF 中的位置和尺寸
const imgWidth = pdfWidth - 20; // 圖片寬度減去左右邊距
const imgHeight = (contentHeight * imgWidth) / contentWidth; // 根據(jù)圖片寬高比計(jì)算圖片高度
pdf.addImage(pageData, 'JPEG', 10, 10, imgWidth, imgHeight); // 將圖片添加到 PDF 中
pdf.save(`${fileName}.pdf`); // 保存 PDF 文件
});
};
},
};
在這里,我們首先通過(guò) document.getElementById 獲取到需要轉(zhuǎn)換的 HTML 元素。接著,使用 html2canvas 將其轉(zhuǎn)換為 canvas 圖像。然后,我們將 canvas 圖像轉(zhuǎn)換為 base64 格式的圖片數(shù)據(jù),并根據(jù)元素的實(shí)際尺寸設(shè)置 PDF 的大小。最后,利用 jsPDF 將圖片添加到 PDF 中,并保存文件。
三、全局注冊(cè):使功能隨處可用
為了在整個(gè) Vue 項(xiàng)目中都能方便地使用這個(gè)轉(zhuǎn) PDF 的功能,我們需要在 main.js 文件中進(jìn)行全局注冊(cè)。
import Vue from 'vue';
import App from './App.vue';
import htmlToPdf from './utils/htmlToPdf';
Vue.config.productionTip = false;
Vue.use(htmlToPdf);
new Vue({
render: (h) => h(App),
}).$mount('#app');
通過(guò)這一步,我們就將 ExportSavePdf 方法注冊(cè)為了 Vue 的原型方法,可以在任何組件中直接調(diào)用。
四、組件中使用
現(xiàn)在,我們可以在需要使用該功能的 Vue 組件中輕松地調(diào)用 ExportSavePdf 方法了。

<template>
<div>
<div id="contentToConvert">
<h1>這是要轉(zhuǎn)換的內(nèi)容</h1>
<p>你可以在這里放置任何需要轉(zhuǎn)換為 PDF 的 HTML 元素。無(wú)論是文字、圖片還是表格,都可以一鍵轉(zhuǎn)換為 PDF 格式,方便分享和保存。</p>
<img src="https://via.placeholder.com/150" alt="示例圖片">
<table>
<tr>
<th>項(xiàng)目</th>
<th>描述</th>
</tr>
<tr>
<td>html2canvas</td>
<td>用于將 HTML 元素轉(zhuǎn)換為 canvas 圖像</td>
</tr>
<tr>
<td>jsPDF</td>
<td>用于將 canvas 圖像轉(zhuǎn)換為 PDF 文件</td>
</tr>
</table>
</div>
<el-button type="primary" @click="exportToPdf">導(dǎo)出為 PDF</el-button>
</div>
</template>
<script>
export default {
methods: {
exportToPdf() {
this.ExportSavePdf('contentToConvert', '我的PDF文檔');
},
},
};
</script>
在這個(gè)示例中,我們定義了一個(gè)包含文字、圖片和表格的 HTML 結(jié)構(gòu),并將其 ID 設(shè)置為 "contentToConvert"。當(dāng)用戶點(diǎn)擊 "導(dǎo)出為 PDF" 按鈕時(shí),就會(huì)觸發(fā) exportToPdf 方法,進(jìn)而調(diào)用 ExportSavePdf 方法,將指定的 HTML 內(nèi)容轉(zhuǎn)換為 PDF 文件并保存。
五、優(yōu)化與拓展:提升用戶體驗(yàn)
雖然基本功能已經(jīng)實(shí)現(xiàn),但我們還可以進(jìn)行一些優(yōu)化和拓展,以提升用戶體驗(yàn)。
優(yōu)化 PDF 樣式
我們可以通過(guò)調(diào)整 css 樣式,使生成的 PDF 文件更加美觀。例如,設(shè)置頁(yè)面的邊距、字體樣式、顏色等。
#contentToConvert {
max-width: 800px;
margin: 0 auto;
padding: 20px;
font-family: Arial, sans-serif;
color: #333;
}
#contentToConvert h1 {
color: #0066cc;
text-align: center;
}
#contentToConvert table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
#contentToConvert table th,
#contentToConvert table td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
#contentToConvert table th {
background-color: #f2f2f2;
}
支持多頁(yè)面 PDF
如果需要轉(zhuǎn)換的內(nèi)容較多,一頁(yè) PDF 無(wú)法完全展示,我們可以對(duì)代碼進(jìn)行擴(kuò)展,支持生成多頁(yè)面 PDF。
html2canvas(element, {
logging: false,
scale: 2,
}).then((canvas) => {
const contentWidth = element.offsetWidth;
const contentHeight = element.offsetHeight;
const pageData = canvas.toDataURL('image/jpeg', 1.0);
const pdfWidth = (contentWidth * 0.75) / 2;
const pdfHeight = (contentHeight * 0.75) / 2 + 15;
const pdf = new jsPDF('', 'pt', [pdfWidth, pdfHeight]);
const imgWidth = pdfWidth - 20;
const imgHeight = (contentHeight * imgWidth) / contentWidth;
// 計(jì)算需要多少頁(yè)
const totalPages = Math.ceil(imgHeight / pdfHeight);
for (let i = 0; i < totalPages; i++) {
const pageY = i * pdfHeight;
pdf.addImage(pageData, 'JPEG', 10, 10 + pageY, imgWidth, imgHeight);
if (i < totalPages - 1) {
pdf.addPage();
}
}
pdf.save(`${fileName}.pdf`);
});
在這個(gè)拓展版本中,我們首先計(jì)算出需要生成的頁(yè)面數(shù)量,然后循環(huán)將每一頁(yè)的內(nèi)容添加到 PDF 中。
通過(guò)以上步驟,我們不僅實(shí)現(xiàn)了基本的 HTML 轉(zhuǎn) PDF 功能,還對(duì)其進(jìn)行了一些優(yōu)化和拓展,使其更加實(shí)用和易用。
到此這篇關(guān)于在Vue項(xiàng)目中實(shí)現(xiàn)HTML轉(zhuǎn)PDF功能的詳細(xì)步驟的文章就介紹到這了,更多相關(guān)Vue實(shí)現(xiàn)HTML轉(zhuǎn)PDF內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue3中element-plus?Upload上傳文件代碼示例
這篇文章主要介紹了vue3中element-plus?Upload上傳文件的相關(guān)資料,在時(shí)間開(kāi)發(fā)中上傳文件是經(jīng)常遇到的一個(gè)需求,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08
如何解決vuex在頁(yè)面刷新后數(shù)據(jù)被清除的問(wèn)題
這篇文章主要介紹了如何解決vuex在頁(yè)面刷新后數(shù)據(jù)被清除的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
關(guān)于下拉類型多選組件Vue-Treeselect(鍵名轉(zhuǎn)換)
這篇文章主要介紹了關(guān)于下拉類型多選組件Vue-Treeselect(鍵名轉(zhuǎn)換),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
vue實(shí)現(xiàn)公告消息橫向無(wú)縫循環(huán)滾動(dòng)
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)公告消息橫向無(wú)縫循環(huán)滾動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
el-dialog關(guān)閉再打開(kāi)后窗口內(nèi)容不刷新問(wèn)題及解決
這篇文章主要介紹了el-dialog關(guān)閉再打開(kāi)后窗口內(nèi)容不刷新問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02
vue實(shí)現(xiàn)el-table點(diǎn)選和鼠標(biāo)框選功能的方法
在Vue中我們經(jīng)常需要處理表格數(shù)據(jù),這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)el-table點(diǎn)選和鼠標(biāo)框選功能的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10
vue項(xiàng)目中運(yùn)用webpack動(dòng)態(tài)配置打包多種環(huán)境域名的方法
本人分享一個(gè)vue項(xiàng)目里,根據(jù)命令行輸入不同的命令,打包出不同環(huán)境域名的方法。需要的朋友跟隨小編一起看看吧2019-06-06
某些場(chǎng)景下建議vue query代替pinia原理解析
這篇文章主要為大家介紹了某些場(chǎng)景下建議vue-query代替pinia原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02

