3

After we have completed the input or content processing of various work data in the front-end report, what needs to be done?

Data export!

The commonly used export formats of these data are: PDF, Excel, HTML and pictures.

But there are always some practical application scenarios. What is needed is not only to export the existing content, but also to transform the format of some content.

Just a few days ago, when Putao went to work, he saw the picture below sent by the customer, and the following dialogue took place

-Grape, can this page be exported?

-Of course, PDF, Excel, HTML are all available.

-But I want to export this page as a picture.

At this time, the problem arises. There is no default format for saving pictures in our front-end electronic reports. At this time, how can we use the existing functions to further expand to realize this function?

One, determine the realization idea

It's hard for a clever woman to cook without rice. First, let's sort out the materials in our hands.

Read the documentation to understand that we can customize the add button:

At the same time, we can also define the event to be triggered after the button is clicked in the action attribute:

Following this idea, we can add an export button to the toolbar and set the action of the button to "the function of exporting pictures when this button is clicked". ARJS itself supports exporting PDF, and also provides an interface to directly call exporting PDF: export , so we can first export PDF through the interface, and then convert the PDF to pictures, and finally realize the function of exporting pictures.

Now, our final question becomes how to PDF converted to pictures and export .

PDF.js is a JavaScript library that uses HTML5 Canvas to safely render PDF files and a web browser that complies with web standards to render PDF files. We can use the PDF.js library to render the exported PDF through Canvas on the web page, and then return a data URL containing the image display through the toDataURL method of Canvas. It's easy to get this URL, you can use the download attribute of the a tag to download it directly, and finally realize the function of exporting pictures in ARJS.

In summary, the overall implementation ideas are as follows:

  • Add export image button
  • Realize exporting PDF
  • Render PDF into <canvas> through PDF.js library
  • Save <canvas> as a picture through the download attribute of the a tag

2. Code actual combat
For simplicity, this example does not use any framework to integrate ARJS, choose to integrate reports in pure JaveScript, you can read related documents: in the pure JavaScript project integrated report Viewer . In addition, in order to insert a canvas element in the document, a div element can be created in advance, so that the canvas element can be inserted under the node later; at the same time, the div can be hidden in order to only have the report viewer in the interface. The final page structure is as follows:

    <body>
            <div id="viewer-host"></div>
            <div id="imgDiv" style="display: none"></div>
    </body>

Add export image button

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);

Interface document: addItem .
(Hint: The above uses an svg in the icon's content attribute. The svg in this sample code comes from the website: ikonate . If you need it, you can download it yourself. If you want to use it for commercial use, you need to pay attention to the copyright)

After adding the above code, we can see such a button in the toolbar of the report preview interface:

Realize exporting PDF

Define an exportImage method in the action of exportImageButton. In this method, export the PDF first. The export result contains a blob object of the PDF file. You can print it out to see the export result:

        function exportImage() {
            const settings = { title: 'Active Reports JS' };
            viewer.export('PDF', settings).then((result) =>{
                    //这个result包含一个所导出PDF的blob对象
                    console.log(result);
            });
        }

Render PDF into canvas through PDF.js library

First of all, we need to go to PDF.js official website download the relevant files and import them into the project. My example here is imported by cdn:

1.      <script src="https://cdnjs.cloudflare.com/ajax/libs/PDF.js/2.10.377/PDF.min.js"></script>

After the introduction, we can operate on the blob object obtained in the previous step and render the PDF into \&lt;canvas\&gt;:

        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);
                    });
                };
            });
        }

Save the canvas as a picture through the download attribute of the a tag
Download the imgURL obtained in the previous step through the a tag:

   function saveImage(index, url) {
            const link = document.createElement("a");
            link.href = url;
            link.download = `image${index}`;
            link.click();
            link.remove();
        }

Now it is possible to export the report content as a picture in the front-end report. The complete demo code file of the example is attached here:

https://gcdn.grapecity.com.cn/forum.php?mod=attachment&aid=MTY0Njg4fGNlMzM5MTkwfDE2MzM2NjU4MzB8NjI2NzZ8MTMyNDM3
Export effect:

So far, the problem mentioned this time has been completely solved~

The follow-up will also bring you more interesting or serious content.


葡萄城技术团队
2.7k 声望28.6k 粉丝

葡萄城创建于1980年,是专业的软件开发技术和低代码平台提供商。以“赋能开发者”为使命,葡萄城致力于通过各类软件开发工具和服务,创新开发模式,提升开发效率,推动软件产业发展,为“数字中国”建设提速。