在Vue 3 + Vite項目中,你可以使用html2canvas
和jspdf
庫來實現將頁面某部分導出為PDF文檔的功能。以下是一個簡單的實現方式:
1.安裝html2canvas
和jspdf
:
pnpm install html2canvas jspdf
2.在Vue組件中使用這些庫來實現導出功能:
<template><div><button @click="exportToPDF">導出PDF</button><div ref="pdfContent" class="pdf-content"><!-- 這里是你想要導出的頁面部分 --></div></div>
</template><script lang="ts">
import { defineComponent, ref } from 'vue';
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';export default defineComponent({setup() {const pdfContent = ref<HTMLElement | null>(null);const exportToPDF = async () => {if (pdfContent.value) {const canvas = await html2canvas(pdfContent.value);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('exported.pdf');}};return {pdfContent,exportToPDF,};},
});
</script><style>
.pdf-content {/* 樣式按需定制 */
}
</style>
最后點擊導出按鈕,即可成功按設置導出你想要導出的部分內容到pdf文檔了,如下所以,打開pdf即可:
封裝方法htmlToPdf.ts
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
// title:下載文件的名稱 htmlId:包裹的標簽的id
const htmlToPdf = (title: string, htmlId: string) => {var element = document.querySelector(htmlId) as HTMLElementwindow.pageYOffset = 0document.documentElement.scrollTop = 0document.body.scrollTop = 0setTimeout(() => {// // 以下注釋的是增加導出的pdf水印 !!!!!!!!!!!!!// const value = '我是水印'// //創建一個畫布// let can = document.createElement('canvas')// //設置畫布的長寬// can.width = 400// can.height = 500// let cans = can.getContext('2d') as any// //旋轉角度// cans.rotate((-15 * Math.PI) / 180)// cans.font = '18px Vedana'// //設置填充繪畫的顏色、漸變或者模式// cans.fillStyle = 'rgba(200, 200, 200, 0.40)'// //設置文本內容的當前對齊方式// cans.textAlign = 'left'// //設置在繪制文本時使用的當前文本基線// cans.textBaseline = 'Middle'// //在畫布上繪制填色的文本(輸出的文本,開始繪制文本的X坐標位置,開始繪制文本的Y坐標位置)// cans.fillText(value, can.width / 8, can.height / 2)// let div = document.createElement('div')// div.style.pointerEvents = 'none'// div.style.top = '20px'// div.style.left = '-20px'// div.style.position = 'fixed'// div.style.zIndex = '100000'// div.style.width = element.scrollHeight + 'px'// div.style.height = element.scrollHeight + 'px'// div.style.background =// 'url(' + can.toDataURL('image/png') + ') left top repeat'// element.appendChild(div) // 到頁面中html2Canvas(element, {allowTaint: true,useCORS: true,scale: 2, // 提升畫面質量,但是會增加文件大小height: element.scrollHeight, // 需要注意,element的 高度 寬度一定要在這里定義一下,不然會存在只下載了當前你能看到的頁面 避雷避雷!!!windowHeight: element.scrollHeight,}).then(function (canvas) {var contentWidth = 1948var contentHeight = canvas.height*1948 / canvas.width// console.log('contentWidth', contentWidth)// console.log('contentHeight', contentHeight)// 一頁pdf顯示html頁面生成的canvas高度;var pageHeight = (contentWidth * 841.89) / 592.28// 未生成pdf的html頁面高度var leftHeight = contentHeight// console.log('pageHeight', pageHeight)// console.log('leftHeight', leftHeight)// 頁面偏移var position = 0// a4紙的尺寸[595.28,841.89],html頁面生成的canvas在pdf中圖片的寬高 //40是左右頁邊距var imgWidth = 595.28-60var imgHeight = (592.28 / contentWidth) * contentHeightvar pageData = canvas.toDataURL('image/jpeg', 1.0)var pdf = new JsPDF('portrait', 'px', 'a4')// 有兩個高度需要區分,一個是html頁面的實際高度,和生成pdf的頁面高度(841.89)// 當內容未超過pdf一頁顯示的范圍,無需分頁if (leftHeight < pageHeight) {// console.log('沒超過1頁')pdf.addImage(pageData, 'JPEG', 2, 2, imgWidth, imgHeight)// pdf.addImage(pageData, 'JPEG', 20, 20, imgWidth, imgHeight)} else {while (leftHeight > 0) {// console.log('超過1頁')pdf.addImage(pageData, 'JPEG', 5, position, imgWidth, imgHeight)leftHeight -= pageHeightposition -= 841.89// 避免添加空白頁if (leftHeight > 0) {pdf.addPage()}}}pdf.save(title + '.pdf')})}, 1000)
}export default htmlToPdf