最近遇到的需求,把html转成pdf文件下载导出。
目前网上看了下,有三种方法,但是其中两种需要后端配合
一种是纯前端实现的,比较简单。所以就使用了这种。
也就是html2canvas + jspdf 的这种方法
这种方法实现的思路就是,通过html2canvas 把元素内的数据截图出来成一个图片
然后把这个图片通过jspdf 方法转成pdf格式输出出来
但是也有缺点,就是只是一个图片,而且清晰度也没有那么高。
只能说勉强实现一个需求,先应付一下,后续会继续看其他的写法,然后更新
这里是导出来后的效果,pdf格式的。只有一页
这里是网页上的,这个报告都是我排班出来的,图片和数据都是网上随便复制的,点击导出后会生成一个pdf文件。右边一大串的是base64格式的图片地址。也就是截图。
这是html版本的,然后引入了vue的框架。
这里核心的是要引入html2canvas.js和jspdf.debug.js
资源的话我上传了,可以点击我的资源去下载,我设置了0积分下载,应该是可以直接下载
如果你们用的是纯vue版本,那就简单了。直接npm 下载这两个插件就行。
第一个.将页面html转换成图片 npm install --save html2canvas
第二个.将图片生成pdf npm install jspdf --save
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<!-- 先引入 Vue -->
<script src='vue.js'></script>
<!-- 引入element-UI组件 -->
<script src='element.js'></script>
<link rel='stylesheet' href='element-index.css'>
<!-- 引入axios -->
<script src='axios.min.js'></script>
<!-- 引入html2canvas 和 jspdf.debug-->
<script src='./node_modules/html2pdf/js/html2canvas.js'></script>
<script src='./node_modules/html2pdf/js/jspdf.debug.js'></script>
</head>
<body>
<div id="app">
<div class="layout">
<div><button @click="downBtn" style="width: 70px; height: 30px" id="download-paper">pdf导出</button></div>
<div ref="html2canvas" id="html2canvas">
<div class="title">
<div class="title_img">
<img src="https://img2.baidu.com/it/u=384718229,1745978279&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=461" alt="" style="width: 70px;" crossorigin="anonymous">
</div>
<div class="title_text">
<p class="yiyuan">第一人民医院</p>
<p style="font-size: 18px;font-weight:bold">消化内镜检查及手术记录报告</p>
</div>
</div>
<div class="info1">
<div class="info1left">检查号:12-10266</div>
<div class="info1right">仪器型号:12-10266</div>
</div>
<div class="info2">
<div class="info2top">
<div>姓名:王小天</div>
<div>性别:男</div>
<div>年龄:34岁</div>
<div>科别:内科</div>
<div>申请医师:黄小燕</div>
</div>
<div class="info2bottom">
<div>病历号:12312313546546464</div>
<div>住院号:y229397</div>
<div>病区号:四病区</div>
<div>床位号:409</div>
</div>
</div>
<div class="info3">
<div>检查图像:</div>
<div>
<img :src="item" alt="" class="changimg" v-for="item,index in img2" :key="index" crossorigin="anonymous">
</div>
</div>
<div class="info4">
<div style="font-weight: bold;margin-bottom: 5px;">内镜所见</div>
<div style="font-size:14px;">食管:黏膜光滑柔软,血管纹理清晰,扩张度好,齿状线清晰。贲门:粘膜光滑,未见异常。 胃底:见一枚0.4*0. 4cm大小息肉,表面充血,予以摘除送检,粘液湖黄色,大量。胃
体:粘膜色泽潮红,下部窦体交界后壁见粘膜凹陷不平,片状发红,子以活检。胃角:后壁见片状发红糜烂灶,予以活检。胃窦: 胃窦后壁见大片状食管:黏膜光滑柔软,血管纹理清晰,扩张度好,齿状线清晰。贲
门:粘膜光滑,未见异常。 胃底:见一枚0.4*0. 4cm大小息肉,表
面充血,予以摘除送检,粘液湖黄色,大量。胃 体:粘膜色泽潮
红,下部窦体交界后壁见粘膜凹陷不平,片状发红,子以活检。胃
角:后壁见片状发红糜烂灶,予以活检。胃窦: 胃窦后壁见大片状
发红病灶,表面不平,部分隆起、部分凹陷,染色表面结构紊乱,予以
活检。幽门: 呈圆形,开闭尚可,粘膜色泽淡红,未见出血及渍
疡。十二指肠: 球部及降部未见异常。活检。幽门: 呈圆形,开闭尚可,粘膜色泽淡红,未见出血及渍疡。十二指肠: 球部及降部未见异常。
</div>
<div style="font-weight: bold;margin-bottom: 5px;margin-top: 10px;">镜下诊断</div>
<div style="font-size:14px;">
1,胃多发病灶性质待定
2,胃底息肉镜下摘除
3,胆汁反流性胃炎
</div>
<div style="font-weight: bold;margin-bottom: 5px;margin-top: 10px;">病理号:</div>
<div style="font-weight: bold;margin-bottom: 5px;margin-top: 10px;">活检部位:胃底、窦体交界后壁、胃窦后壁、</div>
<div style="font-weight: bold;margin-bottom: 5px;margin-top: 10px;">病理诊断:</div>
<div style="font-weight: bold;margin-bottom: 5px;margin-top: 10px;">医生建议:</div>
</div>
<div class="info5">
<div>南京索图科技有限公司</div>
<div>手术及诊断医师:王晓</div>
<div>助手:</div>
<div>检查日期:2022/8/27</div>
</div>
<div style="text-align:center;font-weight: bold;font-size: 14px;">仅供临床参考,不做证明材料!</div>
</div>
</div>
</div>
</body>
<script>
new Vue({
el: '#app',
data() {
return {
img2: [
'https://pics6.baidu.com/feed/562c11dfa9ec8a13d9cd9e4f08e1e488a2ecc0b1.jpeg?token=687c57c1c319d6c576d27df01e88c2cb',
'https://pics6.baidu.com/feed/562c11dfa9ec8a13d9cd9e4f08e1e488a2ecc0b1.jpeg?token=687c57c1c319d6c576d27df01e88c2cb',
'https://pics6.baidu.com/feed/562c11dfa9ec8a13d9cd9e4f08e1e488a2ecc0b1.jpeg?token=687c57c1c319d6c576d27df01e88c2cb',
'https://pics6.baidu.com/feed/562c11dfa9ec8a13d9cd9e4f08e1e488a2ecc0b1.jpeg?token=687c57c1c319d6c576d27df01e88c2cb',
'https://pics6.baidu.com/feed/562c11dfa9ec8a13d9cd9e4f08e1e488a2ecc0b1.jpeg?token=687c57c1c319d6c576d27df01e88c2cb',
'https://pics6.baidu.com/feed/562c11dfa9ec8a13d9cd9e4f08e1e488a2ecc0b1.jpeg?token=687c57c1c319d6c576d27df01e88c2cb',
'https://pics6.baidu.com/feed/562c11dfa9ec8a13d9cd9e4f08e1e488a2ecc0b1.jpeg?token=687c57c1c319d6c576d27df01e88c2cb',
'https://pics6.baidu.com/feed/562c11dfa9ec8a13d9cd9e4f08e1e488a2ecc0b1.jpeg?token=687c57c1c319d6c576d27df01e88c2cb',
]
};
},
mounted() {
},
methods: {
downBtn() {
let dom = document.getElementById("html2canvas");
//调用方法下载
html2canvas(dom, {
useCORS: true, //允许跨域
allowTaint: false,
logging: false,
letterRendering: true,
ddpi: window.devicePixelRatio * 4, //将分辨率提高到特定的DPI 提高四倍
scale: 4, //按比例增加分辨率
background: '#fff'//pdf背景色为白色,默认是黑色的
}).then((canvas) => {
//返回图片dataURL,参数:图片格式和清晰度(0-1)
var pageData = canvas.toDataURL('image/jpeg', 1.0);
//方向默认竖直,尺寸ponits,格式a4[595.28,841.89]
var pdf = new jsPDF('', 'pt', 'a4');
//addImage后两个参数控制添加图片的尺寸,此处将页面高度按照a4纸宽高比列进行压缩
pdf.addImage(pageData, 'JPEG', 0, 0, 595.28, 592.28 / canvas.width * canvas.height);
//保存到pdf,名字是stone
pdf.save('stone.pdf');
});
},
},
})
</script>
<style>
#html2canvas {
width: 800px;
height: 1280px;
padding: 20px;
}
.title {
display: flex;
justify-content: center;
align-items: center;
height: 100px;
}
.title_text {
display: flex;
flex-direction: column;
align-items: center;
}
.yiyuan {
font-size: 20px;
font-weight: bold;
color: blue;
}
.info1 {
height: 30px;
display: flex;
justify-content: space-between;
border-bottom: 1px solid #222;
}
.info2 {
height: 100px;
border-bottom: 1px solid #222;
}
.info3 {
border-bottom: 1px solid #222;
}
.info4{
border-bottom: 1px solid #222;
}
.info5{
display: flex;
justify-content: space-around;
align-items: center;
height: 50px;
}
.info2top {
display: flex;
justify-content: space-around;
align-items: center;
height: 40px;
}
.info2bottom {
display: flex;
justify-content: space-around;
align-items: center;
height: 40px;
}
.changimg {
width: 180px;
margin-right: 15px;
}
</style>
</html>
1,模糊问题通过html2canvas方法内的ddpi和scale放大控制清晰度
2,你下载的时候,导出按钮要放在上面,不能放在最下面,因为可能会由于你页面长了有滚动条,当你滚动到下面点击按钮的时候,上面滚动条看不到的部分是不会被截图的,也就是截图不全。但是如果你把按钮放在顶部,那就可以截全,哪怕下面的滚动部分看不到也可以截全,不知道是为啥。反正这个坑我是踩了,提醒你们一下。
3,这里是简单版本,所以没有分页功能,如果需要分页功能可以去网上找一下,pdf.addPage();这个方法就是添加新的分页,可以通过判断是否后面还有内容来触发这个方法,网上到处都是可以直接复制使用
这里给你们随便复制一个人的代码做参考
getPdf(title,url) {
html2Canvas(document.querySelector('#pdfDom'), {
allowTaint: false,
taintTest: false,
logging: false,
useCORS: true,
dpi: window.devicePixelRatio*4, //将分辨率提高到特定的DPI 提高四倍
scale:4 //按比例增加分辨率
}).then(canvas=>{
var pdf = new jsPDF('p', 'mm', 'a4'); //A4纸,纵向
var ctx = canvas.getContext('2d'),
a4w = 190, a4h = 277, //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
imgHeight = Math.floor(a4h * canvas.width / a4w), //按A4显示比例换算一页图像的像素高度
renderedHeight = 0;
while(renderedHeight < canvas.height) {
var page = document.createElement("canvas");
page.width = canvas.width;
page.height = Math.min(imgHeight, canvas.height - renderedHeight);//可能内容不足一页
//用getImageData剪裁指定区域,并画到前面创建的canvas对象中
page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0);
pdf.addImage(page.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width)); //添加图像到页面,保留10mm边距
renderedHeight += imgHeight;
if(renderedHeight < canvas.height) {
pdf.addPage();//如果后面还有内容,添加一个空页
}
// delete page;
}
//保存文件
pdf.save(title + '.pdf')
})
}
————————————————
版权声明:本文为CSDN博主「inticaler」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/MICHAEL_PRINCE/article/details/118667848
4,注意这里页面的图片都是需要添加 crossorigin=“anonymous” 这句话的,这句话的意思是图片允许跨域,不然会出现图片空白的情况。
5,图片的地址如果你要测试,他只能接受http的那种或者base64格式的。不可以本地引入,像 . /xxx/xxx/xxx.png这种的路径是会报错的,我这里用的测试图片都是网络上的地址。
clickGeneratePicture() {
let ref = this.$refs.html2canvas; // 截图区域
html2canvas(ref, {
backgroundColor: "#142E48"
})
.then(canvas => {
let dataURL = canvas.toDataURL("image/png");
this.dataURL = dataURL;
let creatDom = document.createElement("a");
document.body.appendChild(creatDom);
creatDom.href = dataURL;
creatDom.download = "导出的图片名";
creatDom.click();
})
.catch(err => {
this.$message({
message: "图片生成失败",
type: "error"
});
});
}