博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Web打印连续的表格,自动根据行高分页
阅读量:5066 次
发布时间:2019-06-12

本文共 16641 字,大约阅读时间需要 55 分钟。

拿到这个需求,我已经蛋碎了一地,经过N天的攻克,终于是把它搞定了,只是不知道会不会在某种情况下出现BUG。表示我心虚没有敢做太多的测试....

----------------------------------------------------------废话分割线-----------------------------------------------------------

注:我们的系统是基于ligerui这个一堆bug的插件的。

详细需求:

  1.任意一个表格,行高不均匀且不相等;

  2.数字、公式等,不能换行;

  3.A3、A4纸横向打印,用户可选;

  4.JavaScript实现

  5.每页都要有表头、总记录数、当前页和总页数

整体思路:

  1.js无法获取打印机的信息,所以,要用户在我们系统中选择好纸张大小,然后打印的时候再选一次,个人认为这个要自动适配并不容易,反正我的是手动选的。

  2.数字、公式不能换行,如果表格横向特别长,就不能使用css:word-break进行强制换行,只能由它默认的去换行。

  3.js打印肯定是先新建个空白的页面,然后把东西展示出来,用Jquery.Print这个插件调用浏览器的所见即所得这种方式去打印。

  4.页面上有个隐藏的模版,规定表格、标题、汇总信息的样式,并给定Id,或者Class,以便后续Jquery取得时候比较方便(后面我贴源码出来)。

  5.先把整个表格都展示出来,给定它宽度(A3/A4纸的宽度)之后,它的每一行的高度就确定了。

  6.这时候去遍历这个表格,可以把每一行的高度都取出来,循环的累加它,当高度超过纸张高度时,就记录下来这个开始行数(startLine)和结束行数(endLine),然后Jquery创建一个表格,从步骤4的表格中,把它的表头取出来,Append到新创建的表格中,然后根据开始行数和结束行数,把这些tr取出来,也Append到新创建的表格中。

  7.从模板中取出来标题、汇总信息等的模版,然后把它替换成想要的内容之后,append到上面的表格的前后。

  8.打印设置纸张大小思路:给个打印设置的弹出层,上面有A3/A4两个单选按钮,选完,点击页面上的确定按钮,我把这个选中值存到cookie里面,打印的时候,从cookie里面取出来,然后去给定纸张的高度和宽度。

以上就是整体的思路,下面贴代码(注:css其实也是蛮重要的,但是css前面不是我写的,后面我忘记改了哪些东西了,所以贴出来也没卵用)。

1.打印所使用的HTML模板

1    
2
17
18
19
46
打印模版

2.jquery.printTable.js,这个是网上找的,我改了一些,它默认里面的总页数算法是有问题的,我做了调整,我还新增了列宽的指定等,具体我也记不清了,有兴趣的可以对比一下,我完了以附件的形式上传这个js插件。

