需求目标:实现当前页面数据截图并保存为pdf
实现需求需要处理:
-
处理部分dom样式
-
跨域图片的处理
-
添加平铺水印
-
增加图片的清晰度
-
将canvas转化为pdf
-
下载图片
-
上传图片
1. 当前页面长度过长,html2canvas手机上无法转化
我的解决方案:设置scale
https://github.com/niklasvh/html2canvas/issues/1915
html2canvas(document.body, {
scale: window.devicePixelRatio > 2 ? 2: window.devicePixelRatio
}).then(...);
2. 图片转化为pdf文件时,文件过大时:
doc.addImage(
imgDataURL,
'JPEG'/'PNG',
0,
0,
width,
height,
'',
'FAST'
);
使用jsPdf:
const doc = new JSPDF('', 'pt', [
width * 0.75,
height * 0.75,
]);
注意事项:
- 如果你的宽高使用的是px,在传参的时候需要乘以0.75
- 手机上doc.save无法下载
- 需要通过jsPdf返回Blob对象,使用
var blob = doc.output('datauristring');
-
移动端使用doc.output,会刷新页面(存疑,大家可以注意下)
html2canvas:
通过纯JS对浏览器端经行截屏,但截图的精确度还有待提高,部分css不可识别,所以在canvas中不能完美呈现原画面样式
api
名称 | 默认 | 描述 |
---|---|---|
allowTaint | false | 是否允许跨域图像污染画布 |
backgroundColor | #ffffff | 画布背景色(如果未在DOM中指定)。设置null 为透明 |
backgroundColor | null | 现有canvas 元素用作绘图的基础 |
foreignObjectRendering | false | 如果浏览器支持,是否使用ForeignObject渲染 |
imageTimeout | 15000 | 加载图像的超时时间(以毫秒为单位)。设置0 为禁用超时。 |
ignoreElements | (element) => false | 可从渲染中删除匹配的元素。 |
logging | true | 启用日志记录以进行调试 |
onclone | null | 克隆文档以进行渲染时调用的回调函数可用于修改将要渲染的内容,而不会影响原始源文档。 |
proxy | null | 代理将用于加载跨域图像的网址。如果留空,则不会加载跨域图像。 |
removeContainer | true | 是否清除HTML2canvas临时创建的克隆DOM元素 |
scale | window.devicePixelRatio | 用于渲染的比例尺。默认为浏览器设备像素比率。 |
useCORS | false | 是否尝试使用CORS从服务器加载图像 |
width | Element 宽度 | canvas 的宽度 |
高度 | Element 高度 | canvas 的高度 |
X | Element X偏移 | 裁剪画布X坐标 |
y | Element y偏移 | 裁剪画布y坐标 |
scrollX | Element 滚动X | 渲染元素时要使用的x滚动位置(例如,如果Element使用position: fixed ) |
scrollY | Element 滚动 | 呈现元素时要使用的y-scroll位置(例如,如果Element使用position: fixed ) |
windowWidth | Window.innerWidth | 渲染时使用的窗口宽度Element ,这可能会影响媒体查询之类的内容 |
windowHeight | Window.innerHeight | 渲染时要使用的窗口高度Element ,这可能会影响媒体查询之类的内容 |
不支持的css属性
-
canvas:api
-
最后还是使用了jsPdf这个库
-
pdf 分页处理
createDoc() {
const _width = canvas.width
const _height = canvas.height
const a4Width = 595.28 // a4 实际宽度
const a4Height = 841.89 // a4 实际高度
// a4 单位转化为px的高度
const pageHeight = (_width / a4Width) * a4Height;
// 图片的高度 转化为pt单位
const imgHeight =
(a4Width / _width) * _height;
//未生成pdf的html页面高度
let leftHeight = _height;
let doc = new JSPDF('', 'pt', 'a4');
let position = 0;
if (leftHeight < pageHeight) {
doc.addImage(
`${this.imgBase64}`,
'JPEG',
0,
0,
a4Width,
imgHeight,
'',
'FAST'
);
} else {
while (leftHeight > 0) {
doc.addImage(
`${this.imgBase64}`,
'JPEG',
0,
position,
a4Width,
imgHeight,
'',
'FAST'
);
leftHeight -= pageHeight; // px
position -= a4Height; // pt
// 避免添加空白页
if (leftHeight > 0) {
doc.addPage();
}
}
}
return doc;
}