拿到这个需求,我已经蛋碎了一地,经过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模板

    <!--打印设置页面开始-->
<div id="print-setting" style="display: none;">
<table cellpadding="0" cellspacing="0" style="margin:20px auto 0px auto;">
<tbody>
<tr>
<td align="right" valign="top">纸张大小:</td>
<td align="left" >
<input type="radio" name="paper_size" value="A3">
<label for="radiolist1-0">A3</label>
<input type="radio" name="paper_size" value="A4">
<label for="radiolist1-0">A4</label>
</td>
</tr>
</tbody>
</table>
</div>
<!--打印设置页面结束-->
<!-- 页面打印功能开始 -->
<div id="print-content" class="print-content" style="display: none; width: 1000pt;">
<!--A3:700pt A4:1000pt-->
<div class="header" id="header">
<div>
<h2>
样本出库交接单</h2>
<%--<div id="action-buttons" class="noPrint" >
<input onclick="grid_Print()" type="button" value="&nbsp;&nbsp;打印&nbsp;&nbsp;" class="btn" id="showPrintButton"/>
</div>--%>
</div>
<!-- 页面顶部信息 -->
<div class="headInfo" id="headerInfo">
<span class="floatRight">&nbsp;&nbsp;&nbsp;记录总数:50 </span>
</div>
</div>
<!-- 页面记录信息 -->
<table class="Printtable" id="tabContent" style="display: none;">
<thead>
</thead>
<tbody>
</tbody>
</table>
<!-- 页码信息 -->
<div class="signatureArea" id="footerInfo">
<span class="floatRight pageNum">1/1</span>
</div>
</div>
<!-- 页面打印功能结束 -->

