前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在纯JaveScript中实现报表导出:从“PDF”到“JPG”

在纯JaveScript中实现报表导出:从“PDF”到“JPG”

作者头像
葡萄城控件
发布2021-11-08 10:42:16
2.1K0
发布2021-11-08 10:42:16
举报

我们在前端报表中完成了各种工作数据的输入或内容处理之后,需要做什么?

数据的导出!

这些数据的常用导出格式有:PDF、Excel、HTML和图片几大类型。

但总有一些实际应用场景,需要的不仅仅是将现有内容导出,还需要我们对一些内容的格式进行转化。

就在前几天,葡萄刚上班,就看到客户发来下图,发生了以下对话

-葡萄,这一页可以导出吗?

-当然可以,PDF、Excel、HTML都可以。

-可是我想把这一页导出图片。

这时候问题就出现了,在我们的前端电子报表中并没有默认图片保存的格式,那这时候我们如何用已有功能进一步扩展,来实现这个功能呢?

一、确定实现思路

巧妇难为无米之炊,首先我们先整理一下手中素材。

通过阅读文档了解我们可以自定义添加按钮:

同时我们还可以在action属性中,给按钮定义点击后触发的事件:

顺着这个思路,我们可以在工具栏添加一个导出按钮,将按钮的动作设置为"点击这个按钮时实现导出图片的功能"。ARJS本身支持导出PDF,并且也提供了直接调用导出PDF的接口:export,所以我们可以先通过接口导出PDF,然后再将PDF转换为图片,最终实现导出图片的功能。

这下子,我们的最终问题就变成了是如何 ** PDF **转换为图片并导出

PDF.js是一款使用HTML5 Canvas安全地渲染PDF文件以及遵从网页标准的网页浏览器渲染PDF文件的JavaScript库。我们可以通过PDF.js库将导出的PDF通过Canvas在网页上渲染出来,然后通过Canvas的toDataURL方法返回一个包含图片展示的 data URL。拿到这个URL就好办了,可以利用a标签的download属性直接对其进行下载,最终实现在ARJS中导出图片的功能。

总结,整体实现思路如下:

  • 添加导出图片按钮
  • 实现导出PDF
  • 将 PDF 通过 PDF.js 库渲染成
  • 通过a标签的download属性将保存为图片

二、代码实战 简单起见,本示例不使用任何框架集成ARJS,选择在纯JaveScript中集成报表,大家可以阅读相关文档:在纯JavaScript项目中集成报表 Viewer。另外,为了在document中插入canvas元素,事先可以建立一个div元素,以便之后在该节点下插入canvas元素;同时为了界面中只有报表查看器,可以隐藏该div。最终的页面结构如下:

代码语言:javascript
复制
	<body>
	        <div id="viewer-host"></div>
	        <div id="imgDiv" style="display: none"></div>
	</body>
添加导出图片按钮
代码语言:javascript
复制
1.	    let exportImageButton = {
2.	        key: '$exportImage',
3.	        icon:{
4.	            type: 'svg',
5.	            content:'<svg role="img" xmlns="http://www.w3.org/2000/svg" width="21px" height="21px" viewBox="0 0 24 24" aria-labelledby="imageIconTitle" stroke="#205F78" stroke-width="2.2857142857142856" stroke-linecap="square" stroke-linejoin="miter" fill="none" color="#205F78"> <title id="imageIconTitle">Image</title> <rect width="18" height="18" x="3" y="3"/> <path stroke-linecap="round" d="M3 14l4-4 11 11"/> <circle cx="13.5" cy="7.5" r="2.5"/> <path stroke-linecap="round" d="M13.5 16.5L21 9"/> </svg>',
6.	            size: 'small'
7.	        },
8.	        enabled: true,
9.	        title:'导出图片',
10.	        action: function() {
11.	            //定义导出图片按钮点击事件
12.	        }
13.	    };
14.	    viewer.toolbar.addItem(exportImageButton);

接口文档:addItem。 (提示:以上在icon 的content的属性中,使用了一个svg,这个示例代码中的svg来自网站:ikonate 。如果大家有需要可自行下载,如果作为商用需要注意版权 )

