解决vue项目中html2canvas+jspdf 当前页面生成pdf 模糊,分辨率低的问题
上一篇文章总结了怎么把当前页面,生成PDF,测试的时候发现不同的电脑,下载下来的文件大小不一样,清晰度也不一样。不知是否和电脑屏幕的分辨率有关,这个存疑。百度了一整天,终于找到了解决方案,勉强解决了清晰度问题,不知后面还会出现什么bug。生成pdf的参考原文: https://blog.csdn.net/pratise/article/details/79249943解决清晰度问题的参考原文: h
上一篇文章总结了怎么把当前页面,生成PDF,测试的时候发现不同的电脑,下载下来的文件大小不一样,清晰度也不一样。不知是否和电脑屏幕的分辨率有关,这个存疑。
百度了一整天,终于找到了解决方案,勉强解决了清晰度问题,不知后面还会出现什么bug。
生成pdf的参考原文: https://blog.csdn.net/pratise/article/details/79249943
解决清晰度问题的参考原文: https://blog.csdn.net/weixin_44309374/article/details/106924138
接下来记录一下我解决清晰度问题后的代码,做个留存:
我需要导出的是单页的,高度不超出a4高度的一个表格,所以不考虑分页问题
如果需要导出的是简单的表格之类的,快速获取这个表格的html代码,可以在csdn的创作中心,将word中的表格复制过来,发布博客后,查看源码,就能获得这个表格的html代码(我是这么做的,如果有其他的方法请告诉我哈哈)
(1)我按第二篇参考中的 第二种方法,将 html2canvas.js(点此处跳转)文件 下载到本地 。其实下载了这个文件 ,之前npm insatll 的html2canvas 就用不到的。这里可以随你心情要不要npm uninstall html2canvas。
(2)新建 htmlToPdf.js 代码中的注释,写了一些我自己的理解
// 导出页面为PDF格式
import './html2canvas'
//引入的路径请根据自己的实际情况来写
import JsPDF from 'jspdf'
export default{
install (Vue, options) {
Vue.prototype.getPdf = function (dom,title) {
var title = title
html2canvas(document.querySelector(dom), {
// 以下字段可选
width: 592.28, // canvas宽度
height: 650, // canvas高度 这个高度高于div元素的话,底部会出现黑块 ,相当于leftHeight
// (宽度固定情况下) 小于下面的841.89就不会分页
x: 0, // x坐标
y: 0, // y坐标
foreignObjectRendering: true, // 是否在浏览器支持的情况下使用ForeignObject渲染
useCORS: true, // 是否尝试使用CORS从服务器加载图像
async: false, // 是否异步解析和呈现元素
// 以下字段必填
background: "#ffffff", // 一定要添加背景颜色,否则出来的图片,背景全部都是透明的
dpi: 450, // 处理模糊问题,越高越清晰,文件越大
onrendered: function (canvas) {
let url = canvas.toDataURL();
let contentWidth = canvas.width
let contentHeight = canvas.height
console.log("画布宽度:",canvas.width)
console.log("画布高度:",canvas.height)
// a4 的宽高 592.28 * 841.89
let pageHeight = contentWidth / 592.28 * 841.89 //width是592.28,height <841.89就不会分页
let leftHeight = contentHeight //height 小于 width / 592.28 * 841.89 就不会分页
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('', 'pt', 'a4')
console.log("left:",leftHeight,"pageHeight:",pageHeight)
//强制不分页
// PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
if (leftHeight < pageHeight) {
PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
} else { //leftHeight>pageHeight
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')
},
});
}
}
}
(3) main.js中全局注册
import htmlToPdf from '@/components/utils/htmlToPdf'
// 引入的路径请根据自己的实际情况来写
Vue.use(htmlToPdf)
(4)要导出的当前页面:html.vue
<template>
<!-- <div id="pdfDom" style="text-align: center;width:595.28px;height:841.89px;color:black;background-color:white"> -->
<div id="pdfDom" style="text-align: center;width:595.28px;height:650px;color:black;background-color:white">
<h3 style="padding-top:30px;padding-bottom:10px;">标题</h3>
<div style="text-align:right">
<span style="text-align:right;margin:50px;padding-bottom:15px;">打印日期:{{date}}</span>
</div>
<table style="width:387pt;margin:auto;border-color:black; " cellspacing="0" border="1">
<tbody class="body">
<tr>
<td colspan="2" class="td1">申请人组织机构代码</td>
<td colspan="2" class="td2">{{obj.certNo}}</td>
</tr>
<tr>
<td colspan="2" class="td1">申请人名称</td>
<td colspan="2" class="td2">{{obj.custName}}</td>
</tr>
<tr>
<td colspan="2" class="td1">啊啊啊啊</td>
<td colspan="2" class="td2">{{obj.paymentNo}}</td>
</tr>
<tr>
<td colspan="2" class="td1">业务品种</td>
<td colspan="2" class="td2">非融资性保函</td>
</tr>
<tr>
<td colspan="2" class="td1">T24借据编号</td>
<td colspan="2" class="td2">{{obj.coreSeriNo}}</td>
</tr>
<tr>
<td colspan="2" class="td1">签发币种</td>
<td colspan="2" class="td2">人民币</td>
</tr>
<tr>
<td colspan="2" class="td1">签发金额(元)</td>
<td colspan="2" class="td2">{{ obj.parAmt }}</td>
</tr>
<tr>
<td colspan="2" class="td1">签发日</td>
<td colspan="2" class="td2">{{obj.tkEffDt }}</td>
</tr>
<tr>
<td colspan="2" class="td1">到期日</td>
<td colspan="2" class="td2">{{obj.exprtnDt }}</td>
</tr>
<tr>
<td colspan="2" class="td1">保函类型</td>
<td colspan="2" class="td2">
啊啊啊啊
</td>
</tr>
<tr>
<td colspan="2" class="td1">保函受益人</td>
<td colspan="2" class="td2">{{obj.tendereeName}}</td>
</tr>
<tr>
<td colspan="2" class="td1">系统审批结果</td>
<td colspan="2" class="td2">通过</td>
</tr>
<tr>
<td colspan="2" class="td1">保证金是否入账</td>
<td colspan="2" class="td2">是</td>
</tr>
<tr>
<td colspan="2" class="td1">手续费是否收妥</td>
<td colspan="2" class="td2">是</td>
</tr>
<tr>
<td class="right_bottom" style="width:80pt;text-align: left;border-width:0px 1px 1px 0px;">登记人员</td>
<td class="right_bottom" style="width:127.75pt;text-align: left;border-width:0px 1px 1px 0px;">{{obj.userName||obj.cstMrgNo}}</td>
<td class="right_bottom" style="width:79.05pt;text-align: left;border-width:0px 1px 1px 0px;">登记机构</td>
<td style="width:150.2pt;text-align: left;border-width:0px 0px 1px 0px;border-bottom: solid 1px #000;">{{obj.orgName||obj.orgId}}</td>
</tr>
<tr>
<td style="width:80pt;text-align: left;border-width:0px 1px 0px 0px;border-right: solid 1px #000;">登记时间</td>
<td style="width:127.75pt;text-align: left;border-width:0px 1px 0px 0px;border-right: solid 1px #000;">{{obj.tkEffDt}}</td>
<td style="width:79.05pt;text-align: left;border-width:0px 1px 0px 0px;border-right: solid 1px #000;">业务归属机构</td>
<td style="width:150.2pt;text-align: left;border-width:0px 0px 0px 0px;">{{obj.signOrgName||obj.signOrgId}}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
const moment = require('moment');
export default {
data() {
return {
date: moment(new Date()).format("YYYY-MM-DD"),
}
},
props: {
obj: {
type: Object,
default() {
return {
};
}
},
},
methods: {
get() {
this.getPdf('#pdfDom', "文件名");
},
}
}
</script>
<style lang="less" scoped>
.body td {
padding: 5px 0px 5px 5px;
}
.td1 {
width: 207.75pt;
text-align: left;
border-width: 0px 1px 1px 0px;
border-right: solid 1px #000;
border-bottom: solid 1px #000;
}
.right_bottom{
border-right: solid 1px #000;
border-bottom: solid 1px #000;
}
.td2 {
width: 207.75pt;
text-align: left;
border-width: 0px 0px 1px 0px;
border-bottom: solid 1px #000;
}
</style>
(4) 调用html.vue的页面
注意: 如果导出页面的顶部不在窗口内,比如说超出了屏幕高度,而往下滑,导致看不到顶部,那生成的pdf会截取能看到的那部分,并且底部会有黑块。所以我把下载按钮放在<html>上面,确保要
打印的页面是能看到头部的。
<template>
<div>
<Button @click="show">下载</Button>
<html ref="gethtml" :obj="obj"></html>
</div>
</template>
<script>
import toHtml from "./component/html"
export default {
data() {
return {
load: false,
obj: {
}
};
},
components: { html },
methods: {
show() {
console.log("点了")
this.$refs.gethtml.get();
}
}
};
</script>
大概就是这样,由于不能把我实际的代码贴出来,直接复制的话可能不能使用,有问题请在评论找我。
更多推荐
所有评论(0)