JS纯前端导出PDF及分页和使用window.print()保存PDF
最近由于项目要求需要将导出PDF类文件,其中涉及到固定表头,翻页,样式调整等问题 一开始选择了网上较多讲解的使用html2canvas.js和jspdf.js先转图片再转PDF的方法。
var xsxf = document.getElementById("export_content");html2canvas(xsxf,//document.getElementById("export_content"),{dpi: 172,//导出pdf清晰度//proxy: "string",onrendered: function (canvas) {var contentWidth = canvas.width;var contentHeight = canvas.height;//一页pdf显示html页面生成的canvas高度;var pageHeight = 840;//var pageHeight = contentWidth / 575 * 840;//未生成pdf的html页面高度var leftHeight = contentHeight;//pdf页面偏移var position = 0;//html页面生成的canvas在pdf中图片的宽高(a4纸的尺寸[595.28,841.89])var imgWidth = 595.28;var imgHeight = 592.28 / contentWidth * contentHeight;var pageData;var pdf = new jsPDF('', 'pt', 'a4');//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)//当内容未超过pdf一页显示的范围,无需分页if (leftHeight < pageHeight) {pageData = canvas.toDataURL('image/jpeg', 1.0);pdf.addImage(pageData, 'JPEG', 10, 5, imgWidth - 20, imgHeight - 10);} else {while (leftHeight > 0) {pageData = canvas.toDataURL('image/jpeg', 1.0);pdf.addImage(pageData, 'JPEG', 10, position + 5, imgWidth - 20, imgHeight - 10)leftHeight -= pageHeight;position -= 841.89;//避免添加空白页if (leftHeight > 0) {pdf.addPage();}}}pdf.save(filename);},//背景设为白色(默认为黑色)background: "#fff"});
但很快发现当表格数据量大时出现翻页问题,所以试着先将表头固定数据取出,表体数据进行分割拼接表头
//大于一页分页表头固定function reFullHtml(wb, filename, _tableHead, rowNum, pageHeight) {var tableH = document.querySelector('#table_content').scrollHeight + 70;var miH = (pageHeight - tableH); //详细var trL = $('#mini-grid-table1 > tbody>tr').length;var max = parseInt(miH / 34);var firstNum = rowNum - 2 + max;var page = Math.ceil(trL / max);var brhtml = "</table></br></br></br></br></br>";//PL表尾if (rowNum == 12 && firstNum > (trL + rowNum - 5)) {firstNum = trL + rowNum - 6;page = Math.ceil(trL / (max - 5));brhtml = brhtml + "</br></br></br></br></br></br></br></br></br>";}//CI表尾(特殊德国小家电)if (rowNum == 14 && firstNum > (trL + rowNum - 1)) {firstNum = trL + rowNum - 2;page = Math.ceil(trL / (max - 1));brhtml = brhtml + "</br></br>";}//判断一页内行数高度+表头高是否大于页高if ((firstNum - rowNum) * 34 + 75 > miH) {firstNum -= 1;brhtml = '</table></br></br></br></br></br></br></br>';}var beforNum = firstNum;var newWb = wb;var pNum = firstNum - rowNum - 2;var syNum = pageHeight - (pNum + 1) * 34 - tableH;var nbrHtml = "</table>"for (var c = 0; c < Math.ceil(syNum / 20); c++) {nbrHtml += "</br>"}for (var i = 0; i < page - 1; i++) {if ((firstNum - beforNum) * 34 + 75 > miH) {firstNum -= 1;brhtml = '</table></br></br></br></br></br></br></br>';}beforNum = firstNum;var reg = "<tr><td style='text-align: center; border-bottom: 1px solid #000000; border-right: 1px solid #000000; font-size: 10px; font-family: 微软雅黑; word-wrap:break-word; height:33px;' t='[a-z]' id='sjs-A" + firstNum + "'>.*";var res = newWb.match(reg);if (res != null) {if (res.length > 0) {var newHead = newWb.replace(res[0], brhtml);newWb = newHead + _tableHead + res[0];}}firstNum += pNum;brhtml = nbrHtml;}if (firstNum < (trL + rowNum)) {if (rowNum == 12) {firstNum = trL + rowNum - 6;brhtml = "</table></br></br></br></br></br></br></br></br></br></br></br></br></br>";}else if (rowNum == 14) {firstNum = trL + rowNum - 2;brhtml = "</table></br></br></br></br></br></br>";}var reg1 = "<tr><td style='text-align: center; border-bottom: 1px solid #000000; border-right: 1px solid #000000; font-size: 10px; font-family: 微软雅黑; word-wrap:break-word; height:33px;' t='[a-z]' id='sjs-A" + firstNum + "'>.*";var res1 = newWb.match(reg1);if (res1 != null) {if (res1.length > 0) {var newHead = newWb.replace(res1[0], brhtml);newWb = newHead + _tableHead + res1[0];}}}var xsxf = document.getElementById("export_content");xsxf.innerHTML = "</br>" + newWb;rowNum = 1;if (newWb != "") {//var pageWidth = document.querySelector("#mini-grid-table1").scrollWidth;for (var p = 0; p < document.querySelectorAll("#sjs-A1").length; p++) {document.querySelectorAll("#sjs-A1")[p].width = (pageWidth - 20) + "px";document.querySelectorAll("#sjs-A5")[p].width = (pageWidth - 20) / 2 + "px";document.querySelectorAll("#sjs-E5")[p].width = (pageWidth - 20) / 2 + "px";}downPDF(newWb, filename, _tableHead, rowNum);}}
分页解决完毕后,业务部门使用后反馈PDF过于模糊和数据无法复制,无奈寻找其他方法。
最后确定使用window.print()原生打印方法来保存。
其中碰到几个坑:
1、当表格宽度大于A4纸时,表格列宽会被挤压变现导致之前设置的列宽无效从而使分页出现问题
2、分页容纳行数算法和使用wp打印显示行数不一致,固尝试多次后固定行数
解决方案:
1、分页属性:style=‘page-break-after:always’ 分页属性 table 加上后会自动分页
2、设置表格宽度,其中表格宽最大设置到1000,大于1000时会变形
table {width:750px;
}
3、特殊列设置固定宽(列文字多的),其他使用百分比
function downPDF(wb, filename, _tableHead, rowNum, dataNum) {var xsxf = document.getElementById("export_content");html2canvas(xsxf,//document.getElementById("export_content"),{//dpi: 172,//导出pdf清晰度dpi: 144,//proxy: "string",onrendered: function (canvas) {var contentWidth = canvas.width;var contentHeight = canvas.height;//一页pdf显示html页面生成的canvas高度;var pageHeight = 840;//var pageHeight = contentWidth / 575 * 840;//未生成pdf的html页面高度var leftHeight = contentHeight;//pdf页面偏移var position = 0;//html页面生成的canvas在pdf中图片的宽高(a4纸的尺寸[595.28,841.89])var imgWidth = 595.28;var imgHeight = 592.28 / contentWidth * contentHeight;var pageData;var pdf = new jsPDF('', 'pt', 'a4');if (leftHeight > pageHeight) {if (rowNum != 1) {reFullHtml(wb, filename, _tableHead, rowNum, dataNum);return;}}//20210826 hsj 原转PDF转图片失真严重,直接调用window打印方法保存//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)//当内容未超过pdf一页显示的范围,无需分页//if (leftHeight < pageHeight) {// pageData = canvas.toDataURL('image/jpeg', 1.0);// pdf.addImage(pageData, 'JPEG', 10, 5, imgWidth - 20, imgHeight - 10);//} else {// while (leftHeight > 0) {// pageData = canvas.toDataURL('image/jpeg', 1.0);// pdf.addImage(pageData, 'JPEG', 10, position + 5, imgWidth - 20, imgHeight - 10)// leftHeight -= pageHeight;// position -= 841.89;// //避免添加空白页// if (leftHeight > 0) {// pdf.addPage();// }// }//}//pdf.save(filename);window.print();},//背景设为白色(默认为黑色)background: "#fff"});
}
//大于一页分页表头固定function reFullHtml(wb, filename, _tableHead, rowNum, dataNum) {var trL = $('#mini-grid-table1 > tbody>tr').length;var max = 20;if (dataNum>10) {max = 27;}else if (dataNum == 10){max = 25;}else if (dataNum >7) {max = 22;}var firstNum = rowNum + 2 + max;var page = Math.ceil(trL / max);var brhtml = "</table>";var newWb = wb;for (var i = 0; i < page - 1; i++) {var reg = "<tr><td style='text-align: center; border-bottom: 1px solid #000000; border-right: 1px solid #000000; font-size: 10px; font-family: 微软雅黑; word-wrap:break-word; height:33px;' t='[a-z]' id='sjs-A" + firstNum + "'>.*";var res = newWb.match(reg);if (res != null) {if (res.length > 0) {var newHead = newWb.replace(res[0], brhtml);//style='page-break-after:always' 分页属性newWb = newHead + "</div><div style='page-break-after:always'>" + _tableHead + res[0];}}else {if (rowNum == 12) {firstNum = trL + rowNum - 5;brhtml = "</table>";}else if (rowNum == 14) {firstNum = trL + rowNum - 1;brhtml = "</table>";}var reg1 = "<tr><td style='text-align: center; border-bottom: 1px solid #000000; border-right: 1px solid #000000; font-size: 10px; font-family: 微软雅黑; word-wrap:break-word; height:33px;' t='[a-z]' id='sjs-A" + firstNum + "'>.*";var res1 = newWb.match(reg1);if (res1 != null) {if (res1.length > 0) {var newHead = newWb.replace(res1[0], brhtml);newWb = newHead + "</div><div style='page-break-after:always'>" + _tableHead + res1[0];}}}firstNum += max;}if (firstNum < (trL + rowNum)) {if (rowNum == 12) {firstNum = trL + rowNum - 5;brhtml = "</table>";}else if (rowNum == 14) {firstNum = trL + rowNum - 2;brhtml = "</table>";}var reg1 = "<tr><td style='text-align: center; border-bottom: 1px solid #000000; border-right: 1px solid #000000; font-size: 10px; font-family: 微软雅黑; word-wrap:break-word; height:33px;' t='[a-z]' id='sjs-A" + firstNum + "'>.*";var res1 = newWb.match(reg1);if (res1 != null) {if (res1.length > 0) {var newHead = newWb.replace(res1[0], brhtml);newWb = newHead + "</div><div style='page-break-after:always'>" + _tableHead + res1[0];}}}var xsxf = document.getElementById("export_content");xsxf.innerHTML = "<div style='page-break-after:always'>" + newWb + "</div>";rowNum = 1;if (newWb != "") {if (dataNum >= 10) {for (var n = 0; n < document.querySelectorAll("table").length; n++) {document.querySelectorAll("table")[n].style.width = '900px';document.querySelectorAll("table")[n].style.width = '900px';}}for (var p = 0; p < document.querySelectorAll("#sjs-A1").length; p++) {document.querySelectorAll("#sjs-A1")[p].width = (pageWidth - 20) + "px";document.querySelectorAll("#sjs-A5")[p].width = (pageWidth - 20) / 2 + "px";document.querySelectorAll("#sjs-E5")[p].width = (pageWidth - 20) / 2 + "px";}downPDF(newWb, filename, _tableHead, rowNum);}}
效果
总结:总体来说还是使用最开始导出PDF的思路,先在html中解决分页问题后导出,不过放弃转成图片方式而直接使用原生方法。整体解决了分页问题和不清晰无法复制等问题。
参考资料:https://www.jianshu.com/p/4d65857ffe5e
https://segmentfault.com/a/1190000018701596
JS纯前端导出PDF及分页和使用window.print()保存PDF相关推荐
- 纯前端导出word、pdf、excel、txt、svg文档方法与技巧(附带问题总结)
文章目录 导出pdf **实现思路:** **问题总结:** **具体代码** **封装好的导出函数,记得引入js插件** 封装方法一: 封装方法二: 封装方法三: 纯前端导出word文档方法与技巧 ...
- Vue导出word附表部分横向显示(承接上一篇Vue纯前端导出word)
Vue纯前端导出word直通车 1. 引入js import htmlDocx from "@/utils/html-docx"; 2. page-break-before:alw ...
- JS纯前端实现文件保存
JS纯前端实现文件保存 <body><a href="" id="a">click here to download your file ...
- vue element ui 利用xslx导出文档表格功能(纯前端导出下载文档)
目录 前言 步骤: 1.下载xslx 2.导入xslx 3.template中给个点击事件 4.methods中定义函数实现导出 前言 本篇文章记录纯前端导出下载文档功能. 若想查看从后端接收文件流, ...
- VUE纯前端导出excel表格功能《转载》
插件:使用vue-json-excel插件实现Vue纯前端导出简单的Excel表格功能. 使用方法 1. 安装依赖 npm install vue-json-excel 2. 引入组件 a. 全局引入 ...
- 不用任何 js 库,纯前端导出数据到 Excel / CSV 文件就这么简单几行代码
最近实现的导出数据为表格的需求,不需要工具库,也不要后端实现,mark 一下. js 导出 excel 表格 最近工作中又遇到了将表格数据导出为 excel 表格的需求,我第一时间想到的是之前我的网站 ...
- vue 前端导出Excel表格(基础版 + 多级标题)纯前端导出
先看效果 纯前端基础导出的Excel表格 纯前端多级表头导出的Excel表格 基础导出下面赋源代码 1.安装依赖 npm install vue-json-excel 2.在项目的入口 main.js ...
- 纯前端导出export,复杂表格表头合并,表头数据部分动态,
需求,这样的页面 有多个table,如投标人名单结果那一列,返回的是1就是通过,返回的不是1就是不通过.如资格评审的横表头,评分说明后面的公司即都是数据接口返的,需要处理后才能放在表头这里的.如详细评 ...
- js 使用前端导出excel,设置标题和页脚,实现特殊表格需求
js前端导出excel,网上的例子很多,大部分都是使用如下代码: //统计导出$scope.statisExport=function(){toOutPutExcel('statisTable', ' ...
- html贝塞尔曲线在线,【HTML+js+纯前端】三次方贝塞尔曲线手工拟合小工具
本帖最后由 南郊居士 于 2020-2-18 23:38 编辑 2020.2.18 重要修正: 1. 修正了当图样长宽不同时不能正确显示各控制点的问题. (一整天了都没人吐槽这个问题,看来这个工具还真 ...
最新文章
- pythonassertbug_还在 Bug 不断?不妨试试这 2 个装X技巧
- oracle crs 不能启动,oracle 10g crs 不能启动问题解决案例
- vscode / ubuntu 下编译和调试 C/C++ 方法
- Firefox火狐浏览器自用技巧汇总--以备使用--13.5.16
- 最全的数据结构解析与归纳
- svn 1.6 linux 下载,LINUX下Subversion1.6.17 部署
- 妈的我好像发现是哪出问题了
- oracle导出表中某天数据命令,Oracle数据库使用命令行导入导出数据表及数据内容(本地、远程)...
- 欺诈场景中的随机森林实践(基于SAS场景的实现)
- Djunit工作记录
- Python脚本实现深大校园网网页登陆
- 揭秘Spring——《Spring 揭秘》读书笔记纲要
- 硬原理——DC-DC升压(BOOST)电路原理
- python项目报告怎么写_python项目
- 复习Python爬取必应的壁纸
- 动态爱心表白代码(绝对炫酷)
- STM32——CAN通信实验
- [Slides notes] Other notes using Excel
- 淘宝PC自动化测试框架AutomanX-王超
- hdu 1859 最小长方形