1 /**  2  * jquery 表格打印插件  3  *  4  * 作者: LiuJunGuang  5  * 日期:2013年6月4日  6  * 分页样式(需要自定义):  7  * @media print {  8  *    .pageBreak { page-break-after:always; }  9  * }  10  * 使用例子: 11  *  $(function(){ 12  *        $("#tabContent").printTable({ 13  *         mode          : "rowNumber", 14  *         header        : "#headerInfo", 15  *         footer        : "#footerInfo", 16  *         pageNumStyle  : "第#p页/共#P页", 17  *         pageNumClass  : ".pageNum", 18  *         pageSize      : 10 19  *        }); 20  *   }); 21  *  注意事项: 22  *      使用时注意表格中要使用 thead 和 tbody区分出标题头与表格内容,否则可能出现错误 23  *  24  * 参数说明: 25  *  options are passed as json (json example: { rowHeight : "rowHeight", header : ".tableHeader",}) 26  * 27  *  {OPTIONS}        | [type]    | (default), values            | Explanation 28  *  ---------------- | --------- | -----------------------------| ----------- 29  *  @mode            | [string]  | ("rowHeight"),rowNumber      | 分页模式,按行高分页或按行数分页 30  *  @header          | [string]  | (".tableHeader")             | 页面开始处要添加的内同 31  *  @footer          | [string]  | (".tableFooter")             | 页面结束要添加的内容 32  *  @pageSize        | [number]  | (30)                         | 自动分页行数,按行高分页时改参数无效 33  *  @breakClass      | [string]  | ("pageBreak")                | 分页插入符class,需要定义分页样式 34  *  @pageNumStyle    | [string]  | "#p/#P"                      | 页码显示样式,#p当前页,#P总页数 35  *  @pageNumClass    | [string]  | ".pageNumClass"              | 页码class样式,用于设值(使用text方法设置)  36  *  @startPage       | [number]  | (1)                          | 第一页起始页码 37  *  @pageHeight      | [number]  | (297)                        | 页面高度,单位像素 38  *  @topMargin       | [number]  | (15)                         | 上边距高度,单位像素 39  *  @bottomMargin    | [number]  | (15)                         | 低边距高度,单位像素 40  */ 41 (function($) { 42     var modes = { rowHeight : "rowHeight", rowNumber : "rowNumber" }; 43     //默认参数 44      var defaults = {  45              mode          : modes.rowHeight, 46              header        : ".tableHeader", 47              footer        : ".tableFooter", 48              pageSize      : 30, 49              breakClass    : "pageBreak", 50              pageNumStyle  : "第#p页/共#Total#页", 51              pageNumClass  : ".pageNumClass", 52              startPage     : 1, 53              pageHeight    : 720, //A4纸默认在win7下Web中的dpi是96,所以A4纸在win7下的大小换算成像素应该是794×1123,这里留空白 54              topMargin     : 50, 55              bottomMargin  : 50, 56              width         : 1100, //留白100px 57              totalNumClass : "floatRight", 58              containsId :"#print-content" 59          }; 60      var settings = {};//global settings 61      var rowCount = 0;//行总数 62      var pageCount = 0;//页总数 63      var currentPage = 0;//当前页 64      var $header = null;//表格头 65      var $content = null;//表格内容 66      var $footer = null;//表格尾 67      var $table = null; 68      var $tbodyTr = null; 69      var totalPageCount = 0;//总页数 70     $.fn.printTable = function( options ) { 71         $.extend( settings, defaults, options ); 72         $table = $(this); 73         $tbodyTr = $table.find("tbody tr"); 74         var $container = $(settings.containsId); 75         totalPageCount = 0; 76         //$(settings.totalNumClass).text($tbodyTr.length); 77         //$table.width("720pt"); 78         switch ( settings.mode ){ 79             case modes.rowHeight : 80                 rowHeightPage();//行高分页 81                 $container.html($container.html().replace(/#Total/g,totalPageCount)) ; 82                 break; 83             case modes.rowNumber : 84                 rowNumberPage();//行数分页 85         } 86     }; 87     //获取页总数 88     $.fn.printTable.getStartPage = function(startPage) { 89         return getPageStyle(startPage , pageCount); 90     }; 91     //行高分页 92 function rowHeightPage() { 93         var contentHeight =     initHeightPage(); 94         getContentColne(); 95         beginPageByHeight(contentHeight); 96         hidenContent(); 97     } 98      99     100     //行数分页101     function rowNumberPage(){102         initNumberPage();103         getContentColne();104         beginPageByNumber();105         hidenContent();106     }107     108     //按行高分页109     function beginPageByHeight(contentHeight){110         var totalHeight = 0;111         var startLine = 0;112         $tbodyTr.each(function(i){113             var cHeight = $(this).outerHeight(true);114             $(this).height(cHeight);115             if ((totalHeight + cHeight) < contentHeight) {116                 totalHeight += cHeight;117                 if(i == $tbodyTr.length -1){118                     newPage(i + 1);119                 }120             }else{121                 newPage(i);122             }123 });124         125         function newPage(index){126             createPage(startLine,index);127             currentPage++;128             totalPageCount++;129             startLine = index;130             totalHeight = 0;131         }132     }133     134     //初始化高度分页信息135     function initHeightPage(contentHeight){136         var contentHeight =    initContentHeight();137         currentPage = 0 + settings.startPage;138         pageCount = Math.ceil($table.find("tbody").outerHeight(true)/contentHeight) + settings.startPage - 1;//初始化总页数139         rowCount = $tbodyTr.length; //初始化总记录数140         return contentHeight;141     }142     143     144     //初始化内容高度145     function initContentHeight(){146         var headerHeight = $(settings.header).outerHeight(true);147         var footerHeight = $(settings.footer).outerHeight(true);148         $table.find("thead td").each(function(i) {149             var cWidth = $(this).outerWidth(true);150             $(this).width((cWidth / 96 * 72) + "pt");151         });//给表头一个宽度,但是貌似打印的时候不顶卵用152         var theadHeight = $table.find("thead").outerHeight(true);153         var tableHeight =  settings.pageHeight - settings.topMargin - settings.bottomMargin ;154         var tbodyHeight =  tableHeight - theadHeight- headerHeight - footerHeight;155         return tbodyHeight;156     }157     //初始化分页基本信息158     function initNumberPage(){159         rowCount = $tbodyTr.length;//初始化总记录数160         pageCount =  Math.ceil(rowCount/settings.pageSize) + settings.startPage - 1;//初始化总页数161         currentPage = 0 + settings.startPage;162     }163     164     //开始分页165     function beginPageByNumber(){166         var startLine = 1;//开始行号167         var offsetLine = 0;//偏移行号168         for(var i = settings.startPage; i <= pageCount  ;i++ ){169             currentPage = i;170             startLine = settings.pageSize* (currentPage - settings.startPage);171             offsetLine = (startLine + settings.pageSize) > rowCount ? rowCount : startLine + settings.pageSize;172             createPage(startLine,offsetLine);173         };174     }175      //创建新的一页176     function createPage(startLine, offsetLine) {177         var $pageHeader = $header.clone();178         var $pageContent = $content.clone().append(getTrRecord(startLine, offsetLine));179         var $pageFooter = $footer.clone();180         $pageFooter.find(settings.pageNumClass).text(getPageStyle(currentPage , pageCount));//页码显示格式181         if(offsetLine == rowCount){182             $table.before($pageHeader).before($pageContent).before($pageFooter);183         }else{184             $table.before($pageHeader).before($pageContent).before($pageFooter).before(addPageBreak());185 }186     }187     188     //添加分页符189     function addPageBreak(){190         return "
";191 }192 193 //获取分页样式194 function getPageStyle(currentPage , pageCount){195 var numStr = settings.pageNumStyle;196 numStr = numStr.replace(/#p/g,currentPage);197 //numStr = numStr.replace(/#P/g,pageCount);198 return numStr;199 }200 201 202 //获取记录203 function getTrRecord(startLine,offsetLine){204 return $tbodyTr.clone().slice(startLine,offsetLine);205 }206 //获取内容207 function getContentColne(){208 $header = $(settings.header).clone().removeAttr("id");209 $content = $table.clone().find("tbody").remove().end().removeAttr("id");210 $footer = $(settings.footer).clone().removeAttr("id");211 }212 //隐藏原来的数据213 function hidenContent(){214 $(settings.header).hide();215 $table.hide();216 $(settings.footer).hide();217 }218 })(jQuery);
Jquery.printTable.js

3.打印预览的实现js

1  var win = null;  2        // var winPrintSetting = null;  3         //打印预览函数  4         function grid_PrintView() {  5             if (win) {  6                 win.show();  7                 return;  8             }  9             var grid = $(".listgrid:first").ligerGrid(); 10             //            var oldpageSize = grid.options.pageSize; 11             //            grid.options.pageSize = grid.filteredData.Rows.length; 12             //            grid.reload(); 13  14             $(".Printtable:gt(0)").remove(); 15             $(".header:gt(0)").remove(); 16             $(".headInfo:gt(0)").remove(); 17             $(".signatureArea:gt(0)").remove(); 18             $(".header  h2").text(TABData[0].标题); 19             $(".headInfo .floatRight").text("记录总数:" + grid.currentData.Rows.length); 20            $(".Printtable:last").find("thead").html(""); 21             $(".Printtable:last").find("tbody").html("");//清空第一个表格的thead和tbody 22             $(".Printtable:last thead").append($(".l-grid2  .l-grid-header-inner  tbody")[0].innerHTML); 23             $(".Printtable:last tbody").append($(".l-grid2  .l-grid-body-table tbody")[0].innerHTML);//重新把所有的数据给到这个表格 24             $(".Printtable:last *").removeAttr("class"); 25             $(".Printtable:last *").removeAttr("style");//清理掉样式 26             $(".header").show(); 27             $("#tabContent").show(); 28             win = $.ligerDialog.open( 29         { height: 794, target: $("#print-content"), width: 1090, showMax: true, showToggle: true, showMin: true, isResize: true, modal: false, title: '打印预览       ', slide: true }); 30             win.max(); 31             ChangePages(); 32         } 33 //把一个连起来的表格拆分 34         function ChangePages() { 35             var height = 930; 36             var paper_size = $.cookie('paper_size'); 37             if (paper_size == 'A4') { 38                 height = 580; 39                 $(".print-content").width("700pt"); 40             } else { 41                 height = 930; 42                 $(".print-content").width("1000pt"); 43             } 44             $(".Printtable:last").printTable({ 45                 mode: "rowHeight", 46                 header: "#header", 47                 //footer: "#footerInfo",signatureArea 48                 footer: "#footerInfo", 49                 pageNumStyle: "第#p页/共#Total页", 50                 pageNumClass: ".pageNum", 51                 pageHeight: height, //A4:580 ,A3 930 52                 startPage: 1, 53                 totalNumClass: ".floatRight", 54                 containsClass: "#print-content" 55             }); 56         } 57         //改变打印纸大小时 58         function ChangePaper() { 59           var grid = $(".listgrid:first").ligerGrid(); 60             $(".Printtable:gt(0)").remove(); 61             $(".header:gt(0)").remove(); 62             $(".signatureArea:not(:last)").remove();//清理当前已经分页分好的表格,把除了第一个表格外的所有表格都干掉 63             $(".header  h2").text(TABData[0].标题); 64             $(".headInfo .floatRight").text("记录总数:" + grid.currentData.Rows.length); 65             $(".pageBreak").remove(); 66             $(".Printtable:first").find("thead").html(""); 67             $(".Printtable:first").find("tbody").html("");//清空第一个表格的thead和tbody 68             $(".Printtable:first thead").append($(".l-grid2  .l-grid-header-inner  tbody")[0].innerHTML); 69             $(".Printtable:first tbody").append($(".l-grid2  .l-grid-body-table tbody")[0].innerHTML);//重新把所有的数据给到这个表格 70             $(".Printtable:first *").removeAttr("class"); 71             $(".Printtable:first *").removeAttr("style");//清理掉样式 72             $(".header").show(); 73             $(".signatureArea").show(); 74             ChangePages(); 75         } 76  77         var winPrintSetting = null; 78         //纸张大小设置 79         function PrintSetting() { 80             var paper_size = $.cookie('paper_size'); 81             if (paper_size) { 82                 $("input[name='paper_size'][value='" + paper_size + "']").attr("checked", true); 83             } else { 84                 $.cookie('paper_size', 'A3', { expires: 30 }); 85                 $("input[name='paper_size'][value='A3']").attr("checked", true); 86             } 87             win.min(); 88             89             if (winPrintSetting) { 90                 winPrintSetting.show(); 91             } else { 92                 winPrintSetting = $.ligerDialog.open({ 93                     target: $("#print-setting"), 94                     height: 200, 95                     width: 300, 96                     modal: true, 97                     title: "打印设置", 98                     allowClose: false, 99                     isHidden:true,100                     buttons: [{ text: '确定', onclick: function (item, dialog) {101                         var paperSize = $("[name=paper_size]:checked").val();102                         $.cookie('paper_size', paperSize, { expires: 30 });103                             win.max();104                             win.active();105                             ChangePaper();106                             dialog.hide();107                     }108                     }, { text: '取消', onclick: function (item, dialog) {109                         win.max();110                         win.active();111                         dialog.hide();112                     }113                     }]114                 });115             }116            117         }
打印预览的展示,调整纸张大小

4.没了

注意事项:改变纸张之后调整现有页面的宽度、高度的时候,记得把现有的DOM都给清掉,只留一个模版的table,然后重新来。指定宽度高度的时候,能用pt的就用pt,实在用不了的再用px,哪怕用个mm,cm都比px强,因为打印机最后认的是长度,而不是像素点,建议页面上所有的字体大小都用pt来指定。

在谷歌浏览器中,使用默认页边距的情况下,A3、A4纸比较合适的尺寸:

A3:1000pt *930px

A4:700pt*580px

这个因为宽度是你用jquery去指定的,所以能用pt去指定,但是你在分页时算高度时,用Jquery获取出来只能获取到像素,所以,这就是为什么要用奇葩的pt*px这种组合的原因。这样子反正我的是大部分没有什么问题,如果不行稍微微调一点就可以了

这是我网上找的Jquery.printTable.js

 效果图N张:

转载于:https://www.cnblogs.com/baiyunchen/p/4794134.html

你可能感兴趣的文章
黑客与画家 part1 版权声明 part2 O'Reilly Media,Ina.介绍
查看>>
滤波器中的窗口
查看>>
简单三层实现登陆
查看>>
程序兵法:Java String 源码的排序算法(一)
查看>>
多久能学会编程
查看>>
如何不让php自动把&times换成×号
查看>>
HDU 1008 Elevator
查看>>
POJ 2135 Farm Tour (费用流)
查看>>
使用JavaScript实现一个俄罗斯方块
查看>>
Python爬虫框架Scrapy安装使用步骤
查看>>
Anaconda 下libsvm的安装
查看>>
列表生成式
查看>>
SSM整合项目中使用百度Ueditor遇到的问题。
查看>>
复制文件
查看>>
作业调度模拟程序
查看>>
C++ inline
查看>>
SpringMVC中JSP取不到ModelAndView的数据原因
查看>>
cenos 安装 phpredis 扩展
查看>>
Yii2 的 redis 应用
查看>>
sqlplus登陆
查看>>