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
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhffhjji
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13