I want to do a function to export PDF on WEB. I found that jsPDF is recommended by many people. Unfortunately, it does not support Chinese. Finally, I found pdfmake, which solved this problem well. Its effect can be viewed first at http://pdfmake.org/playground.html. During use, it was also found that inserting pictures was a relatively cumbersome thing.
In response to these issues, the main content of this article can be divided into three parts:
• Basic usage method of pdfmake;
•How to solve Chinese problems;
•How to insert pictures by specifying the image address.
Basic usage method of pdfmake
1. Contains the following two files
<script src="build/pdfmake.min.js"></script> <script src="build/vfs_fonts.js"></script>
2. Declare a Document-definition object in JS code, which is pdfmake's own term. To put it simply, it is to create an object that contains at least the content attribute. Then you can call the pdfMake method to export the PDF, see the following code:
<script type="text/javascript"> //Create Document-definition object var dd = { content: [ 'One paragraph', 'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines' ] }; //Export PDF pdfMake.createPdf(dd).download(); </script>Follow the above example and you will see the prompt file to be downloaded. For a complete tutorial about pdfmake, please log in to the pdfmake project to view it.
pdfmake supports Chinese
Three steps:
1. Go to the pdfmake project website, download all the projects, then enter the project directory and put the font file (such as Microsoft Yahei.ttf) into the examples/fonts directory, and then use grunt dump_dir to generate a new vfs_fonts.js file;
From the above description, we can see that the project is managed through grunt. If there is no relevant knowledge, please go online and take a tutoring first.
The grunt dump_dir command will package all files in the fonts directory, so please do not put useless files in it.
Microsoft Yahei.ttf searches online, and the directory where fonts are stored under the WINDOWS computer system disk can also be found.
2. Go back to your own example code, modify the fonts object of pdfMake in the JS code and declare that the font you want to use:
pdfMake.fonts = { Roboto: { normal: 'Roboto-Regular.ttf', bold: 'Roboto-Medium.ttf', italics: 'Roboto-Italic.ttf', boldtalics: 'Roboto-Italic.ttf', boldtalics: 'Roboto-Italic.ttf' }, Microsoft Yahei: { normal: 'Microsoft Yahei.ttf', bold: 'Microsoft Yahei.ttf', italics: 'Microsoft Yahei.ttf', } };3. Declare the font to be used by default in the Document-definition object. Specifically: it is to declare an object. In addition to the content attribute, it also needs a defaultStyle attribute. There is another font attribute under the defaultStyle:
var dd = { content: [ 'Chinese and English test', 'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines' ], defaultStyle: { font: 'Microsoft Yahei' } };The following is a complete example source code based on the above steps:
<!DOCTYPE html><html lang="zh-CN"> <head> <meta charset="utf-8"> <title>my first export PDF</title> <script src="build/pdfmake.min.js"></script> <script src="build/vfs_fonts.js"></script> <script> function down() { var dd = { content: [ 'Chinese and English test', 'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines' ], defaultStyle: { font: 'Microsoft Yahei' } }; pdfMake.fonts = { Roboto: { normal: 'Roboto-Regular.ttf', bold: 'Roboto-Medium.ttf', italics: 'Roboto-Italic.ttf', boldalics: 'Roboto-Italic.ttf', boldalics: 'Roboto-Italic.ttf', } }; pdfMake.createPdf(dd).download(); } </script> </head> <body> <button onclick="down()">Download</button> </body></html>Insert picture
In terms of inserting images, jsPDF requires the image to be converted into Data URL first, and pdfmake allows direct paths to be specified, which seems very convenient, but this is conditional, and it must be used as a server, or put the image in vfs_fonts.js, so in general, it is not very useful, so you still have to convert the image to Data URL form.
To solve this problem, I wrote a function object of ImageDataURL that can pass in multiple image addresses at the same time. After all the images are loaded, ImageDataURL.oncomplete will be triggered. The Data URL of each image is taken out through this.imgdata in the callback. The PDF can be generated correctly according to the requirements of pdfmake.
The principle of ImageDataURL is to draw the image on the canvas tag of H5, and then obtain the Data URL of the image through the toDataURL of the canvas. Please pay attention to browser compatibility issues when using it.
The following is an example of writing sampleImage.jpg, sampleage.jpg, sampleImage.jpg to PDF in sequence. Sampleage.jpg does not exist during testing, and the PDF is directly ignored.
<!DOCTYPE html><html lang="zh-CN"> <head> <meta charset="utf-8"> <title>my second export PDF</title> <script src="build/pdfmake.min.js"></script> <script src="build/vfs_fonts.js"></script> <script> function down() { var x = new ImageDataURL(["sampleImage.jpg", "sampleImage.jpg"]); x.oncomplete = function() { var imgs = new Array(); console.log("complete"); for (key in this.imgdata) { if (this.imgdata[key] == this.emptyobj)//Ignore the non-existent pictures; imgs.push({image:this.imgdata[key]});//Pdfmake's image format{image:image dataurl} } var dd = { content: [ 'Title', imgs, ], }; pdfMake.createPdf(dd).download(); } } </script> </head> <body> <button onclick="down()">Download</button> <script> function ImageDataURL(urls) {//urls must be a string or a string array this.completenum = 0; this.totalnum = 0; this.imgdata = new Array(); this.emptyobj = new Object(); this.oncomplete = function(){}; this.getDataURL = function(url, index) { var c = document.createElement("canvas"); var cxt = c.getContext("2d"); var img = new Image(); var dataurl; var p; p = this; img.src = url; img.onload = function() { var i; var maxwidth = 500; var scale = 1.0; if (img.width > maxwidth) { scale = maxwidth / img.width; c.width = maxwidth; c.height = Math.floor(img.height * scale); } else { c.width= img.width; c.height= img.height; } cxt.drawImage(img, 0, 0, c.width, c.height); p.imgdata[index] = c.toDataURL('image/jpeg'); for (i = 0; i < p.totalnum; ++i) { if (p.imgdata[i] == null) break; } if (i == p.totalnum) { p.oncomplete(); } }; img.onerror = function() { p.imgdata[index] = p.emptyobj; for (i = 0; i < p.totalnum; ++i) { if (p.imgdata[i] == null) break; } if (i == p.totalnum) { p.oncomplete(); } }; } if (urls instanceof Array) { this.totalnum = urls.length; this.imgdata = new Array(this.totalnum); for (key in urls) { this.getDataURL(urls[key], key); } } else { this.imgdata = new Array(1); this.totalnum = 1; this.getDataURL(urls, 0); } } </script> </body></html>The above method of exporting PDF plug-ins by JS (supporting Chinese and image usage paths) is all the content I share with you. I hope you can give you a reference and I hope you can support Wulin.com more.