|
这是第 161篇不掺水的,想要了解更多,请戳下方卡片关注我们吧~前言在我们日常开发中一定会遇到"所见即所得"的需求,如导出查询表格中的内容为 Excel 表格——《前端导出 Excel,让后端刮目相看》(https://juejin.cn/post/7030291455243452429)、通过后台网页配置实现配置预览页与实际页面展示的统一——《从零开发一款可视化大屏制作平台》(https://juejin.cn/post/6937257727106220040)。今天我们也来实现一个"所见即所得"的需求:将用户所见网页提取为图片。方案 1:最短步骤实现结果第一个想到的方案就是通过浏览器自带的网页另存为图片去实现。但这种方法显然是不可行的。第一需要提示用户操作进行繁琐的操作,第二无法达到局部提取为图片的效果。方案 2:达成初步可行方案通过调研发现,可以使用 html2canvas(http://html2canvas.hertzen.com/) 将网页先转换为 canvas 数据。再将其转换为图片的方法,最终实现我们想要的功能。引入 html2canvascnpminstall--savehtml2canvasHTML
名称:
年龄:
班级:班级1班级2保存为图片JS//点击保存为CanvasonSaveCanvas(){//这里的类名要与点击事件里的一样constcanvas=document.querySelector('#screenshot-box');letthat=this;html2canvas(canvas,{scale:2,logging:false,useCORS:true}).then(function(canvas){consttype='png';letimgData=canvas.toDataURL(type);//图片格式处理let_fixType=function(type){type=type.toLowerCase().replace(/jpg/i,'jpeg');letr=type.match(/png|jpeg|bmp|gif/)[0];return'image/'+r;};imgData=imgData.replace(_fixType(type),'image/octet-stream');letfilename="htmlImg"+'.'+type;//保存为文件//以bolb文件下载that.downFileToLocal(filename,that.convertBase64ToBlob(imgData))});},如此我们便实现了初步的功能当然,我们也可以设置一个预览图片来预览我们将要导出的图片HTMLJSthis.previewPic=URL.createObjectURL(that.convertBase64ToBlob(imgData));展示效果将方案进行拓展并升级需求止步于此,但秉承着"将事情做的更好"的我们岂能止步于此。实现 HTML 导出为 Word我们需要通过 html-docx 来实现导出为 Word(导出 Word 目前只支持原生 HTML + CSS)。引入 html-docxcnpminstall--savehtml-docx-jsHTML姓名年龄贾维斯2导出为wordJSonWordExport(){varcontentHtml=document.getElementById("export-word").innerHTML;constcssHTML=`table{width:200px;border:1pxsolid#ccc;color:red;}`varcontent=`${contentHtml}`varconverted=htmlDocx.asBlob(content,{orientation:"landscape"});this.downFileToLocal('word文件名.docx',converted)}展示效果如此我们便实现了导出 HTML 为 Word。实现 HTML 导出为 PDF目前市面上 HTML 导出 PDF 的实现方式有多种,如 jsPDF (https://github.com/parallax/jsPDF)、iText (https://blog.csdn.net/weixin_43897590/article/details/124729389)、wkhtmltopdf (https://github.com/wkhtmltopdf/wkhtmltopdf) 等。在不同情况下我们应该使用不同的解决方案:方案优点缺点分页图片表格链接中文特殊字符jsPDF1、整个过程在客户端执行(不需要服务器参与),调用简单1、生成的 pdf 为图片形式,且内容失真支持支持支持不支持支持支持iText1、功能基本可以实现,比较灵活 2、生成 pdf 质量较高1、对 html 标签严格,少一个结束标签就会报错;2、后端实现复杂,服务器需要安装字体;3、图片渲染比较复杂支持支持支持支持支持支持wkhtmltopdf1、调用方式简单;2、生成pdf质量较高1、服务器需要安装 wkhtmltopdf 环境;2、根据网址生成 pdf,对于有权限控制的页面需要在拦截器进行处理支持支持支持支持支持支持今天我们使用在客户端执行(不需要服务器参与)的方式——jsPDF。导入 jsPDFnpminstall--savejspdfHTML导出为PDFJS//导出为PDFonPDFExport(){constcanvas=document.querySelector('#screenshot-box');html2canvas(canvas).then(function(canvas){letcontentWidth=canvas.width;letcontentHeight=canvas.height;//一页pdf显示html页面生成的canvas高度;letpageHeight=contentWidth/592.28*841.89;//未生成pdf的html页面高度letleftHeight=contentHeight;//页面偏移letposition=0;//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高letimgWidth=595.28;letimgHeight=592.28/contentWidth*contentHeight;letpageData=canvas.toDataURL('image/jpeg',1.0);letpdf=newjsPDF('','pt','a4');//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)//当内容未超过pdf一页显示的范围,无需分页if(leftHeight0){pdf.addImage(pageData,'JPEG',0,position,imgWidth,imgHeight)leftHeight-=pageHeight;position-=841.89;//避免添加空白页if(leftHeight>0){pdf.addPage();}}}pdf.save('content.pdf');})}展示效果如此我们便实现了导出 HTML 为 PDF。将功能封装为组件实现一次 HTML 导出图片需要写的代码太多,很多参数也需要按需定制。是否能够将其封装成组件呢?我们可以通过 Vue 的插槽 (https://v2.cn.vuejs.org/v2/api/#v-slot) 将我们导出的内容进行插入完整组件组件导出为图片
|
|