vue项目中将html转为pdf并下载
个人项目地址: SubTopH前端开发个人站
(自己开发的前端功能和UI组件,一些有趣的小功能,感兴趣的伙伴可以访问,欢迎提出更好的想法,私信沟通,网站属于静态页面)
SubTopH前端开发个人站https://subtop.gitee.io/subtoph.github.io/#/home
以上 ? 是个人前端项目,欢迎提出您的建议?
以下是正文内容...............
首先安装所需要的依赖
yarn add html2canvas
yarn add jspdf
下面是一个简单的案例,导出A4尺寸pdf
html代码
<template>
<div class="biographical-notes-page">
<p class="daochu" @click="getPdf">导出</p>
<div class="biographical-notes" id="resultsHuiZongTableId">
<div class="my-info">
<div class="photo-box">
<img src=" />
</div>
<div class="info-text">
<p>
<span>姓名:xxx</span>
</p>
<p>
<span>年龄:xx</span>
</p>
<p>
<span>电话:xxxxxxx</span>
</p>
<p>
<span>邮箱:xxxxxxx@163.com</span>
</p>
<p>
<span>工作经验:x年</span>
</p>
<p>
<span>学历学位:本科</span>
</p>
</div>
</div>
</div>
<!-- 加载动画 -->
<div class="loading" v-if="loading">
<p>PDF文件生成中...</p>
</div>
</div>
</template>
javaScript代码,重点是dpi设置控制pdf分辨率
<script>
import { reactive, toRefs, onBeforeMount, onMounted } from 'vue';
import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';
export default {
name: '',
setup() {
const data = reactive({
loading: false
});
onBeforeMount(() => {});
onMounted(() => {});
const [PDF_WIDTH, PDF_HEIGHT] = [595.28, 841.89];
const getPdf = () => {
const ele = document.querySelector('#resultsHuiZongTableId');
downloadPdf(ele, 'A4.pdf');
};
const downloadPdf = (element, filename, options) => {
if (!element) return;
let marginX = (options && (options.marginX || options.margin)) || 0;
let marginY = (options && (options.marginY || options.margin)) || 0;
data.loading = true;
return html2Canvas(element, {
allowTaint: true,
useCORS: true,
dpi: 300, // 设置截图的分辨率
scale: 300 / 96 // 设置截图缩放比例,以适应pdf的dpi
}).then((canvas) => {
let [contentWidth, contentHeight] = [canvas.width, canvas.height];
let [realPdfWidth, realPdfHeight] = [
PDF_WIDTH - marginX * 2,
PDF_HEIGHT - marginY * 2
];
let singlePageContentHeight = Math.ceil(
(contentWidth / realPdfWidth) * realPdfHeight
);
let pageCount = Math.ceil(contentHeight / singlePageContentHeight);
let pdf = new JsPDF({
orientation: 'p',
unit: 'px',
format: [PDF_WIDTH, PDF_HEIGHT],
compress: true
});
if (pageCount < 2) {
pdf.addImage(
canvas.toDataURL(),
'JPEG',
marginX,
marginY,
realPdfWidth,
realPdfHeight
);
} else {
for (let i = 0; i < pageCount; i++) {
if (i > 0) {
pdf.addPage();
}
let singlePageImgData = canvas
.getContext('2d')
.getImageData(
0,
i * singlePageContentHeight,
contentWidth,
singlePageContentHeight
);
let tempCanvas = document.createElement('canvas');
tempCanvas.width = contentWidth;
tempCanvas.height = singlePageContentHeight;
tempCanvas.getContext('2d').putImageData(singlePageImgData, 0, 0);
pdf.addImage(
tempCanvas.toDataURL(),
'JPEG',
marginX,
marginY,
realPdfWidth,
realPdfHeight
);
}
}
data.loading = false;
let res = pdf.save(filename);
console.log(res)
return res;
});
};
return {
getPdf,
...toRefs(data)
};
}
};
</script>
css代码
<style scoped lang="less">
.daochu {
position: absolute;
top: 100px;
left: 0px;
color: #fff;
cursor: pointer;
}
.loading{
position: absolute;
top:0;
left:0;
width:100%;
height: 100%;
background: rgba(0, 0, 0, 0.456);
p{
line-height: 800px;
text-align: center;
color:#fff;
font-weight: 700;
}
}
.biographical-notes-page {
position: relative;
width: 100%;
height: 100%;
background: #000;
overflow: auto;
padding: 20px 0;
box-sizing: border-box;
color: #000;
.biographical-notes {
// font-family: '苹方';
width: 1190px;
min-height: 1682px;
margin: 0px auto;
background: #fff;
padding: 20px 40px;
box-sizing: border-box;
.my-info {
overflow: hidden;
.photo-box {
float: left;
width: 200px;
height: 260px;
background: @TSB;
img{
width: 100%;
}
}
.info-text {
padding: 20px 40px;
float: left;
p {
line-height: 36px;
}
}
}
.info-title {
color: @TSB;
font-size: 22px;
margin-top: 30px;
}
.info-content {
margin-top: 10px;
span {
font-size: 16px;
line-height: 32px;
display: block;
color: #777;
}
}
}
}
简单的转pdf案例,可根据实际业务场景进行扩展