前端页面用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
欢迎转载,请注明出处