这是渲染的数据
这是生成的pdf文件,直接可以打印
需要安装和npm依赖和引入封装的pdf.js文件
npm install -- save html2canvas
npm install jspdf -- save
pdf.js文件
import html2canvas from "html2canvas" ;
import jsPDF from "jspdf" ;
export const downloadPDF = ( page, fileName ) => { html2canvas ( page) . then ( function ( canvas ) { canvas2PDF ( canvas, fileName) ; } ) ;
} ;
const canvas2PDF = ( canvas, fileName ) => { let contentWidth = canvas. width; let contentHeight = canvas. height; let imgWidth = 595.28 ; let imgHeight = 595.28 / contentWidth * contentHeight; let pdf = new jsPDF ( "p" , "pt" ) ; pdf. addImage ( canvas. toDataURL ( "image/jpeg" , 1.0 ) , "JPEG" , 0 , 0 , imgWidth, imgHeight) ; pdf. save ( fileName + ".pdf" ) ;
} ;
具体实现
Tempalte
< template> < div> < div v- for = "(item, index) in listDatas" : key= "index" > < div class = "boss" > < div class = "box" : ref= "`pdf-${index}`" > < div class = "box_son" > < div class = "titles" > "XXX" 竞赛< / div> < div class = "zhunasd" > 准考证< / div> < div class = "once" > < div class = "contents" > < div> 姓名: & nbsp; { { item. name } } < / div> < div> 考号: & nbsp; { { item. kaohao } } < / div> < div> 司职: & nbsp; { { item. gongzhongTitle } } < / div> < / div> < div class = "photos" > < img : src= "item.sfzhimgs" alt= "" width= "100%" height= "150px" / > < / div> < / div> < tableborder= "1px solid #2D2822" cellpadding= "0" cellspacing= "0" class = "tables" > < tr> < td style= "width: 250px; border: 1px solid #2d2822" > & nbsp; 考试类别< / td> < td style= "width: 180px; border: 1px solid #2d2822" > & nbsp; 序号< / td> < / tr> < tr> < td style= "width: 250px; border: 1px solid #2d2822" > & nbsp; 理论测试< / td> < td style= "width: 180px; border: 1px solid #2d2822" > & nbsp; { { item. liLunZw } } < / td> < / tr> < tr> < tdstyle= "width: 250px; border: 1px solid #2d2822" v- if = "item.fangzhen[1] != undefined" > & nbsp; { { item. fangzhen[ 0 ] } } < / td> < tdstyle= "width: 180px; border: 1px solid #2d2822" v- if = "item.uuid[1] != undefined" > & nbsp; { { item. uuid[ 0 ] } } < / td> < / tr> < tr> < tdstyle= "width: 250px; border: 1px solid #2d2822" v- if = "item.fangzhen[1] != undefined" > & nbsp; { { item. fangzhen[ 1 ] } } < / td> < tdstyle= "width: 180px; border: 1px solid #2d2822" v- if = "item.uuid[1] != undefined" > & nbsp; { { item. uuid[ 1 ] } } < / td> < / tr> < tr> < tdstyle= "width: 250px; border: 1px solid #2d2822" v- if = "item.fangzhen[2] != undefined" > & nbsp; { { item. fangzhen[ 2 ] } } < / td> < tdstyle= "width: 180px; border: 1px solid #2d2822" v- if = "item.uuid[2] != undefined" > & nbsp; { { item. uuid[ 2 ] } } < / td> < / tr> < tr> < tdstyle= "width: 250px; border: 1px solid #2d2822" v- if = "item.fangzhen[3] != undefined" > & nbsp; { { item. fangzhen[ 3 ] } } < / td> < tdstyle= "width: 180px; border: 1px solid #2d2822" v- if = "item.uuid[3] != undefined" > & nbsp; { { item. uuid[ 3 ] } } < / td> < / tr> < / table> < div class = "footers" > < div> 注意事项: < / div> < div class = "footers_one" > 1 、考生凭准考证和身份证进入考场, 对号入座, 并将准考证、< br / > < div class = "footers_two" > 身份证放在桌面上< / div> < / div> < div class = "footers_two" > 2 、准考证如有涂改或者损坏严重情况, 将视为无效证件。< / div> < / div> < / div> < / div> < / div> < / div> < button @click= "handleExport" > 导出PDF < / button> < / div>
< / template>
Script
1.转换为base64的图片才能生效 http和https的图片生成都不生效
2.这里用到的是Google Chrome浏览器多文件下载一次最多只有10个,这里我们有做异步处理延迟1秒下载
< script> import { downloadPDF } from "../utils/pdf" ;
export default { data ( ) { return { listDatas : [ { kaohao : "2100" , liLunZw : "D106" , sfzh : "2110" , name : "Stephen Curry" , uuid : [ "GS01" , "GA02" , "GF03" ] , gongzhongTitle : "后卫" , fangzhen : [ "运球训练" , "投篮训练" , "上篮训练" ] , sfzhimgs : "转换为base64的图片才能生效 http和https的图片生成都不生效" , } , { kaohao : "2100" , liLunZw : "D107" , sfzh : "2110" , name : "Andrew Wiggins" , uuid : [ "GS01" , "GA02" , "GF03" ] , gongzhongTitle : "小前锋" , fangzhen : [ "运球训练" , "投篮训练" , "上篮训练" ] , sfzhimgs : "" , } , { kaohao : "2100" , liLunZw : "D107" , sfzh : "2110" , name : "Andrew Wiggins" , uuid : [ "GS01" , "GA02" , "GF03" ] , gongzhongTitle : "小前锋" , fangzhen : [ "运球训练" , "投篮训练" , "上篮训练" ] , sfzhimgs : "" , } , { kaohao : "2100" , liLunZw : "D107" , sfzh : "2110" , name : "Andrew Wiggins" , uuid : [ "GS01" , "GA02" , "GF03" ] , gongzhongTitle : "小前锋" , fangzhen : [ "运球训练" , "投篮训练" , "上篮训练" ] , sfzhimgs : "" , } , ] , } ; } , methods : { handleExport ( ) { this . downloadPDFs ( ) ; } , async downloadPDFs ( ) { const downloadPromises = [ ] ; for ( let index = 0 ; index < this . listDatas. length; index++ ) { const item = this . listDatas[ index] . name; const pdfElement = this . $refs[ ` pdf- ${ index} ` ] [ 0 ] ; var content = pdfElement. textContent; const startIndex = content. indexOf ( "考号:" ) + 4 ; const endIndex = content. indexOf ( "工种:" ) ; const examNumber = content. substring ( startIndex, endIndex) . trim ( ) ; const ZhongName = item + "," + examNumber; await this . delay ( 1000 ) ; const downloadPromise = downloadPDF ( pdfElement, ZhongName) ; downloadPromises. push ( downloadPromise) ; } Promise. all ( downloadPromises) . then ( ( ) => { console. log ( "全部下载完成" ) ; } ) . catch ( ( error ) => { console. error ( "下载出错" , error) ; } ) ; } , delay ( ms ) { return new Promise ( ( resolve ) => setTimeout ( resolve, ms) ) ; } , } ,
} ;
< / script>
Style
< style>
. boss { width : 100 % ; margin : 0 auto; display : flex; justify- content: center; overflow : hidden;
}
. box { width : 480px; height : 760px; display : flex; justify- content: center;
}
. box_son { width : 425px; height : 600px; margin- top: 30px;
}
. titles { font- size: 20px; font- weight: 800 ; display : flex; justify- content: center; margin- top: 10px;
}
. zhunasd { font- size: 20px; font- family: Microsoft YaHei; font- weight: 800 ; text- align: center;
}
. once { width : 100 % ; display : flex; justify- content: space- between; margin- top: 20px; font- size: 17px; font- family: Microsoft YaHei; font- weight: 500 ;
}
. contents { width : 70 % ; height : 160px; line- height: 56px;
}
. photos { width : 30 % ; height : 160px;
}
. tables { width : 425px; margin- top: 20px; height : 180px;
}
. footers { margin- top: 20px;
}
. footers_one { margin- top: 10px;
}
. footers_two { margin- top: 10px;
}
< / style>
综上就是全部的实现的内容