135 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
| // 导出页面为PDF格式
 | ||
| // import html2Canvas from 'html2canvas'
 | ||
| // import jsPDF from 'jspdf'
 | ||
| 
 | ||
| // pdf导出:消除分页内容割裂的具体步骤
 | ||
| // 主要思路:pfd导出页面背景设置为纯白色, 根据内容之间的空白像素点来分页导出。
 | ||
| 
 | ||
| // 0、导出页面等比例转换成a4纸的格式, 此时宽度为a4w, 高度为H。
 | ||
| // 1、从高度为H的导出页面(已转换)取出一页a4纸高宽度内容, 内容高度为a4h, 位置标记高度h0(h0 = 0,从h0高度开始取), 页面宽度为a4w。
 | ||
| // 2、对高度范围为h (h = a4h + h0) 到h0, 宽度为a4w的内容从下到上, 从左到右遍历像素点。
 | ||
| // 3、当连续遍历到p (p是一个阈值, 一般设为10; 根据实际情形调整) 个白色(#fff)像素点时, 停止遍历。
 | ||
| // 4、记录此时的遍历高度h1 (h0 < h1 < h) ; 宽度为a4w, 高度范围为h1到h0的内容就是这一页要展示的内容(把该内容复制到新的canvas里, 然后将该canvas利用pdf导出来)。
 | ||
| // 5、更新位置高度h0 (h0 = h0 + h1)。
 | ||
| // 6、循环【1】到【5】直到 h0 > H 时跳出循环。
 | ||
| 
 | ||
| // export default {
 | ||
| //   install(Vue) {
 | ||
| //     Vue.prototype.getPdf = function(pdfDom) {
 | ||
| //       this.loading = true // 显示导出loading
 | ||
| 
 | ||
| //       const title = this.htmlTitle // PDF导出文件描述
 | ||
| //       const w = document.querySelector(pdfDom).offsetWidth // 获得该容器的宽
 | ||
| //       const h = document.querySelector(pdfDom).offsetHeight // 获得该容器的高
 | ||
| //       const scale = 1 // 定义缩放倍数
 | ||
| 
 | ||
| //       const canvas = document.createElement('canvas') // 定义画布canvas
 | ||
| 
 | ||
| //       // PDF内容失真处理
 | ||
| //       canvas.width = w * scale // 将画布宽&&高放大两倍
 | ||
| //       canvas.height = h * scale
 | ||
| //       canvas.state = false // canvas生成pdf过程状态
 | ||
| //       canvas.getContext('2d').scale(scale, scale)
 | ||
| 
 | ||
| //       const options = {
 | ||
| //         scale: scale,
 | ||
| //         canvas: canvas,
 | ||
| //         width: w,
 | ||
| //         height: h,
 | ||
| //         background: '#ffffff'
 | ||
| //       }
 | ||
| 
 | ||
| //       html2Canvas(document.querySelector(pdfDom), options).then(function(canvas) {
 | ||
| //         const a4Width = 552.28 // A4纸原始宽度为592.28, 这里减去了左右间距2个20
 | ||
| //         const a4Height = 801.89 // A4纸原始高度为841.89, 这里减去了左右间距2个20
 | ||
| //         const a4HeightRef = Math.floor(canvas.width / a4Width * a4Height) // html页面在a4纸中的高度 ,这里向下取整, 后面与这个变量相关的值都是近似值
 | ||
| //         const pageData = canvas.toDataURL('image/jpeg', 1.0)
 | ||
| 
 | ||
| //         let actualHeight = canvas.height // html页面在canvas中的高度
 | ||
| //         let positionHeight = 0 // canvas分页, 位置高度
 | ||
| //         // eslint-disable-next-line new-cap
 | ||
| //         const pdf = new jsPDF('x', 'pt', 'a4')
 | ||
| //         const currentCanvas = document.createElement('canvas') // 遍历canvas, 每一页生成的临时canvas
 | ||
| //         let height // canvas分页, 每页实际分割的高度(如果每页没有空白, 该高度=a4HeightRef, 有空白的, 会将下面的空白高度去掉)
 | ||
| 
 | ||
| //         function createPdfPage(canvas) {
 | ||
