前端导出网页内容至PDF。
要用到两个库:
- html2canvas: 将网页内容转换为canvas
- jspdf: 将canvas生成的图片转换为PDF文件
1 2 |
import { jsPDF } from 'jspdf'; import html2canvas from 'html2canvas'; |
先用html2canvas将要打印的内容转换为canvas
1 2 3 4 5 |
html2canvas(document.querySelector("#capture"), { useCORS: true // 如果网页中有跨域图片,需要将此项设置为true }).then(canvas => { // 将返回的canvas对象转为图片对象 }); |
将返回的canvas对象转为图片对象
1 2 3 4 5 6 |
const dataUrl = canvas.toDataURL(); const $image = new Image(); $image.onload = () => { // 将图片根据要打印的纸张尺寸裁剪出来 } $image.src = dataUrl; |
将图片根据要打印的纸张尺寸裁剪出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
// 需要根据设备的dpr进行计算 const dpr = window.devicePixelRatio; const pageWidth = 790 * dpr; const pageHeight = 1050 * dpr; const $pageCanv = document.getElementById('pageCanv'); $pageCanv.width = $image.width; $pageCanv.height = pageHeight; const ctx = $pageCanv.getContext("2d"); // 将图片加入jsPDF const doc = new jsPDF(); // 根据要打印的内容和纸张高度判断是否需要分页 // 如果不需分页 直接添加进jsPDF if($image.height <= pageHeight) { ctx.drawImage( $image, 0, 0, $image.width, $image.height, 0, 0, $image.width / dpr, $image.height / dpr ); doc.addImage({ imageData: $pageCanv.toDataURL(), }); } else { // 需要分页 for(let i = 0; i < totalPage; i++) { ctx.clearRect(0, 0, $pageCanv.width, $pageCanv.height); ctx.drawImage( $image, 0, i === 0 ? 0 : pageHeight * i - 20, $image.width, pageHeight, 0, 0, pageWidth / dpr, pageHeight / dpr); doc.addImage({ imageData: $pageCanv.toDataURL(), }); if(i < totalPage - 1) { doc.addPage(); } } } // 导出PDF文件 doc.save('fileName.pdf'); $image.remove(); |
总结:
- 必须加入dpr计算,否则视网膜屏上会显示不完整
- 要打印背景色,需要添加:-webkit-print-color-adjust: exact;
- 每次分页裁剪都重叠一小部分,避免一行文字被分别打印到两张纸的情况发生
- 使用opacity属性是打印不出来的,如果要半透明的色彩,需要使用rgba
- 浏览器自带的打印功能也可以导出pdf文件,使用@media print{ } 来定制打印样式
- 裁剪分页有更完美的方法,循环判断内容区块是否正处于分页处,如果处于分页处则提前分页,因为感觉有点麻烦所以没有这么写
文章评论 暂无评论
暂无评论