html2canvas
html2canvas是在浏览器上对网页进行截图操作,实际上是操作DOM。
html2canvas
如果下载出来是pdf文件,可以加上jspdf插件,会先通过html2canvas把页面转化成base64图片,再通过jspdf导出。
安装
npm i html2canvas jspdf
或
yarn add html2canvas jspdf
常用配置项
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| allowTaint | boolean | false | 是否允许跨域图像污染画布 |
| useCORS | boolean | false | 是否跨域加载图片 |
| backgroundColor | string | #fff | 背景色 |
| width | number | 元素宽度 | 单元格 |
| height | number | 元素高度 | 单元格 |
| scale | number | window.devicePixelRatio | 缩放比例 |
| scrollX | number | 元素x轴滚动位置 | 生成后x轴滚动位置 |
| scrollY | number | 元素y轴滚动位置 | 生成后y轴滚动位置 |
使用
如果需要下载pdf再打开,可以直接pdf.save(name + time),后面的就可以注释了。 不需要的话把pdf.save(name + time)注释,页面打印完成后直接打开新标签展示pdf。
<template>
<div>
<h1 ref="toPdf">
导出区域
</h1>
<button @click="toPdfFn">导出pdf</button>
</div>
</template>
<script>
import html2canvas from "html2canvas";
import JSPDF from "jspdf";
export default {
methods:{
toPdfFn(){
this.htmlToPdf('文件名','时间')
},
htmlToPdf(name,time){
let element = this.$refs.toPdf
html2canvas(element, {
logging: false,
allowTaint: true, //开启跨域
useCORS: true,
width: 595,
scale: 2, // 处理模糊问题
dpi: 300, // 处理模糊问题
height:element.availHeight, //解决下方白边问题
}).then(function(canvas) {
let pdf = new JSPDF("p", "mm", "a4") // A4纸,纵向
let ctx = canvas.getContext("2d")
let a4w = 190;
let a4h = 277 // A4大小,210mm x 297mm,四边各保留20mm的边距,显示区域190x277
let imgHeight = Math.floor(a4h * canvas.width / a4w) // 按A4显示比例换算一页图像的像素高度
let renderedHeight = 0
while (renderedHeight < canvas.height) {
let 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()
}
}
//下载pdf 打开
// pdf.save(name + time)
// 将 PDF 文档转换为 Blob 对象
const blob = pdf.output('blob');
// 创建 URL 对象并指向该 Blob 对象
const url = URL.createObjectURL(blob);
// 使用 iframe 加载 PDF 文件并直接显示
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = url;
document.body.appendChild(iframe);
// 使用 window.open() 方法在新窗口中打开 PDF 文件
window.open(url, '_blank');
})
}
}
}
</script>
记录下使用时遇到的问题
使用html2canvas截图的时候,需要截图的dom内css不要用transform实现居中,会丢失。
使用html2canvas将div倾斜时,transform: skew(-15deg, 0deg);打印部分显示不出来。
使用font-family: Songti SC-Black, Songti SC; 失效。 更换字体: font-family: 'STZhongsong';
打印出来模糊问题,使用: scale: 2, //处理模糊问题 dpi: 300, // 处理模糊问题 ( 看上方代码 );
html2Canvas打印时,使用网络图片跨域问题, 首先在线图片域名需要配置允许跨域访问。 allowTaint: true. // 开启跨域 然后img标签需要添加crossorigin="anonymous"。
<img crossOrigin="anonymous :src="url" alt="img">
解决html2canvas A4分页截断问题。
计算完后打印出来的页面
页面设计的时候就考虑到分页的情况,通过 CSS 设置高度来避免页面被分割。当然这样工作量就很大了。因为鄙人公司ui比较TM的**(可爱) 1px 都要跟你算好久(你们公司的ui是这样吗?), 所以就选择通过css来计算绘制。思路: A4纸的宽高都是固定的,A4纸像素长宽分别是842×595。 一个页面来进行展示,子组件单独写样式。
<template>
<div>
<button @click="toPdfFn">导出pdf</button>
<html2Pdf ref="toPdf">
导出区域
</html2Pdf>
</div>
</template>
一页高度就是固定的,然后根据设计稿来就行了! 懂的都懂 (手动狗头)
<section class="PDF"> 内容 </section>
.PDF {
text-align: center;
width: 595px;
height: 842px;
background: #FFFFFF;
border-radius: 0px 0px 0px 0px;
opacity: 1;
}