使用html2canvas生成图片
使用的资源npm i html2canvas
获得base64的图片
const container = document.body;
const canvas = await html2canvas(container, {
scale: window.devicePixelRatio,
width: container.offsetWidth,
height: container.offsetHeight,
useCORS: true,
allowTaint: false
});
const missionImg = canvas.toDataURL('image/jpeg', 1.0);
下载图片
var a = document.createElement('a');
a.download = '文件.jpg'; //下载的文件名,默认是'下载'
a.href = missionImg;
document.body.appendChild(a);
a.click();
a.remove(); //下载之后把创建的元素删除
使用jspdf生成pdf
使用的资源<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"></script>,这个包安装的太大,所以引用静态资源放在本地,
使用jspdf获取pdf实例
const contentWidth = canvas.width;
const contentHeight = canvas.height;
// 一页pdf显示html页面生成的canvas高度;
const pageHeight = contentWidth / 592.28 * 841.89;
// 未生成pdf的html页面高度
let leftHeight = contentHeight;
// pdf页面偏移
let position = 0;
// a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
const imgWidth = 595.28;
const imgHeight = 592.28 / contentWidth * contentHeight;
const missionImg = canvas.toDataURL('image/jpeg', 1.0);
// 三个参数,第一个方向,第二个尺寸,第三个尺寸格式
const doc = new jspdf.jsPDF('', 'pt', 'a4');
// 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
// 当内容未超过pdf一页显示的范围,无需分页
// console.log('--leftHeight--', leftHeight, '--pageHeight--', pageHeight);
if (leftHeight < pageHeight) {
doc.addImage(missionImg, 'JPEG', 0, 0, imgWidth, imgHeight);
} else {
while (leftHeight > 0) {
// console.log('--leftHeight--', leftHeight, '--position--', position);
doc.addImage(missionImg, 'JPEG', 0, position, imgWidth, imgHeight);
leftHeight -= pageHeight;
position -= 841.89;
// 避免添加空白页
if (leftHeight > 0) {
doc.addPage();
}
}
}
上面代码仅考虑分页情况,所以每页的留白和每页的分割,都需要自己根据实际情况去处理,当需要添加padding的时候注意box-sizing: border-box;配合使用
pdf 文件下载
doc.save('download.pdf');
pdf 文件上传
这里的文件上传使用的把base64格式转换成文件再上传,因此需要有一个转换的过程。
同时如果上传数据里面有对象或者数组需要对每个属性单独添加。params.append('obj[keyName]', keyValue),数组就需要加上索引的属性访问。
// 生成file
function dataURLtoFile(dataurl) {
const arr = dataurl.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
const file = new File([u8arr], 'file.pdf', {type: mime});
return file;
}
const file = dataURLtoFile(doc.output('datauri'))
const params = new FormData();
params.append(file, file);
// axios.post(url, params)
直接打开文件
在文件上传的基础上,当生成了文件以后生成一个文件链接并打开
const blob = dataURLtoFile(doc.output('datauri'));
window.open(URL.createObjectURL(blob));
如果被浏览器拦截,在点击按钮之前优先生成好链接,点击按钮以后仅仅open一下生成的链接。