相关文章推荐
好帅的抽屉  ·  android ...·  3 月前    · 
憨厚的茶壶  ·  【Java】Class.getPrimiti ...·  1 年前    · 
发财的李子  ·  Resample xarray ...·  1 年前    · 

由于项目需要前端导出文档,一开始是准备导出word,后来发现导出word比较麻烦,并且前端基本都是由echarts和dataTable组成的,不好导出,最后改为导出为pdf,采用的是jsPDF和html2canvas

一、先引入html2canvas和jsPD

<script type="text/javascript" src="/resource/plugins/jsPDF/jspdf.debug.js"></script>
<script type="text/javascript" src="/resource/plugins/jsPDF/html2canvas.js"></script>
<script type="text/javascript" src="/resource/plugins/jsPDF/rasterizeHTML.js"></script>

二、使用jsPDF导出需要导出的div块,直接通过对应的id即可,其中html2canvas截取当前页面保存为canvas

// 导出日报 $("#exportall").on("click", function (url, name, data1) { if (confirm("您确认下载该PDF文件吗?")) { var pdf = new jsPDF('p', 'pt', 'a4'); // 设置打印比例 越大打印越小 pdf.internal.scaleFactor = 1.5; var options = { pagesplit: true, //设置是否自动分页 "background": '#FFFFFF' //如果导出的pdf为黑色背景,需要将导出的html模块内容背景 设置成白色。 var printHtml = $('#monthlyReport').get(0); // 页面某一个div里面的内容,通过id获取div内容 pdf.addHTML(printHtml, 15, 15, options, function () { pdf.save('后勤月报.pdf');

重点在 var printHtml = $('#monthlyReport').get(0);,可以导出局部的div,不一定需要导出整个页面

三、结果,成功导出

四、存在的问题及优化

由于需要导出内容主要是由echarts和dataTable组成的,再加上内容比较长,需要分页,所以会出现图形或者表格被分页分割成两部分,如图

解决方案,通过计算高度判断是否换到下一页,网上找的,代码比较复杂,也没有细究,直接上代码