| //           if (actualHeight > 0) {
 | ||
| //             let checkCount = 0 // 统计出现空白的次数, 按照每页像素点从下到上, 从左到右同时去遍历; 这里根据实际PDF出现的内容, 灵活调整阈值, 使其分割更为合理(这里的阈值为10)
 | ||
| 
 | ||
| //             if (actualHeight > a4HeightRef) {
 | ||
| //               let currentHeight = positionHeight + a4HeightRef // 当前单页
 | ||
| 
 | ||
| //               for (let i = currentHeight; i >= positionHeight; --i) {
 | ||
| //                 let isWrite = true
 | ||
| 
 | ||
| //                 for (let j = 0; j < canvas.width; ++j) {
 | ||
| //                   const c = canvas.getContext('2d').getImageData(j, i, 1, 1).data // 获取横轴为j, 纵轴为i, 高度宽度均为1的像素数据[255,255,255,0.8]
 | ||
| 
 | ||
| //                   if (c[0] !== 0xff || c[1] !== 0xff || c[2] !== 0xff) {
 | ||
| //                     isWrite = false
 | ||
| //                     break
 | ||
| //                   }
 | ||
| //                 }
 | ||
| 
 | ||
| //                 if (isWrite) {
 | ||
| //                   ++checkCount
 | ||
| //                   if (checkCount >= 10) {
 | ||
| //                     currentHeight = i
 | ||
| //                     break
 | ||
| //                   }
 | ||
| //                 } else {
 | ||
| //                   ++checkCount
 | ||
| //                 }
 | ||
| //               }
 | ||
| 
 | ||
| //               height = Math.round(currentHeight - positionHeight)
 | ||
| //             } else {
 | ||
| //               height = actualHeight
 | ||
| //             }
 | ||
| 
 | ||
| //             currentCanvas.width = canvas.width
 | ||
| //             currentCanvas.height = height
 | ||
| //             // 将当前遍历的canvas页内容复制到新的currentCanvas中
 | ||
| //             currentCanvas.getContext('2d').drawImage(canvas, 0, positionHeight, canvas.width, height, 0, 0, canvas.width, height)
 | ||
| //             pdf.addPage()
 | ||
| //             // 将currentCanvas添加到页面中
 | ||
| //             pdf.addImage(currentCanvas.toDataURL('image/jpeg', 1.0), 'JPEG', 20, 20, a4Width, a4Width / currentCanvas.width * height)
 | ||
| //             actualHeight -= height
 | ||
| //             positionHeight += height
 | ||
| 
 | ||
| //             if (actualHeight > 0) {
 | ||
| //               createPdfPage(canvas)
 | ||
| //             } else {
 | ||
| //               pdf.save(`${title}.pdf`)
 | ||
| //               canvas.state = true
 | ||
| //             }
 | ||
| //           }
 | ||
| //         }
 | ||
| 
 | ||
| //         // 当内容未超过pdf一页显示的范围, 无需分页
 | ||
| //         if (actualHeight < a4HeightRef) {
 | ||
| //           // 这里默认执行了一次pdf.addPage();
 | ||
| //           pdf.addImage(pageData, 'JPEG', 20, 20, a4Width, a4Width / canvas.width * actualHeight)
 | ||
| //           pdf.save(`${title}.pdf`)
 | ||
| //           canvas.state = true
 | ||
| //         } else {
 | ||
| //           // 删除第一张空白页
 | ||
| //           // html2Canvas方法默认就有一页pdf,即在进入createPdfPage()方法前就已经执行了一次pdf.addPage();
 | ||
| //           pdf.deletePage(1)
 | ||
| //           createPdfPage(canvas)
 | ||
| //         }
 | ||
| //       })
 | ||
| //         .then(() => {
 | ||
| //           if (canvas.state) {
 | ||
| //             this.loading = false
 | ||
| //           } else {
 | ||
| //             this.$message({
 | ||
| //               message: 'Error exporting pdf',
 | ||
| //               type: 'error'
 | ||
| //             })
 | ||
| //           }
 | ||
| //         })
 | ||
| //     }
 | ||
| //   }
 | ||
| // }
 |