拿到这个需求,我已经蛋碎了一地,经过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. mysql的一些sql用法

    mysql中修改列名: alter table 表名 change abc def 列类型;比如 alter table student change pws psw char(10);

  2. CentOS 7运维管理笔记(3)----Linux路由器配置

    当正在配置的Linux主机需要作为路由器使用时,通过以下步骤配置后,子网上的计算机就可以访问外网了: 1. 编辑 /etc/sysctl.conf 文件,添加 net.ipv4_ip_forward ...

  3. 基础JavaScript练习(一)

    任务目的 学习与实践JavaScript的基本语法.语言特性 初步了解JavaScript的事件是什么 初步了解JavaScript中的DOM是什么 任务描述 如图,模拟一个队列,队列的每个元素是一个 ...

  4. Java Collections Framework知识结构目录

    The core collection interfaces are the foundation of the Java Collections Framework. The Java Collec ...

  5. C#性能优化实践(转载)

    原文地址http://www.infoq.com/cn/articles/C-sharp-performance-optimization?utm_source=infoq&utm_mediu ...

  6. django模板报错:Requested setting TEMPLATE_DEBUG, but settings are not configured. You must either define

    转自:http://blog.csdn.net/xiaowanggedege/article/details/8651236 django模板报错: Requested setting TEMPLAT ...

  7. 【NLP_Stanford课堂】语言模型3

    一.产生句子 方法:Shannon Visualization Method 过程:根据概率,每次随机选择一个bigram,从而来产生一个句子 比如: 从句子开始标志的bigram开始,我们先有一个( ...

  8. glyphicons-halflings-regular.woff2 not found 前台错误修正

    错误内容如下: 首先在 web.config 里面加上如下内容: <system.webServer> <staticContent> <remove fileExten ...

  9. 错误: 安装必备组件失败: 安装必备组件失败: SqlInstanceRtc 有关详细信息

    错误: 安装必备组件失败: 安装必备组件失败: SqlInstanceRtc 有关详细信息 查看错误得知是安装sqlexpr_x64.exe的时候出现了错误 解决: 通过打开skype镜像,找到sql ...

  10. background-color和background-image相关细节

    1.background-color 是以border-box作为他的左上角来定位的 2.background-image 默认是以padding-box作为他的左上角来定位的 3.backgroun ...