一. 安装所需依赖
npm install html2canvas --save npm install jspdf --save
二. htmlToPdfNew.js 核心文件
import jsPDF from "jspdf" ;
import html2canvas from "html2canvas" ;
class PdfLoader {
constructor ( ele, pdfFileName, splitClassName ) {
this . ele = ele;
this . pdfFileName = pdfFileName;
this . splitClassName = splitClassName;
this . A4_WIDTH = 595 ;
this . A4_HEIGHT = 842 ;
}
async getPDF ( ) {
let ele = this . ele;
let pdfFileName = this . pdfFileName;
let eleW = ele. offsetWidth;
let eleH = ele. scrollHeight;
let eleOffsetTop = ele. offsetTop;
let eleOffsetLeft = ele. offsetLeft;
let canvas = document. createElement ( "canvas" ) ;
let abs = 0 ;
let win_in =
document. documentElement. clientWidth || document. body. clientWidth;
let win_out = window. innerWidth;
if ( win_out > win_in) {
abs = ( win_out - win_in) / 2 ;
}
canvas. width = eleW * 2 ;
canvas. height = eleH * 2 ;
let context = canvas. getContext ( "2d" ) ;
context. scale ( 3 , 3 ) ;
context. translate ( - eleOffsetLeft - abs, - eleOffsetTop) ;
html2canvas ( ele, {
useCORS : true ,
} ) . then ( async ( canvas ) => {
let contentWidth = canvas. width;
let contentHeight = canvas. height;
let pageHeight = ( contentWidth / this . A4_WIDTH ) * this . A4_HEIGHT ;
let leftHeight = contentHeight;
let position = 30 ;
let imgWidth = this . A4_WIDTH - 60 ;
let imgHeight = ( this . A4_WIDTH / contentWidth) * contentHeight;
let pageData = canvas. toDataURL ( "image/jpeg" , 1.0 ) ;
let pdf = jsPDF ( "" , "pt" , "a4" ) ;
if ( leftHeight < pageHeight) {
pdf. addImage ( pageData, "JPEG" , 30 , 20 , imgWidth, imgHeight) ;
} else {
while ( leftHeight > 0 ) {
pdf. addImage ( pageData, "JPEG" , 30 , position, imgWidth, imgHeight) ;
leftHeight -= pageHeight;
position -= this . A4_HEIGHT ;
if ( leftHeight > 0 ) {
pdf. addPage ( ) ;
}
}
}
pdf. save ( pdfFileName + ".pdf" , { returnPromise : true } ) . then ( ( ) => {
let doms = document. querySelectorAll ( ".emptyDiv" ) ;
for ( let i = 0 ; i < doms. length; i++ ) {
doms[ i] . remove ( ) ;
}
} ) ;
this . ele. style. height = "" ;
} ) ;
}
isSplit ( nodes, index, pageHeight ) {
if (
nodes[ index] . offsetTop + nodes[ index] . offsetHeight < pageHeight &&
nodes[ index + 1 ] &&
nodes[ index + 1 ] . offsetTop + nodes[ index + 1 ] . offsetHeight > pageHeight
) {
return true ;
}
return false ;
}
async outPutPdfFn ( pdfFileName ) {
return new Promise ( ( resolve, reject ) => {
this . ele. style. height = "initial" ;
pdfFileName ? ( this . pdfFileName = pdfFileName) : null ;
let target = this . ele;
let pageHeight = ( target. scrollWidth / this . A4_WIDTH ) * this . A4_HEIGHT ;
let domList = document. getElementsByClassName ( this . splitClassName) ;
let pageNum = 1 ;
let eleBounding = this . ele. getBoundingClientRect ( ) ;
for ( let i = 0 ; i < domList. length; i++ ) {
let node = domList[ i] ;
let bound = node. getBoundingClientRect ( ) ;
let offset2Ele = bound. top - eleBounding. top;
let currentPage = Math. ceil (
( bound. bottom - eleBounding. top) / pageHeight
) ;
if ( pageNum < currentPage) {
pageNum++ ;
let divParent = domList[ i] . parentNode;
let newNode = document. createElement ( "div" ) ;
newNode. className = "emptyDiv" ;
newNode. style. background = "white" ;
newNode. style. height =
pageHeight * ( pageNum - 1 ) - offset2Ele + 30 + "px" ;
newNode. style. width = "100%" ;
let next = domList[ i] . nextSibling;
if ( next) {
divParent. insertBefore ( newNode, node) ;
} else {
divParent. appendChild ( newNode) ;
}
}
}
} ) ;
}
}
export default PdfLoader;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
三. 组件使用方法
引入 htmlToPdfNew.js 核心文件import PdfLoader from "./htmlToPdfNew.js" ;
dom 设置
< button @click = " downLoadPdf" > 下载 button>
< div id = " pdfContainer" > div>
下载事件方法downLoadPdf ( ) {
let ele = document. getElementById ( "pdfContainer" ) ;
let pdf = new PdfLoader ( ele, "测试" , "itemClass" ) ;
pdf. getPDF ( ) ;
} ,
四. 组件使用实例
< template>
< div class = " home" >
< button @click = " downLoadPdf" > 下载 button>
< div id = " pdfContainer" class = " pdfContainer" >
< div class = " title" > PDF 标题 div>
< div class = " itemClass" > div>
< div class = " info" >
< div class = " text1" > 君不见黄河之水天上来,奔流到海不复回。 div>
< div class = " text2" > 君不见高堂明镜悲白发,朝如青丝暮成雪。 div>
div>
div>
div>
template>
< script>
import PdfLoader from "./htmlToPdfNew.js" ;
export default {
methods : {
downLoadPdf ( ) {
let ele = document. getElementById ( "pdfContainer" ) ;
let pdf = new PdfLoader ( ele, "测试" , "itemClass" ) ;
pdf. getPDF ( ) ;
} ,
} ,
} ;
script>
< style scoped lang = " scss" >
.home {
width : 100%;
height : 100%;
.pdfContainer {
width : 800px;
padding : 10px 20px;
border : 1px solid #e2e2e2;
box-sizing : border-box;
text-align : center;
.title {
text-align : center;
font-weight : bold;
padding-bottom : 10px;
}
.info {
line-height : 35px;
.text1 {
color : rgb ( 0, 170, 255) ;
}
.text2 {
color : rgb ( 255, 119, 0) ;
}
}
}
}
style>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57