vue页面导出pdf,预览并下载(pc端)
Vue前端HTML保存为PDF常用方式有两种。
一,使用html2Canvas和JsPDF库,转化为图片后保存PDF。
二,调用浏览器window.print(),然后手动保存为PDF。
第一种
优点
- 没有预览点击即可保存
- 不需要手动配置保存
- 可选取部分Dom保存
缺点
- 较不清晰
- 需要先转化为图片
- 没有提前预览
- 不适合保存过长分页内容
- 依赖html2Canvas和JsPDF库
第二种
优点
- 可以提前预览
- 适合保存过长分页内容比较合适
- 直接由浏览器API保存,内容清晰
- 开发便利快速。
缺点
- 第一次需要在预览框手动配置参数
- 需要手动点击保存
- 会有Print预览弹窗
- 不可选取部分Dome,只能保存当前整页面。
一,终端输入命令,添加两个npm
第一个.将页面html转换成图片
npm install --save html2canvas
第二个.将图片生成pdf
npm install jspdf --save
二,定义全局函数..创建一个htmlToPdf.js文件在指定位置.我个人习惯放在('src/components/utils/htmlToPdf'), getPdf方法和pdfExport方法可以任意使用。正常来写应该使用 PDF.save(title + '.pdf')来进行打印下载,PDF.save(title + '.pdf')下面的代码是使用移动端的时候才加上的,光是pc端可以恢复这行代码,干掉下面的代码。
/**
path: src/utils/htmlToPdf.js
name: 导出页面为PDF格式
**/
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
const htmlToPdf = {
// pdfExport() {
// var mainRight = document.getElementById('mainRight');
// html2canvas(mainRight, {
// allowTaint: true,
// scale: 2, // 提升画面质量,但是会增加文件大小
// }).then(function(canvas) {
// var contentWidth = canvas.width;
// var contentHeight = canvas.height;
// var pageData = canvas.toDataURL('image/jpeg', 0.4);
// var pdfWidth = (contentWidth + 10) / 2 * 0.75;
// var pdfHeight = (contentHeight + 200) / 2 * 0.75; // 500为底部留白
// var imgWidth = pdfWidth;
// var imgHeight = (contentHeight / 2 * 0.75); //内容图片这里不需要留白的距离
// var pdf = new jsPDF('', 'pt', [pdfWidth, pdfHeight]);
// pdf.addImage(pageData, 'jpeg', 0, 0, imgWidth, imgHeight);
// pdf.save('report_pdf_' + new Date().getTime() + '.pdf');
// }); }
getPdf(title) {
html2Canvas(document.querySelector('#pdfDom'), {
allowTaint: true,
}).then(canvas=>{
//内容的宽度
let contentWidth = canvas.width;
//内容高度
let contentHeight = canvas.height;
//一页pdf显示html页面生成的canvas高度,a4纸的尺寸[595.28,841.89];
let pageHeight = contentWidth / 592.28 * 841.89;
//未生成pdf的html页面高度
let leftHeight = contentHeight;
//页面偏移
let position = 0;
//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
let imgWidth = 595.28;
let imgHeight = 841.89 / contentWidth * contentHeight;
// let imgHeight = 592.28 / contentWidth * contentHeight;
//canvas转图片数据
let pageData = canvas.toDataURL('image/jpeg', 1.0);
//新建JsPDF对象
let PDF = new JsPDF('', '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')
var _this=this
//转成base64
let pdf64 = PDF.output("datauristring");
//base64转成blob文件
let path = _this.createDownloadFile("报表", pdf64);
//上传到服务器
let formdata = new FormData();
//第三个参数传一个不一定会用到的文件名,但是得有。注意后缀
formdata.append("file", path, "报表.pdf");
//调上传接口,这里因为我封装了axios增加了拦截器,所以是下面的写法,这里根据各位的上传方法不同,自行修改
request({
url: _this.url + _this.curVersion + "/SysFile/uploadImg",
method: "post",
data: formdata,
}).then((res) => {
//拼接文件线上地址
let path =
_this.url + res.data.data.filePath + res.data.data.fileName;
//调用安卓或者ios提供的方法,打开浏览器
Android.openBrowser(path);
});
})
}
};
export default htmlToPdf;
三,在main.js中使用我们定义的函数文件,定义全局。
import htmlToPdf from '@/components/utils/htmlToPdf'
Vue.use(htmlToPdf)
这里开始分两种方式进行,@click="pdfBtn"是点击pdf的事件,id="pdfDom"的div中就是打印的内容,所有内容要写在这个div里。
第一种:html2Canvas和JsPDF库
<template>
<div id="PdfPage1">
<button type="button" @click="pdfBtn">导出PDF</button>
<div id="pdfDom" >
</div>
</div>
</template>
<script>
import htmlToPdf from '@/utils/htmlToPdf'
export default {
name: "PdfPage",
data(){
return{
htmlTitle:'页面导出PDF文件名',
}
},
methods:{
pdfBtn(){
htmlToPdf.getPdf(this.htmlTitle);
}
}
}
</script>
<style scoped>
</style>
第二种:window.print()
<template>
<div id="PdfPage2">
<button type="button" @click="pdfBtn">导出PDF</button>
<div id="pdfDom">
</div>
</div>
</template>
<script>
export default {
name: "PdfPage2",
methods:{
pdfBtn(){
window.print();
}
}
}
</script>
<style scoped>
</style>
打印的css,在点击按钮生成pdf时,打印页面会生成这些样式
@media print{
打印页面样式
.noprint{
display: none;
}
.Front{
background-color: white;
background: url(../assets/beijng.jpg);
background-size:100% 100%;
}
.buttonNoPrint{
display:none;
}
.Header{
display:none;
}
.Headers{
display:none;
}
body{
-webkit-print-color-adjust:exact;
-moz-print-color-adjust:exact;
-ms-print-color-adjust:exact;
print-color-adjust:exact;
}
#pdfDom{
/* width: 1078px;
height: 1568px;
height: 7200px;
border: 1px #000 solid; */
border-bottom: white;
margin: 0 auto;
/* margin-left: 1%;
margin-top: 1%; */
}
配置页眉页脚的边距,宽度
@page{
size: auto !important;
/* margin: 3mm !important; */
margin: 1.5em 1.5em 1.5em
}
}