一、代碼實例
// 導出頁面為PDF格式 import html2Canvas from 'html2canvas' import JsPDF from 'jspdf' import $jQuery from 'jquery' import Axios from '@/axios' import { getServerPath } from '@/constants/CommCreditClientApi' export default { install(Vue, options) { Vue.prototype.uploadDom = function (domId, data) { this.$message.info('上傳開始') let vm = this // 將base64轉換為文件對象 let dataURLtoFile = function (dataurl, filename) { let arr = dataurl.split(',') let mime = arr[0].match(/:(.*?);/)[1] let bstr = atob(arr[1]) let n = bstr.length let u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } // 轉換成file對象 return new File([u8arr], filename, { type: mime }) // 轉換成成blob對象 // return new Blob([u8arr],{type:mime}) } // pdf文件上傳 let uploadPdf = function (file) { // let url ='' getServerPath().then(url => { let requestUrl = 'http://' + url + '/oms/credit/file/param/common/paramImageManager' console.log(requestUrl) let formData = new FormData() let fileList = [] fileList.push(file) formData.append('fileList', file) // 組裝入參--start formData.append('batchClass', 'htmlToPdf') formData.append('userName', localStorage.getItem('userName')) formData.append('branch', JSON.parse(localStorage.getItem('userInfo')).deptNo.toString()) formData.append('company', JSON.parse(localStorage.getItem('userInfo')).company.toString()) formData.append('operateFlag', 'A') console.log(data) formData.append('attachId', data.businessSeqNo) formData.append('clientNo', data.clientNo) formData.append('channel', data.channel) formData.append('registerBranch', JSON.parse(localStorage.getItem('userInfo')).deptNo.toString()) formData.append('registerUserId', localStorage.getItem('userName')) formData.append('lastChangeBranch', JSON.parse(localStorage.getItem('userInfo')).deptNo.toString()) formData.append('lastChangeUserId', localStorage.getItem('userName')) // 組裝入參--end Axios({ method: 'post', url: requestUrl, data: formData }).then(res => { vm.$message.info('上傳完成') }).catch(() => { vm.$message.error('上傳失敗') }) }) } let pdfName = 'test.pdf' let element = $jQuery(`#${domId}`) var w = element.width() // 獲得該容器的寬 var h = element.height() // 獲得該容器的高 // var offsetTop = element.offset().top // 獲得該容器到文檔頂部的距離 // var offsetLeft = element.offset().left // 獲得該容器到文檔最左的距離 var canvas = document.createElement('canvas') canvas.width = w canvas.height = h var context = canvas.getContext('2d') var scale = 1 context.scale(1, 1) // context.translate(-offsetLeft, -offsetTop) var opts = { scale: scale, canvas: canvas, width: w, height: h, useCORS: true, background: '#FFF', allowTaint: false } html2Canvas(element[0], opts).then(function (canvas) { let pdf = new JsPDF('p', 'mm', 'a4') // A4紙,縱向 let ctx = canvas.getContext('2d') let a4w = 190 let a4h = 277 // A4大小,210mm x 297mm,四邊各保留10mm的邊距,顯示區域190x277 let imgHeight = Math.floor(a4h * canvas.width / a4w) // 按A4顯示比例換算一頁圖像的像素高度 let renderedHeight = 0 while (renderedHeight < canvas.height) { let page = document.createElement('canvas') page.width = canvas.width page.height = Math.min(imgHeight, canvas.height - renderedHeight) // 可能內容不足一頁 // 用getImageData剪裁指定區域,並畫到前面創建的canvas對象中 page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0) pdf.addImage(page.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width)) // 添加圖像到頁面,保留10mm邊距 renderedHeight += imgHeight if (renderedHeight < canvas.height) { pdf.addPage() // 如果后面還有內容,添加一個空頁 } } // pdf.save(pdfName) // 將pdf輸入為base格式的字符串 let buffer = pdf.output('datauristring') // 將base64格式的字符串轉換為file文件 let myfile = dataURLtoFile(buffer, pdfName) uploadPdf(myfile) console.log(myfile) }) } } }
formData里存放的是要傳給后端的數據。后端接收到的文件流(即formData.fileList)是MultipartFile數組形式;這里需要注意一點,如果是單文件,可以直接將file放入fileList傳輸,后端依然可以像單批次多文件一樣進行處理。除文件流數組外的參數,通過HttpServletRequest類型的入參進行接收,通過request.getParameter(key)函數獲取值。
二、實現原理
用到了html2Canvas和JsPDF這兩個插件。首先通過html2Canvas將頁面轉化為canvas元素,並進行裁切,然后再轉化為文件流。
三、參考鏈接
以上代碼綜合了以下三篇文章。
https://blog.csdn.net/bing823506390/article/details/109673360
https://blog.csdn.net/pratise/article/details/79249943
https://www.imooc.com/article/268668/