Report export in pure JaveScript: from "PDF" to "JPG"

Keywords: Javascript

What do we need to do after we complete the input or content processing of various work data in the front-end report?

Data export!

The common export formats of these data include PDF, Excel, HTML and pictures.

However, there are always some practical application scenarios, which need not only to export the existing content, but also to transform the format of some content.

Just a few days ago, as soon as grape went to work, he saw the following figure sent by the customer, and the following dialogue occurred

-Grapes, can this page be exported?

-Of course, PDF, Excel and HTML are OK.

-But I want to export this page to pictures.

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

1, Determine the implementation idea

A clever woman can't make bricks without rice. First of all, let's sort out the materials in our hands.

Read the documentation to learn that we can customize the Add button:

At the same time, we can also define the event triggered after clicking the button in the action attribute:

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

At this point, our final problem becomes how to convert * * PDF * * into pictures and export them.

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

In summary, the overall implementation idea is as follows:

  • Add export picture button
  • Implement export PDF
  • Render PDF to < canvas > through PDF.js Library
  • Save < canvas > as a picture through the download attribute of the a tag

2, For the sake of code practice and simplicity, this example does not use any framework to integrate ARJS. You can choose to integrate reports in pure JaveScript. You can read the relevant documents: In pureIntegrating report Viewer in JavaScript project . In addition, in order to insert the canvas element into the document, you can create a div element in advance so that the canvas element can be inserted under the node later; At the same time, in order to only have report viewer in the interface, you can hide the Div. The final page structure is as follows:

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

Add export picture 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:'Export picture',
10.	        action: function() {
11.	            //Define export picture button click event
12.	        }
13.	    };
14.	    viewer.toolbar.addItem(exportImageButton);

Interface documentation: addItem . (Note: the above uses an svg in the content attribute of icon. The svg in this example code comes from the website: ikonate (if you need it, you can download it by yourself. If you are a business, you need to pay attention to the copyright.)

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

Implement export PDF

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

	    function exportImage() {
	        const settings = { title: 'Active Reports JS' };
	        viewer.export('PDF', settings).then((result) =&gt;{
	                //The result contains a blob object of the exported PDF
	                console.log(result);
	        });
	    }

Render PDF to canvas through PDF.js Library

First we need to go PDF.js official website Download relevant files and import them into the project. The example here is introduced through 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 as & lt; canvas>:

	    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) =&gt;{
	            //Core code
	           //Convert blob to ArrayBuffer through FileReader interface
	            const fileReader = new FileReader();
	            fileReader.readAsArrayBuffer(result.data);
	            fileReader.onload = function() {
	                //To read and write ArrayBuffer objects, create a typedArray view
	                const typedArrayResult = new Uint8Array(fileReader.result);
	                //PDF.js render canvas after reading the document
	                PDFjsLib.getDocument(typedArrayResult).promise.then(function(PDF) {
	                    if (PDF) {
	                        const pageNum = PDF.numPages;
	                        for (let i = 1; i &lt;= pageNum; i++) {
	                            PDF.getPage(i).then((page) =&gt; {
	                                //Create a canvas and return relevant data
	                                const canvasObj = pageToCanvasObj(page);
	                                //< canvas > rendering
	                                page.render(canvasObj.renderContext).promise.then(() =&gt; {
	                                   //Get the picture link through the toDataURL of the canvas object
	                                    const imgUrl = canvasObj.canvas.toDataURL();
	                                })
	                            })
	                        }
	                    }
	                },(error) =&gt; {
	                    alert(error);
	                });
	            };
	        });
	    }

Save the canvas as a picture through the download attribute of the a tag, and 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();
	    }

This enables the complete export of the report content as a picture in the front-end report. The sample full demo code file is attached here:

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

So far, the problems mentioned this time have been completely solved~

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

</canvas></canvas></canvas>

Posted by coreyk67 on Wed, 03 Nov 2021 17:12:09 -0700