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