打印模版

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

 /**
* jquery 表格打印插件
*
* 作者: LiuJunGuang
* 日期:2013年6月4日
* 分页样式(需要自定义):
* @media print {
* .pageBreak { page-break-after:always; }
* }
* 使用例子:
* $(function(){
* $("#tabContent").printTable({
* mode : "rowNumber",
* header : "#headerInfo",
* footer : "#footerInfo",
* pageNumStyle : "第#p页/共#P页",
* pageNumClass : ".pageNum",
* pageSize : 10
* });
* });
* 注意事项:
* 使用时注意表格中要使用 thead 和 tbody区分出标题头与表格内容,否则可能出现错误
*
* 参数说明:
* options are passed as json (json example: { rowHeight : "rowHeight", header : ".tableHeader",})
*
* {OPTIONS} | [type] | (default), values | Explanation
* ---------------- | --------- | -----------------------------| -----------
* @mode | [string] | ("rowHeight"),rowNumber | 分页模式,按行高分页或按行数分页
* @header | [string] | (".tableHeader") | 页面开始处要添加的内同
* @footer | [string] | (".tableFooter") | 页面结束要添加的内容
* @pageSize | [number] | (30) | 自动分页行数,按行高分页时改参数无效
* @breakClass | [string] | ("pageBreak") | 分页插入符class,需要定义分页样式
* @pageNumStyle | [string] | "#p/#P" | 页码显示样式,#p当前页,#P总页数
* @pageNumClass | [string] | ".pageNumClass" | 页码class样式,用于设值(使用text方法设置)
* @startPage | [number] | (1) | 第一页起始页码
* @pageHeight | [number] | (297) | 页面高度,单位像素
* @topMargin | [number] | (15) | 上边距高度,单位像素
* @bottomMargin | [number] | (15) | 低边距高度,单位像素
*/
(function($) {
var modes = { rowHeight : "rowHeight", rowNumber : "rowNumber" };
//默认参数
var defaults = {
mode : modes.rowHeight,
header : ".tableHeader",
footer : ".tableFooter",
pageSize : 30,
breakClass : "pageBreak",
pageNumStyle : "第#p页/共#Total#页",
pageNumClass : ".pageNumClass",
startPage : 1,
pageHeight : 720, //A4纸默认在win7下Web中的dpi是96,所以A4纸在win7下的大小换算成像素应该是794×1123,这里留空白
topMargin : 50,
bottomMargin : 50,
width : 1100, //留白100px
totalNumClass : "floatRight",
containsId :"#print-content"
};
var settings = {};//global settings
var rowCount = 0;//行总数
var pageCount = 0;//页总数
var currentPage = 0;//当前页
var $header = null;//表格头
var $content = null;//表格内容
var $footer = null;//表格尾
var $table = null;
var $tbodyTr = null;
var totalPageCount = 0;//总页数
$.fn.printTable = function( options ) {
$.extend( settings, defaults, options );
$table = $(this);
$tbodyTr = $table.find("tbody tr");
var $container = $(settings.containsId);
totalPageCount = 0;
//$(settings.totalNumClass).text($tbodyTr.length);
//$table.width("720pt");
switch ( settings.mode ){
case modes.rowHeight :
rowHeightPage();//行高分页
$container.html($container.html().replace(/#Total/g,totalPageCount)) ;
break;
case modes.rowNumber :
rowNumberPage();//行数分页
}
};
//获取页总数
$.fn.printTable.getStartPage = function(startPage) {
return getPageStyle(startPage , pageCount);
};
//行高分页
function rowHeightPage() {
var contentHeight = initHeightPage();
getContentColne();
beginPageByHeight(contentHeight);
hidenContent();
} //行数分页
function rowNumberPage(){
initNumberPage();
getContentColne();
beginPageByNumber();
hidenContent();
} //按行高分页
function beginPageByHeight(contentHeight){
var totalHeight = 0;
var startLine = 0;
$tbodyTr.each(function(i){
var cHeight = $(this).outerHeight(true);
$(this).height(cHeight);
if ((totalHeight + cHeight) < contentHeight) {
totalHeight += cHeight;
if(i == $tbodyTr.length -1){
newPage(i + 1);
}
}else{
newPage(i);
}
}); function newPage(index){
createPage(startLine,index);
currentPage++;
totalPageCount++;
startLine = index;
totalHeight = 0;
}
} //初始化高度分页信息
function initHeightPage(contentHeight){
var contentHeight = initContentHeight();
currentPage = 0 + settings.startPage;
pageCount = Math.ceil($table.find("tbody").outerHeight(true)/contentHeight) + settings.startPage - 1;//初始化总页数
rowCount = $tbodyTr.length; //初始化总记录数
return contentHeight;
} //初始化内容高度
function initContentHeight(){
var headerHeight = $(settings.header).outerHeight(true);
var footerHeight = $(settings.footer).outerHeight(true);
$table.find("thead td").each(function(i) {
var cWidth = $(this).outerWidth(true);
$(this).width((cWidth / 96 * 72) + "pt");
});//给表头一个宽度,但是貌似打印的时候不顶卵用
var theadHeight = $table.find("thead").outerHeight(true);
var tableHeight = settings.pageHeight - settings.topMargin - settings.bottomMargin ;
var tbodyHeight = tableHeight - theadHeight- headerHeight - footerHeight;
return tbodyHeight;
}
//初始化分页基本信息
function initNumberPage(){
rowCount = $tbodyTr.length;//初始化总记录数
pageCount = Math.ceil(rowCount/settings.pageSize) + settings.startPage - 1;//初始化总页数
currentPage = 0 + settings.startPage;
} //开始分页
function beginPageByNumber(){
var startLine = 1;//开始行号
var offsetLine = 0;//偏移行号
for(var i = settings.startPage; i <= pageCount ;i++ ){
currentPage = i;
startLine = settings.pageSize* (currentPage - settings.startPage);
offsetLine = (startLine + settings.pageSize) > rowCount ? rowCount : startLine + settings.pageSize;
createPage(startLine,offsetLine);
};
}
//创建新的一页
function createPage(startLine, offsetLine) {
var $pageHeader = $header.clone();
var $pageContent = $content.clone().append(getTrRecord(startLine, offsetLine));
var $pageFooter = $footer.clone();
$pageFooter.find(settings.pageNumClass).text(getPageStyle(currentPage , pageCount));//页码显示格式
if(offsetLine == rowCount){
$table.before($pageHeader).before($pageContent).before($pageFooter);
}else{
$table.before($pageHeader).before($pageContent).before($pageFooter).before(addPageBreak());
}
} //添加分页符
function addPageBreak(){
return "<div class='"+settings.breakClass+"'></div>";
} //获取分页样式
function getPageStyle(currentPage , pageCount){
var numStr = settings.pageNumStyle;
numStr = numStr.replace(/#p/g,currentPage);
//numStr = numStr.replace(/#P/g,pageCount);
return numStr;
} //获取记录
function getTrRecord(startLine,offsetLine){
return $tbodyTr.clone().slice(startLine,offsetLine);
}
//获取内容
function getContentColne(){
$header = $(settings.header).clone().removeAttr("id");
$content = $table.clone().find("tbody").remove().end().removeAttr("id");
$footer = $(settings.footer).clone().removeAttr("id");
}
//隐藏原来的数据
function hidenContent(){
$(settings.header).hide();
$table.hide();
$(settings.footer).hide();
}
})(jQuery);

Jquery.printTable.js

3.打印预览的实现js

  var win = null;
// var winPrintSetting = null;
//打印预览函数
function grid_PrintView() {
if (win) {
win.show();
return;
}
var grid = $(".listgrid:first").ligerGrid();
// var oldpageSize = grid.options.pageSize;
// grid.options.pageSize = grid.filteredData.Rows.length;
// grid.reload(); $(".Printtable:gt(0)").remove();
$(".header:gt(0)").remove();
$(".headInfo:gt(0)").remove();
$(".signatureArea:gt(0)").remove();
$(".header h2").text(TABData[0].标题);
$(".headInfo .floatRight").text("记录总数:" + grid.currentData.Rows.length);
$(".Printtable:last").find("thead").html("");
$(".Printtable:last").find("tbody").html("");//清空第一个表格的thead和tbody
$(".Printtable:last thead").append($(".l-grid2 .l-grid-header-inner tbody")[0].innerHTML);
$(".Printtable:last tbody").append($(".l-grid2 .l-grid-body-table tbody")[0].innerHTML);//重新把所有的数据给到这个表格
$(".Printtable:last *").removeAttr("class");
$(".Printtable:last *").removeAttr("style");//清理掉样式
$(".header").show();
$("#tabContent").show();
win = $.ligerDialog.open(
{ height: 794, target: $("#print-content"), width: 1090, showMax: true, showToggle: true, showMin: true, isResize: true, modal: false, title: '打印预览 <input onclick="grid_Print()" type="button" value="&nbsp;&nbsp;打印&nbsp;&nbsp;" class="btn" id="showPrintButton">&nbsp;&nbsp; <input onclick="PrintSetting()" type="button" value="打印设置" class="btn" id="printSetting"/> ', slide: true });
win.max();
ChangePages();
}
//把一个连起来的表格拆分
function ChangePages() {
var height = 930;
var paper_size = $.cookie('paper_size');
if (paper_size == 'A4') {
height = 580;
$(".print-content").width("700pt");
} else {
height = 930;
$(".print-content").width("1000pt");
}
$(".Printtable:last").printTable({
mode: "rowHeight",
header: "#header",
//footer: "#footerInfo",signatureArea
footer: "#footerInfo",
pageNumStyle: "第#p页/共#Total页",
pageNumClass: ".pageNum",
pageHeight: height, //A4:580 ,A3 930
startPage: 1,
totalNumClass: ".floatRight",
containsClass: "#print-content"
});
}
//改变打印纸大小时
function ChangePaper() {
var grid = $(".listgrid:first").ligerGrid();
$(".Printtable:gt(0)").remove();
$(".header:gt(0)").remove();
$(".signatureArea:not(:last)").remove();//清理当前已经分页分好的表格,把除了第一个表格外的所有表格都干掉
$(".header h2").text(TABData[0].标题);
$(".headInfo .floatRight").text("记录总数:" + grid.currentData.Rows.length);
$(".pageBreak").remove();
$(".Printtable:first").find("thead").html("");
$(".Printtable:first").find("tbody").html("");//清空第一个表格的thead和tbody
$(".Printtable:first thead").append($(".l-grid2 .l-grid-header-inner tbody")[0].innerHTML);
$(".Printtable:first tbody").append($(".l-grid2 .l-grid-body-table tbody")[0].innerHTML);//重新把所有的数据给到这个表格
$(".Printtable:first *").removeAttr("class");
$(".Printtable:first *").removeAttr("style");//清理掉样式
$(".header").show();
$(".signatureArea").show();
ChangePages();
} var winPrintSetting = null;
//纸张大小设置
function PrintSetting() {
var paper_size = $.cookie('paper_size');
if (paper_size) {
$("input[name='paper_size'][value='" + paper_size + "']").attr("checked", true);
} else {
$.cookie('paper_size', 'A3', { expires: 30 });
$("input[name='paper_size'][value='A3']").attr("checked", true);
}
win.min(); if (winPrintSetting) {
winPrintSetting.show();
} else {
winPrintSetting = $.ligerDialog.open({
target: $("#print-setting"),
height: 200,
width: 300,
modal: true,
title: "打印设置",
allowClose: false,
isHidden:true,
buttons: [{ text: '确定', onclick: function (item, dialog) {
var paperSize = $("[name=paper_size]:checked").val();
$.cookie('paper_size', paperSize, { expires: 30 });
win.max();
win.active();
ChangePaper();
dialog.hide();
}
}, { text: '取消', onclick: function (item, dialog) {
win.max();
win.active();
dialog.hide();
}
}]
});
} }

打印预览的展示,调整纸张大小

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

http://files.cnblogs.com/files/baiyunchen/jquery-printTable1.0.zip

效果图N张:

Web打印连续的表格,自动根据行高分页的更多相关文章

  1. spreadJs 自动换行功能和自动增高行高

    var styleTmp = sheet.getStyle(displayRowIndex, displayColumnIndex, GcSpread.Sheets.SheetArea.viewpor ...

  2. ui-grid样式,表格高度自适应行高,没有滚动条,去掉表头

    前后端设置:

  3. jquery 表格自动拆分(方便打印)插件-printTable

    /** * jquery 表格打印插件 * * 作者: LiuJunGuang * 日期:2013年6月4日 * 分页样式(需要自定义): * @media print { * .pageBreak ...

  4. 20191012——POI设置单元格自动行高(思路)

    在经过Jxls或者POI导出数据至excel中后,发现有的单元格内容太多,既没有自动换行,也没有自动增大行高.那如何通过Java代码来实现呢?请看下面步骤: (一)首先,将excel设置为最合适的行高 ...

  5. iOS UITableView 解决估算行高和指定行高的矛盾

    喜欢交朋友的加:微信号 dwjluck2013 1.一般来说 在iOS 中若UITableViewCell 固定行高, 会通过 - (CGFloat)tableView:(UITableView *) ...

  6. Web打印控件Lodop实现表格物流单的打印

    Web打印控件Lodop实现表格物流单的打印 一.lodop打印预览效果图 LODOP.PRINT_SETUP();打印维护效果图 LODOP.PREVIEW();打印预览图 二.写在前面 最近项目用 ...

  7. WEB打印的几种方案

    -------------------------------------------一  基于Web的打印方案比较分析-------------------------------- 基于web的套 ...

  8. 网页WEB打印控件制作-开放源码

    在WEB系统中,打印的确是比较烦人的问题,如果我们能制作一个属于自己的自定义的打印插件,那么我们在后续自定义打印的时候能随心所欲的控制打印,这样的效果对于程序员来说是非常开心的一件事件,本文将自己开发 ...

  9. Web打印--Lodop API

    Lodop是一款专业的WEB打印控件,其设计目标是简单易用.功能足够强大,开创WEB打印开发的新局面. Lodop设计者对WEB下的打印开发任务进行了分类汇总,高度抽象,设计出仅用几个功能函数,就可实 ...

随机推荐

  1. 移动端布局注意事项与less

    用Koala实现less的实时编译 1.下载Koala(Koala可以实现实时编译) 2.把CSS文件夹(如index.css,index.less)拖到Koala中 3.点击到需要编译的index. ...

  2. ubuntu终端颜色设置

    在 .bashrc中增加 PS1='${debian_chroot:+($debian_chroot)}\[\033[00;32m\]\u @ \h\[\033[00m\]:\[\033[00;34m ...

  3. puppeteer自动化测试

    1.基础知识 puppeteer.launch() 创建浏览器实例 puppeteer.newPage() 创建一个新页面 puppeteer.goto() 进入指定网站 page.screensho ...

  4. 如何创建一个基本JQuery的插件

    如何创建一个基本的插件 有时您希望在整个代码中提供一些功能.例如,也许你想要一个单一的方法,你可以调用一个jQuery选择,对选择执行一系列的操作.在这种情况下,您可能需要编写一个插件. 链接jQue ...

  5. HADOOP背景介绍

    1. HADOOP背景介绍 1.1 什么是HADOOP 1. HADOOP是apache旗下的一套开源软件平台 2. HADOOP提供的功能:利用服务器集群,根据用户的自定义业务逻辑,对海量数据进行分 ...

  6. eclipse 内存溢出

    2011年02月22日 星期二 11:14 eclipse.exe -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M ec ...

  7. numpy用法介绍-未完待续

    简介 NumPy(Numerical Python简称) 是高性能科学计算和数据分析的基础包 为什么使用? 标准安装的Python中用列表(list)保存一组值,可以用来当作数组使用,不过由于列表的元 ...

  8. How to use DBVisualizer to connect to Hbase using Apache Phoenix

    How to use DBVisualizer to connect to Hbase using Apache Phoenix Article DB Visualizer is a popular ...

  9. Hush Framework框架配置(续) 转自《Android和PHP最佳实践》官方站

    图书资源下载 Xampp 开发环境下载:http://pan.baidu.com/share/link?shareid=531771&uk=773037279 微博实例完整源码包下载:http ...

  10. 阿里云安装jdk报错gzip: stdin: unexpected end of file

    在阿里云上面安装jdk时候报了这个问题,如下图所示 然后看了下jdk应该是有150多M的,但是阿里云上面的只有1M多,删除 重新下载... tar zxvf jdk 好了