result:
Business: Print the table on the right side of the page into a pdf in the desired format. The first problem encountered is that the table has scroll wheels on the top, bottom, left and right, and html2canvas is equivalent to a screenshot. How to display the scroll area is a problem?
The gif is a bit blurry, but the general function can be seen
Copiable code is at the bottom
Reference article: The main idea is that since the original height and width of the table are wrong, you should restore its width and height to the real height and width before converting to PDF, then print it to PDF, and finally convert it to the original height and width. (It is worth noting that the height and width of the canvas must also be set, just like the table)
html code:
script code
There is an “Export button” on the table. Clicking it will trigger the handleExport function.
All code:
html:
<div ref="myContainer" id="fatherDiv" class="demo-form-inline" style="height: calc(100% - 120px)" > <el-table ref="workforceTable" :data="tableData" border @drop.native="drop($event)" @dragover.native="allowDrop($event)" stripe :span-method="objectSpanMethod" :cell-class-name="tableCellClassName" max-height="100%" height="100%" class="demo-form-inline" id="factTable" > <el-table-column prop="time" label="time" width="70" align="center" fixed ></el-table-column> <el-table-column :prop="item.sectorCode" :label="item.sectorName" v-for="item in sectorList" :key="item.sectorCode" align="center" > <el-table-column :prop="seat.seatId" :label="seat.seatName" v-for="seat in item.seatList" :key="seat.seatId" align="center" min-width="102px" > <template slot-scope="scope"> <span :defProp="seat.seatId" :defTime="scope.row.time" :defIndex="scope.$index" ></span> <span class="el-tag el-tag--light" defid="scope.row[seat.seatId]" v-if="scope.row[seat.seatId]" > <!-- Name (team name) --> <!-- {<!-- -->{ scope.row[seat.seatId] + "(" + scope.row["team" + seat.seatId] + ")" }} --> <!-- Name --> {<!-- -->{ scope.row[seat.seatId] }} <i class="el-tag__close el-icon-close" @click="onRemovePerson(scope.$index, seat.seatId)" v-if="isManual" ></i> </span> </template> </el-table-column> </el-table-column> <el-table-column :prop="seat.seatId" :label="seat.seatName" v-for="seat in seatList" :key="seat.seatId" align="center" min-width="102px" > <template slot-scope="scope"> <span :defProp="seat.seatId" :defTime="scope.row.time" :defIndex="scope.$index" ></span> <span class="el-tag el-tag--light" defid="scope.row[seat.seatId]" v-if="scope.row[seat.seatId]" > <!-- Name (team name) --> <!-- {<!-- -->{ scope.row[seat.seatId] + "(" + scope.row["team" + seat.seatId] + ")" }} --> <!-- Name --> {<!-- -->{ scope.row[seat.seatId] }} <i class="el-tag__close el-icon-close" @click="onRemovePerson(scope.$index, seat.seatId)" v-if="isManual" ></i> </span> </template> </el-table-column> </el-table> </div>
script code:
handleExport() { this.$nextTick(() => { let pdfName = (this.deptRegion == "TWR" ? "Tower" : this.deptRegion == "APP" ? "Approach" : "area") + "Control Room" + this.$common.parseTime(this.selectedMonth, "{y}/{m}/{d}") + "Daily schedule"; document .getElementsByClassName("demo-form-inline")[0] .classList.add("export-pdf-style"); this.generatePDF(this.$refs.myContainer, pdfName); }); }, generatePDF(el, name) { let bodyWrapper = document.querySelector( "#factTable .el-table__body-wrapper" ); let headerNode = document.querySelector( "#factTable .el-table__header-wrapper" ); bodyWrapper.style.height = `${bodyWrapper.scrollHeight}px`; document.getElementById("fatherDiv").style.width = `${bodyWrapper.scrollWidth}px`; document.getElementById("fatherDiv").style.height = `${bodyWrapper.scrollHeight + headerNode.scrollHeight not}px`; setTimeout(function () { html2canvas(el, { scale: 4, width: bodyWrapper.scrollWidth + 60, // In order to display all the contents of the horizontal scroll bar, this must be specified! ! height: bodyWrapper.scrollHeight + headerNode.scrollHeight, }).then((canvas) => { let contentWidth = canvas.width; let contentHeight = canvas.height; let pageHeight = (contentWidth / 592.28) * 841.89; //One page of pdf displays the canvas height generated by the html page; let leftHeight = contentHeight; //HTML page height without generating pdf let position = 0; //Page offset let imgWidth = 595.28; //The size of a4 paper [595.28,841.89], the width and height of the canvas generated by the html page in the pdf image let imgHeight = (592.28 / contentWidth) * contentHeight; let pageData = canvas.toDataURL("image/jpeg", 1.0); let pdf = new jsPDF("", "pt", "a4"); if (leftHeight < pageHeight) { //There are two heights that need to be distinguished, one is the actual height of the html page, and the page height of the generated pdf (841.89) pdf.addImage(pageData, "JPEG", 5, 30, imgWidth, imgHeight); //When the content does not exceed the display range of one PDF page, no paging is required } else { while (leftHeight > 0) { pdf.addImage(pageData, "JPEG", 5, position, imgWidth, imgHeight); //arg3-->distance from left margin; arg4-->distance from top margin; arg5-->width; arg6-->height leftHeight -= pageHeight; position -= 841.89; if (leftHeight > 0) { //Avoid adding blank pages pdf.addPage(); //Add new page } } } pdf.save(`${name}.pdf`); document.getElementById("fatherDiv").style.width = `${100}%`; document.getElementById("fatherDiv").style.height = `calc(100% - 120px)`; document.getElementsByClassName("demo-form-inline")[0].classList.remove("export-pdf-style"); }); }, 200); },
css code:
.export-pdf-style >>> .el-table , .export-pdf-style >>> .el-tag{ background: white !important; color: black !important; } .export-pdf-style >>> .el-table th, .export-pdf-style >>> .el-table .el-table__cell { color: black; border: 1px solid black; background: white !important; }
The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Vue entry skill tree Home page Overview 39301 people are learning the system