以上代码添加之后,我们就可以在报表预览界面的工具栏看到这样一个按钮:

实现导出PDF

在exportImageButton的action中定义一个exportImage方法,在这个方法中首先实现导出PDF,导出的结果包含一个PDF文件的blob对象,大家可自行打印出来看一下导出结果:

代码语言:javascript
复制
	    function exportImage() {
	        const settings = { title: 'Active Reports JS' };
	        viewer.export('PDF', settings).then((result) =>{
	                //这个result包含一个所导出PDF的blob对象
	                console.log(result);
	        });
	    }
将PDF通过PDF.js库渲染成canvas

首先我们需要去PDF.js官网下载相关文件引入到项目中,我这里的示例通过cdn的方式引入:

代码语言:javascript
复制
1.	  <script src="https://cdnjs.cloudflare.com/ajax/libs/PDF.js/2.10.377/PDF.min.js"></script>

引入之后,我们就可以对上一步得到的blob对象进行操作,将PDF渲染成&lt;canvas&gt;:

代码语言:javascript
复制
	    function pageToCanvasObj(page) {
	        const viewport = page.getViewport({scale: 1});
	        const canvas = document.createElement('canvas');
	        const context = canvas.getContext('2d');
	        canvas.height = viewport.height;
	        canvas.width = viewport.width;
	        canvas.style.width = "100%";
	        canvas.style.height = "100%";
	        imgDiv.append(canvas);
	        return {
	            canvas,
	            renderContext: {
	                canvasContext: context,
	                viewport
	            }
	        }
	    }
	
	    function exportImage() {
	        const settings = { title: 'Active Reports JS' };
	        viewer.export('PDF', settings).then((result) =>{
	            //核心代码
	           //通过FileReader的接口将blob转换为ArrayBuffer
	            const fileReader = new FileReader();
	            fileReader.readAsArrayBuffer(result.data);
	            fileReader.onload = function() {
	                //为了读写ArrayBuffer对象,建立typedArray视图
	                const typedArrayResult = new Uint8Array(fileReader.result);
	                //PDF.js读取文档后渲染canvas
	                PDFjsLib.getDocument(typedArrayResult).promise.then(function(PDF) {
	                    if (PDF) {
	                        const pageNum = PDF.numPages;
	                        for (let i = 1; i <= pageNum; i++) {
	                            PDF.getPage(i).then((page) => {
	                                //创建canvas,并且返回相关数据
	                                const canvasObj = pageToCanvasObj(page);
	                                //<canvas>渲染
	                                page.render(canvasObj.renderContext).promise.then(() => {
	                                   //通过canvas对象的toDataURL得到图片链接
	                                    const imgUrl = canvasObj.canvas.toDataURL();
	                                })
	                            })
	                        }
	                    }
	                },(error) => {
	                    alert(error);
	                });
	            };
	        });
	    }

通过a标签的download属性将canvas保存为图片 将上一步得到的imgURL通过a标签下载:

代码语言:javascript
复制
   function saveImage(index, url) {
	        const link = document.createElement("a");
	        link.href = url;
	        link.download = `image${index}`;
	        link.click();
	        link.remove();
	    }

这下就实现了在在前端报表中完整将报表内容作为图片导出。在此附上示例完整demo代码文件:

https://gcdn.grapecity.com.cn/forum.php?mod=attachment&aid=MTY0Njg4fGNlMzM5MTkwfDE2MzM2NjU4MzB8NjI2NzZ8MTMyNDM3 导出效果:

到这里,已经完全解决了本次提到的问题~

后续也会为大家带来更多有趣或严肃的内容。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-11-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 添加导出图片按钮
  • 实现导出PDF
  • 将PDF通过PDF.js库渲染成canvas
相关产品与服务
腾讯云 BI
腾讯云 BI(Business Intelligence,BI)提供从数据源接入、数据建模到数据可视化分析全流程的BI能力,帮助经营者快速获取决策数据依据。系统采用敏捷自助式设计,使用者仅需通过简单拖拽即可完成原本复杂的报表开发过程,并支持报表的分享、推送等企业协作场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档