朔州做网站,巴西网站建设,工业设计东莞网站建设,免费建站网站大全导入依赖
html2canvas依赖
npm install html2canvasjspdf依赖
npm install jspdfpdf导出 以导出横向#xff0c;A4大小的pdf为例 规律#xff1a;1. html2canvas 中#xff0c;在保持jsPDF中的宽高不变的情况下#xff0c;设置html2canvas中的 width 和 height 值越小A4大小的pdf为例 规律1. html2canvas 中在保持jsPDF中的宽高不变的情况下设置html2canvas中的 width 和 height 值越小导出的pdf越显示不全(会被放大只能看到局部)反之值越大导出的pdf越显示完整(值也不能过大过大在pdf中就显示的越小)。 2. jsPDF 中在保持html2canvas中的宽高不变的情况下pdf.addImage(pageData, ‘JPEG’, 5, yPosition, width, height) width 和 height 值越小导出的pdf越显示完整反之导出的pdf越显示不全。 总结html2canvas 与 jsPDF 设置刚好相反合理设置大小才能使数据撑满整个pdf。 index.vue执行导出pdf页面
a-spin :spinningpdfConfirmLoadingdiv refpdfDivpdf-template :refpdfTemplate i v-fori in arrNum/pdf-template/div
/a-spinscriptimport {printPdf} from ./utils/indeximport pdfTemplate from ./template/pdfTemplateexport default {name: courseTableList,components: {pdfTemplate},data() {return {pdfVisible: false,disableSubmit: false,arrNum: 1,pdfConfirmLoading: false,}},created() {},methods: {//导出pdfasync handleExportPdf() {this.handleElement()},handleElement() {if(this.selectionRows.length 0) {this.pdfConfirmLoading trueconst groupedData this.selectionRows.reduce((result, item) {// 检查是否已存在以该teacher为键的分组if (!result[item.instructor]) {result[item.instructor] [];}// 将当前项添加到对应的分组中result[item.instructor].push(item);return result;}, {});// 转换成数组形式const groupedArray Object.values(groupedData);let len groupedArray.lengththis.arrNum lenlet that thisthis.pdfVisible truethis.$nextTick(() {for (let index 0; index groupedArray.length; index) {const item groupedArray[index];let num index 1let pageFooter num of len;that.$refs[pdfTemplate num][0].setDataList(item, pageFooter);}this.pdfConfirmLoading false})} else {this.$message.warning(请勾选数据)}},//确认导出pdfasync confirmExportPdf() {this.pdfConfirmLoading trueawait printPdf(this.$refs.pdfDiv, courseSchedule)this.pdfConfirmLoading falsethis.pdfVisible false},}}
/script
pdfTemplate.vue模板根据需求自定义创建
templatediv classcontent refpdfContent :keyJSON.stringify(datasource)!-- 头部 --div classheaderdiv classheader_row1div classheader_row1_vdiv classheader_row1_leftspanRegd. User: YiZhong College/span/divdiv classheader_row1_rightspanChristine Xia/span/div/divdiv classheader_row1_middlespanTimetables/span/div/divdiv classheader_row2div classheader_row2_vdiv classheader_row2_leftspanSchool: FD - YiZhong Cambridge International School/span/divdiv classheader_row2_rightspanFDCC1/span/div/divdiv classheader_row2_middlespanFD 2022-23 Teachers Timetables/span/div/divdiv classheader_line/div/div!-- 表格 --div classtable_middlea-table :columnscolumns :data-sourcedatasource bordered :paginationfalse!-- 时间段 --tamplate slottimePeriodSlot slot-scopetext, recordspan{{record.period}}brnbsp;nbsp;{{text}} ~ {{record.endTime}}/span/tamplate/a-table/div!-- 页脚 --div classfooterdiv classfooter_line/divdiv classfooter_enddiv classfooter_end_datetime{{this.currentTime}}/divdiv classfooter_end_pages{{this.pageNum}}/div/div/div/div
/templatescriptlet columns [{title: 教师,dataIndex: startTime,scopedSlots: { customRender: timePeriodSlot },customCell: () {return {style: {min-width: 120px,},};},},{title: Monday,children: [{title: ,dataIndex: monday,key: monday,customCell: () {return {style: {min-width: 180px,},};},},],},{title: Tues,children: [{title: ,dataIndex: tuesday,key: tuesday,scopedSlots: { customRender: childrenRender },customCell: () {return {style: {min-width: 180px,},};},},],},{title: Wed,children: [{title: ,dataIndex: wednesday,key: wednesday,scopedSlots: { customRender: childrenRender },customCell: () {return {style: {min-width: 180px,},};},},],},{title: Thurs,children: [{title: ,dataIndex: thursday,key: thursday,scopedSlots: { customRender: childrenRender },customCell: () {return {style: {min-width: 180px,},};},},],},{title: Friday,children: [{title: ,dataIndex: friday,key: friday,scopedSlots: { customRender: childrenRender },customCell: () {return {style: {min-width: 180px,},};},},],},
];export default {name: pdfExport,data() {return {currentTime: ,pageNum: Page 1 of 1,datasource: [],}},computed: {columns() {return columns}},created() {this.getCurrentTime();},methods: {setDataList(list, pageFooter) {this.datasource listif(this.datasource.length 0) {this.columns[0].title this.datasource[0].instructor}this.sortByStartTime()if(pageFooter) {this.pageNum pageFooter}},sortByStartTime() {this.datasource.sort((a, b) {const timeA new Date(2023/01/01 ${a.startTime});const timeB new Date(2023/01/01 ${b.startTime});return timeA - timeB;});},getCurrentTime() {const date new Date();const month date.getMonth() 1;const day date.getDate();const year date.getFullYear();const hours date.getHours();const minutes date.getMinutes();const seconds date.getSeconds();// 格式化为指定格式的字符串const dateString ${this.formatNumber(month)}/${this.formatNumber(day)}/${year};const timeString ${this.formatNumber(hours)}:${this.formatNumber(minutes)}:${this.formatNumber(seconds)};this.currentTime ${dateString} ${timeString};},formatNumber(number) {return number 10 ? 0${number} : number;}}
}
/scriptstyle scoped langless.content {padding: 15px;color: black;}/**头部属性样式设置*/.header_row1 {display: flex;justify-content: center;font-size: 16px;margin-bottom: 3px;position: relative;}.header_row1 .header_row1_middle {font-weight: 700;position: absolute;}.header_row2 {display: flex;justify-content: center;font-size: 16px;margin-bottom: 15px;position: relative;}.header_row2 .header_row2_middle {font-size: 22px;font-weight: 700;position: absolute;}.header_row1_left,.header_row1_right,.header_row2_left,.header_row2_right {display: inline-block;}.header_row1_v,.header_row2_v {width: 100%;}.header_row1_left,.header_row2_left {float: left;}.header_row1_right,.header_row2_right {float: right;}.header_line {border: 1px solid black;margin-bottom: 5px;}/**中间属性样式设置*//* 将表格的标题行背景设置为白色 */.ant-table-thead {::v-deep tr th {background: #fff;}}/* 将所有边框设置为黑色 */.table_middle {/deep/ .ant-table {color: black;font-size: 16px;}/deep/ .ant-table-bordered .ant-table-thead tr:first-child th:first-child {border-left: none;border-top: none;font-weight: 700;text-align: left;}/deep/ .ant-table-bordered .ant-table-thead tr:not(:last-child) th {border-bottom: 2px solid black;border-top: 2px solid black;font-weight: normal;text-align: center;}/deep/ .ant-table-bordered .ant-table-thead tr th{border-right: 2px solid black;border-bottom: 2px solid black;}/deep/.ant-table-bordered .ant-table-tbody tr td {border-right: 2px solid black;border-bottom: 2px solid black;}/deep/ .ant-table-bordered .ant-table-tbody tr td:first-child {border-left: 2px solid black;}/deep/ .ant-table-bordered.ant-table-empty .ant-table-placeholder {border: 2px solid black;border-top: 1px solid black;}}/**页脚属性样式设置*/.footer .footer_line {border: 1px solid black;}.footer {font-size: 16px;}.footer_line {margin-top: 75px;margin-bottom: 3px;}.footer_end {display: flex;justify-content: space-between;}
/styleindex.js pdf导出单页方法
export const printPdf (dom, name 文件) {const printEle domlet width printEle.scrollWidth;let height printEle.scrollHeight;html2canvas(printEle, {allowTaint: true, //允许跨域useCORS: true,width: width,height: height,background: #FFFFFF, //如果指定的div没有设置背景色会默认成黑色scale: 2 // 按比例增加分辨率}).then(canvas {let contentWidth canvas.widthlet contentHeight canvas.height//a4纸的尺寸[595.28,841.89]html页面生成的canvas在pdf中图片的宽高let pdf new jsPDF(l, pt, a4)let imgWidth pdf.internal.pageSize.getWidth()let imgHeight (imgWidth / contentWidth) * contentHeightlet pageData canvas.toDataURL(image/jpeg, 1.0)//有两个高度需要区分一个是html页面的实际高度和生成pdf的页面高度(841.89)//当内容未超过pdf一页显示的范围无需分页pdf.addImage(pageData, JPEG, 5, 5, imgWidth, imgHeight)pdf.save(${name}.pdf)})
}
index.js pdf导出分页方法
import html2canvas from html2canvas
import { jsPDF } from jspdfexport const printPdf (dom, name 文件) {let contents dom.getElementsByClassName(content)return exportToPDF(contents, name)
}//导出pdf
async function exportToPDF(contents, name exportPdf) {// 创建一个空的横向A4大小的PDF文档对象const pdf new jsPDF(l, pt, a4);let yPosition 5; // 当前y坐标位置for (let i 0; i contents.length; i) {const content contents[i];let width content.scrollWidth;let height content.scrollHeight;// 使用html2canvas将content转换为canvasconst canvas await html2canvas(content, {allowTaint: true, //允许跨域useCORS: true,width: width * 1.02,height: height,background: #FFFFFF, //如果指定的div没有设置背景色会默认成黑色scale: 2 // 按比例增加分辨率})// 如果是下一个content的内容则创建新的页码if (i 0) {pdf.addPage();yPosition 5;}let pageData canvas.toDataURL(image/jpeg, 1.0)//宽度使用pdf的宽度let imgWidth pdf.internal.pageSize.getWidth()//高度根据宽度的比列计算let imgHeight (imgWidth / canvas.width) * canvas.height// 将canvas添加到PDF中pdf.addImage(pageData, JPEG, 5, yPosition, imgWidth, imgHeight)yPosition pdf.internal.pageSize.getHeight();}// 输出PDF文件pdf.save(${name}.pdf)return new Promise((resolve, reject) {resolve()})
}