前端页面用html2Canvas+jsPdf(vue+jsp)转成PDF和java转pdf

1.后端代码:

 1 import com.itextpdf.text.Document;
 2 import com.itextpdf.text.Image;
 3 import com.itextpdf.text.PageSize;
 4 import com.itextpdf.text.pdf.PdfWriter;
 5 import sun.misc.BASE64Decoder;
 6 
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9 import java.io.FileOutputStream;
10 import java.io.IOException;

 

 1 /**
 2      *
 3      * @param request
 4      * @param response
 5      * @throws DocumentException
 6      * @throws MalformedURLException
 7      * @throws IOException
 8      */
 9     @RequestMapping(value = "createPDF.do", method = RequestMethod.POST)
10     @ResponseBody
11     public void createPDF(HttpServletRequest request, HttpServletResponse response) throws IOException, com.itextpdf.text.DocumentException {
12         String imgStr=request.getParameter("image");
13         byte[] b=GenerateImage(imgStr.replace("data:image/png;base64,", ""));
14         // 1.新建document对象
15         Document document = new Document(PageSize.A4,20,20,10,10);
16 
17         // 2.建立一个书写器(Writer)与document对象关联,通过书写器(Writer)可以将文档写入到磁盘中。
18         // 创建 PdfWriter 对象 第一个参数是对文档对象的引用,第二个参数是文件的实际名称,在该名称中还会给出其输出路径。
19         PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("D:/jsjPdf.pdf"));
20 
21         // 3.打开文档
22         document.open();
23 
24         // 4.添加一个内容段落
25         //document.add(new Paragraph("Hello World!"));
26 
27         //图片1
28         Image image1 = Image.getInstance(b);
29         //设置图片位置的x轴和y周
30         image1.setAbsolutePosition(100f, 550f);
31         //设置图片的宽度和高度
32         image1.scaleAbsolute(200, 200);
33         //将图片1添加到pdf文件中
34         document.add(image1);
35 
36         // 5.关闭文档
37         document.close();
38         //关闭书写器
39         writer.close();
40     }
41     /**
42      * base64字符串转化成图片
43      * @param imgStr
44      * @return
45      * @throws IOException
46      */
47     public byte[] GenerateImage(String imgStr) throws IOException { // 对字节数组字符串进行Base64解码并生成图片
48         // if (imgStr == null) // 图像数据为空
49         BASE64Decoder decoder = new BASE64Decoder();
50 
51         // Base64解码
52         byte[] b = decoder.decodeBuffer(imgStr);
53         for (int i = 0; i < b.length; ++i) {
54             if (b[i] < 0) {// 调整异常数据
55                 b[i] += 256;
56             }
57         }
58         // 生成jpeg图片
59         // String imgFilePath = "E:/test33.jpg";// 新生成的图片
60         // OutputStream out = new FileOutputStream(imgFilePath);
61         // out.write(b);
62         // out.flush();
63         // out.close();
64         return b;
65 
66     }

2.前端代码:(vue+jsp)

 1 htmlToPdf : function () {
 2                 // $("#pdf").click(function(){
 3                     // 导出之前先将滚动条置顶,不然会出现数据不全的现象
 4                     // window.pageYOffset = 0;
 5                     // document.documentElement.scrollTop = 0
 6                     // document.body.scrollTop = 0
 7                 
 8                  9                     html2canvas(document.body, {
10                         onrendered: function(canvas) {
11                             //把截取到的图片替换到a标签的路径下载
12                             $("#download").attr('href',canvas.toDataURL());
13                             $.post("/xxx/xxx/createPDF.do",{
14                                 image:canvas.toDataURL()
15                             },function(result){
16                                 let contentWidth = canvas.width
17                                 let contentHeight = canvas.height
18 
19                                 //一页pdf显示html页面生成的canvas高度;
20                                 let pageHeight = contentWidth / 592.28 * 841.89
21                                 //未生成pdf的html页面高度
22                                 let leftHeight = contentHeight
23                                 //页面偏移
24                                 let position = 0
25                                 //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
26                                 let imgWidth = 595.28
27                                 let imgHeight = 592.28 / contentWidth * contentHeight
28 
29                                 let pageData = new Image();
30                                 //设置图片跨域访问
31                                 // pageData.setAttribute('crossOrigin', 'Anonymous');
32 
33                                 // setTimeout(() => {
34                                 pageData = canvas.toDataURL('image/jpeg', 0.5);//  参数:图片格式和清晰度(0-1)
35                                 var PDF = new jsPDF('', 'pt', 'a4');
36                                 //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
37                                 //当内容未超过pdf一页显示的范围,无需分页
38                                 if (leftHeight < pageHeight) {
39                                     PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
40                                 } else {
41                                     while (leftHeight > 0) {
42                                         PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
43                                         leftHeight -= pageHeight
44                                         position -= 841.89
45                                         //避免添加空白页
46                                         if (leftHeight > 0) {
47                                             PDF.addPage()
48                                         }
49                                     }
50                                 }
51                                 PDF.save("JOB操作页" + '.pdf')
52                                 // }, 1000);
53                                 54                             });
55 
56                             //下载下来的图片名字
57                             // $("#download").attr('download','share.png') ;
58                             // document.body.appendChild(canvas);
59                         },
60                         //useCORS: true,    //解决资源跨域问题
61                         // allowTaint: true,不允许跨域图片污染画布
62                         // logging:true,
63                         //可以带上宽高截取你所需要的部分内容
64                         //
65                         //     width: 300,
66                         //     height: 30069                     });
70                 // });
71 
72 
73             }

3.java需要用到的依赖

 1      <dependency>
 2             <groupId>com.itextpdf</groupId>
 3             <artifactId>itextpdf</artifactId>
 4             <version>5.5.13.1</version>
 5         </dependency>
 6         <!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
 7         <dependency>
 8             <groupId>com.itextpdf</groupId>
 9             <artifactId>itext-asian</artifactId>
10             <version>5.2.0</version>
11         </dependency>

4.前端需要引入的js

1 <!-- 如果你需要把数据传到后段,你还要引入jquery的js (去百度找一找)-->
2 <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
3 <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.0.272/jspdf.debug.js"></script>

5.html

1 <button id="pdf" @click="htmlToPdf" type="button" class="btn btn-primary ibox-tools_btn" >转PDF</button>
2                             <a id="download">下载</a>

6.效果图:

不过在使用HTML2canvas把jsp页面转成图片的时候会在图片上出现一些奇怪的函数

 

原理:html2canvas库的工作原理并不是真正的“截图”,而是读取网页上的目标DOM节点的信息来绘制canvas,所以它并不支持所有的css属性(像上面的截图的红圈中就有复选框没有显示出来)。

通过html2canvas把DOM节点转成图片,然后在通过jsPDF把图片插入到pdf中

Jspdf是一个将html内容生成pdf文件的库,原理是对输入浏览器的文字或二进制图片进行base64编码转换,以pdf中应有的形式组织,最终以data uri scheme,data:application/pdf;base64;[content] 的格式输出

其实在前端就可以把页面转成pdf的格式了,如果你需要在后端进行转pdf,就需要把图片的base64编码传到后台就行了(上面代码里有写)

 

使用html2Canvas会现的一些问题:

https://www.jianshu.com/p/22bd5b98e38a

 

posted @ 2020-06-08 14:45  星期7  阅读(918)  评论(0编辑  收藏  举报