// 导出日报
            $("#exportall").on("click", function (url, name, data1) {
                if (confirm("您确认下载该PDF文件吗?")) {
                    var id='monthlyReport';
                    html2canvas($("#"+id), {
                        background: "#FFFFFF",//如果指定的div没有设置背景色会默认成黑色,这里是个坑
                        onrendered:function(canvas) {
                            //未生成pdf的html页面高度
                            var leftHeight = canvas.height;
                            var a4Width = 595.28
                            var a4Height = 841.89
                            //一页pdf显示html页面生成的canvas高度;
                            var a4HeightRef = Math.floor(canvas.width / a4Width * a4Height);
                            //pdf页面偏移
                            var position = 0;
                            var pageData = canvas.toDataURL('image/jpeg', 1.0);
                            var pdf = new jsPDF('x', 'pt', 'a4');
                            var index = 1,
                                canvas1 = document.createElement('canvas'),
                                height;
                            pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen');
                            var pdfName='后勤月报';
                            $('.head-content').append($(
                                '<div class="pdfTip">' +
                                '   <div>正在生成第<span class="pdfProgress">1</span>页,共<span class="pdfTotal"></span>页...' +
                                '</div>'));
                            function createImpl(canvas) {
                                if (leftHeight > 0) {
                                    index++;
                                    var checkCount = 0;
                                    if (leftHeight > a4HeightRef) {
                                        var i = position + a4HeightRef;
                                        for (i = position + a4HeightRef; i >= position; i--) {
                                            var isWrite = true
                                            for (var j = 0; j < canvas.width; j++) {
                                                var c = canvas.getContext('2d').getImageData(j, i, 1, 1).data
                                                if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff) {
                                                    isWrite = false
                                                    break
                                            if (isWrite) {
                                                checkCount++
                                                if (checkCount >= 10) {
                                                    break
                                            } else {
                                                checkCount = 0
                                        height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef);
                                        if(height<=0){
                                            height = a4HeightRef;
                                    } else {
                                        height = leftHeight;
                                    canvas1.width = canvas.width;
                                    canvas1.height = height;
                                    // console.log(index, 'height:', height, 'pos', position);
                                    var ctx = canvas1.getContext('2d');
                                    ctx.drawImage(canvas, 0, position, canvas.width, height, 0, 0, canvas.width, height);
                                    var pageHeight = Math.round(a4Width / canvas.width * height);
                                   // pdf.setPageSize(null, pageHeight)
                                    if(position != 0){
                                        pdf.addPage();
                                    pdf.addImage(canvas1.toDataURL('image/jpeg', 1.0), 'JPEG', 0, 0, a4Width, a4Width / canvas1.width * height);
                                    leftHeight -= height;
                                    position += height;
                                    $('.pdfProgress').text(index + 1);
                                    $('.pdfTotal').text(index + Math.ceil(leftHeight / a4HeightRef));
                                    if (leftHeight > 0) {
                                        setTimeout(createImpl, 500, canvas);
                                    } else {
                                        pdf.save(pdfName + '.pdf');
                                        $('.pdfTip').remove();
                            //当内容未超过pdf一页显示的范围,无需分页
                            if (leftHeight < a4HeightRef) {
                                pdf.addImage(pageData, 'JPEG', 0, 0, a4Width, a4Width / canvas.width * leftHeight);
                                pdf.save(pdfName + '.pdf')
                            } else {
                                try {
                                    pdf.deletePage(0);
                                    $('.pdfTip').show();
                                    $('.pdfTotal').text(index + Math.ceil(leftHeight / a4HeightRef));
                                    setTimeout(createImpl, 500, canvas);
                                } catch (err) {
                                    console.log(err);

可以看出,通过计算如果会被分隔则会自动切换到下一页,虽然有些部分还是看着不是根很舒服,但是还是实现了,不过用这个有个问题就是由于需要计算,所以导出会比较慢!

由于项目需要前端导出文档,一开始是准备导出word,后来发现导出word比较麻烦,并且前端基本都是由echarts和dataTable组成的,不好导出,最后改为导出为pdf,采用的是jsPDF和html2canvas一、先引入html2canvas和jsPD&lt;script type="text/javascript" src="/resource/plugins/jsPDF/jspdf.debug.js"&gt;&lt;/script&gt;&lt;script type="text/
【Vue 项目】html2canvas + jspdf 实现将页面内容生成 PDF 及相关问题解决方案(页面被分页分割问题html2canvas生成图片只有一半)
文中内容是在 Vue 项目中使用 html2canvas和 jspdf 插件实现将页面的内容生成 PDF,并记录在使用过程中遇到的一些问题解决方案。文中将会贴出很多参考文章,如果各位有需要,可以前往原文章查阅。 html2canvas + jspdf介绍使用方法分页分割问题html2canvas生成图片只有一半其他参考文章 1、html2canvas 该插件允许我们直接在浏览器上对网页或其部分进行“截图”操作,但是屏幕截图基于 DOM,这一点很关键。这就会导致截图的结果,很可能不是自己想要的。.
如果不是有特别的需求,比如打印或者分页,还是建议能在一页显示pdf,这样就避免了文字被截断的风险。 不做分页处理 html2canvas(copyDom[0], opts).then((canvas) => { debugger var contentWidth = canvas.width; var contentHeight =...
将页面内容截图导出为PDF文件,如果有高度过高的表格或图片,尽量不截断而是放在下一页展示。 1.将需要导出的dom,都用一个特殊的类名标注起来,然后用html2Canvas将这些dom一一截图。 (这里并非将整个页面截图,而是多个dom截图再拼接,是为了判断是否截断问题。) 2.之后将得到的图片用JsPDF从上到下依次添加到一个pdf文件中即可。 3.关于截断分页问题,需要对每一张图片和当前页面剩余高度进行比较,可以分为一下几种情况。 import ‘./jspdf.min.js’ 如果有滚动条,先把滚动条置顶 document.body.scrollTop = document.documentElement.scrollTop = 0 if (!selector) { throw new Error(‘缺少selector’) let el = document.querySelector(selector) if (!el) { throw new Er 问题背景:生成的图片在一个弹窗里面,如果页面没有滚动条就是正常的,但是一旦出现滚动条并且页面发生滚动时html2canvas绘制成的图片就会偏移出对应滚动高度的白边,如下: 解决办法: 楼主查了很多资料,也用了很多方法都没能解决这个问题,一气之下打算研究研究html2canvas的配置参数,果不其然,在配置参数RenderOptions下找到如下配置 眼尖的楼主立马发现了scrollY这个东西。没错,这个肯定是配置偏移量的对吧,既然你是向下偏移我页面滚动的高度,那我把scrollY设置为负的那不就好了吗,说干就干。于是楼主设置了{scrollY: -window.p 首先说说遇到了什么问题。首先有这么一个需求。需要前端根据后端传过来数据,动态的生成图片。图片中的文案、背景图片、用户头像全部都是通过后端的接口获取。但是使用 html2canvas 生成的canvas有些图片成功的在canvas里生成了。但是有些图片无论如何都显示不出来。 在项目里面操作了半天未果,google了半天未果。此时有些许绝望。突然想到了,为什么不去它的 官网 看看呢。于是乎我在官网上看到了下面的内容。 Limitations<br> All the images that the script uses need to reside under the same
以前我们只能通过其他的截图工具来截取图像。现代浏览器的功能已经越来越强,随着H5的逐渐普及,浏览器本身就可以截图啦。html2canvas就是这样一款前端插件,它的原理是将Dom节点在Canvas里边画出来。虽然很方便,但有以下限制: 不支持iframe 不支持跨域图片 不能在浏览器插件中使用 部分浏览器上不支持SVG图片 不支持Flash 不支持古代浏览器和IE,如果你想确认是否支持某个浏览器,可以用它访问 http://deerface.sinaapp.com/ 试试 :slightly_smiling_face: 由于我的使用场景很简单,记录一下异常信息,并且异常页面也是由自己定义的
html2canvas 1.0.0-alpha.11 https://html2canvas.hertzen.com Released under MIT License html2canvas 将页面dom 元素画到 canvas 上,视觉上 达成截图的 效果。 该脚本允许您直接...
### 回答1: html2canvas是一个开源的JavaScript库,可将网页中的元素转换为图像,以便进行截图、打印等操作。在使用html2canvas进行截图时,有时会遇到分页截断问题分页截断指的是当网页的内容超出一页时,html2canvas只能截取页面的一部分内容,而无法完全截取整个页面的内容。这种情况通常出现在需要打印网页的场景下。 为了解决这个问题,可以使用一些方法来避免或者解决分页截断问题。以下是一些方法: 1.使用CSS的分页属性,将内容分割成多个页面。这样,html2canvas只需截取每个页面的内容即可。 2.将页面缩小后再截取,这样可以让整个页面都能够在一个截图中完整显示。 3.使用第三方库jsPDF,将网页转换为PDF文件,然后再进行截取。这样可以完整截取整个页面的内容。 总之,html2canvas分页截断问题是一个常见的问题,但可以通过一些方法避免或解决。需要根据具体情况选择最合适的方法来解决问题。 ### 回答2: HTML2Canvas是一个常用的JavaScript库,可以将网页的内容转化为图片。但是,使用HTML2Canvas进行分页截断时,会出现一些问题。这些问题包括内容不完整、布局混乱等。 通常情况下,HTML2Canvas分页截断是根据页面的高度进行截断的。例如,如果页面高度为1000像素,当截断到800像素时,HTML2Canvas会自动将当前页面截断,并在下一页继续截断。但是,这种截断方式会存在一些问题。 第一个问题是内容不完整。由于HTML2Canvas是根据页面高度进行截断的,因此当某一部分内容长度超出当前页面高度时,HTML2Canvas会将其截断,导致部分内容无法完全展示。 第二个问题是布局混乱。由于页面内容的不规则性,HTML2Canvas分页截断时可能会导致布局出现混乱。例如,某一部分内容跨越了多个页面时,分页截断会将其分为多份,导致页面布局出现错乱。 解决这些问题的方法一般是自定义分页截断方式。可以通过计算页面内容的高度,将其分为多个部分,并按照一定的规则进行拼接,从而避免上述问题。这种方式需要注意页面的布局,特别是内容长度不规则的部分,在拼接时需要特别处理。 总之,HTML2Canvas分页截断是一个比较复杂的问题,需要仔细处理。要想解决这个问题,需要有较深的JavaScript编程能力和对网页布局的深入认识。 ### 回答3: HTML2Canvas是一个用于将网页内容转换为Canvas图像的JavaScript库。它十分便利,可以帮助我们将一个网页截图并转换为图像。不过,使用HTML2Canvas时,我们可能遇到了分页截断问题,即无法完整地将整个网页截图,而是只能截取一部分。这个问题解决方案如下: 首先,需要使用jsPDF这个库,它可以将Canvas图像转换为PDF文件。在使用HTML2Canvas截图之前,要定义一个空数组pages[]。 然后,将HTML2Canvas生成的Canvas图像分割成多个子图像,并将它们分别添加到pages[]数组中。此时,需要根据每个子图像的高度计算出它们在PDF文件中的位置。 最后,将pages[]数组中的所有子图像添加到 PDF文件中即可。 具体实现方法如下: ```javascript let pdf = new jsPDF("p", "mm", "a4"); let pages = []; function captureAndAddToPDF(selector) { html2canvas($(selector)[0]).then(function (canvas) { let imgData = canvas.toDataURL("image/png"); let imgWidth = pdf.internal.pageSize.width; let ratio = imgWidth / canvas.width; let imgHeight = canvas.height * ratio; let pageData = canvas.toDataURL("image/png", 1.0); pages.push(pageData); let position = 0; let imgWidth = pdf.internal.pageSize.getWidth(); let imgHeight = pdf.internal.pageSize.getHeight(); pdf.addImage(pageData, "PNG", 0, position, imgWidth, imgHeight); position -= imgHeight; captureAndAddToPDF("#content"); pdf.save("output.pdf"); 其中,selector为需要截图的页面元素的选择器,可以根据具体情况进行修改。 以上就是解决HTML2Canvas分页截断问题的方法。需要注意的一点是,当截图过大时,PDF文件可能会非常大,建议将该部分代码封装为单独的函数,只对需要截图的部分进行截图。
老哥 怎么这个报错了 [code=javascript] [Vue warn]: Error in v-on handler: "ReferenceError: $ is not defined" found in ---> <ElButton> at packages/button/src/button.vue <Detail> at src/views/mobil/prod/detail.vue <AppMain> at src/layout/components/AppMain.vue <Layout> at src/layout/index.vue <App> at src/App.vue [/code] 关于html2canvas截断问题的解决方案 record_pengzi: 谢谢大佬,找了很久终于有好用的了,我加上页眉页脚边距也就好看了