要把一个长表格打印出来,要做到正确分页,直接用HTML生成表格是不能满足要求的:
1、如果把整个表格放在一页,在打印时再自动分页,则有可能在某一表格行中间分页,而且只能有一个表格头,不能每页一个,因为你不知道会在哪里分页;
2、如果按照固定的行数分页,由于每行的高度不一样,就会造成有的页不能填满,有的却太满自动分页了。
原来考虑过一种方法:
利用Javascript动态生成表格,每次往表格的最后插入一行,然后检查表格高度,如果高度超过了一页的最大高度,则把这一行删除,新建一个表格,把这一行插入到新的表格里面,如此循环,直到全部行插入完毕。但是,利用table的height属性、style.height属性都得不到表格的实际高度(只有设置了height属性、style的height属性才能取得这两个值,但只是设置值,并不是实际值),于是就只能放弃了。
后来仔细查看了table的dom属性,才知道它还有clientHeight,offsetHeight等属性,这两个才是表格的真正高度,它们之间的区别可看这里:
http://developer.mozilla.org/cn/docs/DOM:element.clientHeight
http://developer.mozilla.org/en/docs/DOM:element.offsetHeight
更直观的可以看这里:
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/om/measuring.asp
简单地说,clientHeight就是不包含border的高度,offsetHeight就是连border的高度。对于要打印的表格,border一般只有2px,所以用clientHeight和offsetHeight区别不大。
构建这个页面需要用到的:
table的
insertRow(),
deleteRow()方法,用来给表格增加、删除一行(tr);
tr的
insertCell()方法,用来给一行加入一格(td);
td的innerText属性,用来给一格加入内容。
CSS分页要用到page-break-before:always(或page-break-after:aways)的样式,遇到使用了该样式的标签,就会在标签前面(或后面)强制分页,于是可以在两个表格之间加一个这样的分页。
为了显示而不打印,还要用到<style>标签的media属性,当设置
<style media="print">
.noprint {display:none}
</style>
时,用了noprint作为class的标签就只会显示而不打印出来。
对于IE,还可以使用WebBrowser控件,弹出“页面设置”窗口、“打印预览”窗口、直接打印等功能。对于其他浏览器,则只能调用window.print()函数了。
JSF生成的中文都是用unicode;来表示的,其中unicode是中文字符的UNICODE编码,通过innerText生成表格内容时,必须把这些东西转换成真正的中文,否则会直接把这些符号插入到表格中,惨不忍睹。javascript里有个String.fromCharCode()函数可以把Unicode编码转换成字符。另外,通过innerHTML加入内容也可把这些编码正常显示出来,但需要escape XML,以免把内容当作HTML标签渲染。
评论
2、如果按照固定的行数分页,由于每行的高度不一样,就会造成有的页不能填满,有的却太满自动分页了。
ie在打印的时候不但可以在每页自动添加,还可以自动添加表脚,当然还可以自动判断长度分页,实现这些都不需要半点脚本。请看这个例子(使用了内置打印控件来预览,如果被浏览器禁止了需要手工使用打印预览功能或者打印出来)
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
function pageSetup(){try{WB.ExecWB(8,1)}catch(e){alert("您的浏览器不支持此功能")}}
function preview(){try{WB.ExecWB(7,1)}catch(e){alert("您的浏览器不支持此功能")}}
</SCRIPT>
<style>
td,th{border-bottom:1px solid black;width:70px}
thead{display:table-header-group}
tfoot{display:table-footer-group}
</style>
</HEAD>
<BODY>
<OBJECT classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 id=WB width=0 VIEWASTEXT></OBJECT>
<TABLE cellspacing=0 align=center>
<thead><th> 姓 名 </th><th> 地 址 </th><th> 籍 贯 </th><th>毕业学校</th><th> 年 龄 </th><th> 性 别 </th><th> 婚 否 </th></thead>
<tbody align=center>
<SCRIPT LANGUAGE="JavaScript">
<!--
var n=100;
for(var i=0;i<n;i++){
document.write("<tr>");
for(var j=0;j<7;j++)
document.write("<td>"+Math.round(Math.random()*10000)+
(Math.random()>.05?"":"<br>"+Math.round(Math.random()*10000))+
(Math.random()>.02?"":"<br>"+Math.round(Math.random()*10000))+
(Math.random()>.01?"":"<br>"+Math.round(Math.random()*10000))+
"</td>");
document.write("</tr>");
}
//-->
</SCRIPT>
</tbody>
<tfoot><th colspan=7 align=center style="width:100%">这 是 一 个 测 试</th></tfoot>
</TABLE>
</BODY>
<SCRIPT LANGUAGE="JavaScript">
preview();
</SCRIPT>
</HTML>
例子中特意使用脚本构造了随机高度的行。 回复
不过不用脚本生成表格的话还是有可能会把行拦腰截断,上面那个不截断,是因为行高比较小,我稍稍改了一下每行的内容,就出现了:
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
function pageSetup(){try{WB.ExecWB(8,1)}catch(e){alert("您的浏览器不支持此功能")}}
function preview(){try{WB.ExecWB(7,1)}catch(e){alert("您的浏览器不支持此功能")}}
</SCRIPT>
<style>
td, th{border-bottom:1px solid black;width:70px}
thead{display:table-header-group}
tfoot{display:table-footer-group}
</style>
</HEAD>
<BODY>
<OBJECT classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 id=WB width=0 VIEWASTEXT></OBJECT>
<TABLE cellspacing=0 align=center border=1>
<thead><th> 姓 名 </th><th> 地 址 </th><th> 籍 贯 </th><th>毕业学校</th><th> 年 龄 </th><th> 性 别 </th><th> 婚 否
</th></thead>
<tbody align=center>
<SCRIPT LANGUAGE="JavaScript">
<!--
var n=100;
for(var i=0;i<n;i++){
document.write("<tr>");
for(var j=0;j<7;j++)
document.write("<td>有可能在某一表格行中间分页在某一表格行中间分页</td>");
document.write("</tr>");
}
//-->
</SCRIPT>
</tbody>
<tfoot><th colspan=7 align=center style="width:100%">这 是 一 个 测 试</th></tfoot>
</TABLE>
</BODY>
<SCRIPT LANGUAGE="JavaScript">
preview();
</SCRIPT>
</HTML> 回复
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
function pageSetup(){try{WB.ExecWB(8,1)}catch(e){alert("您的浏览器不支持此功能")}}
function preview(){try{WB.ExecWB(7,1)}catch(e){alert("您的浏览器不支持此功能")}}
</SCRIPT>
<style>
td, th{border-bottom:1px solid black;width:70px}
thead{display:table-header-group}
tfoot{display:table-footer-group}
</style>
</HEAD>
<BODY>
<OBJECT classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 id=WB width=0 VIEWASTEXT></OBJECT>
<TABLE cellspacing=0 align=center border=1>
<thead><th> 姓 名 </th><th> 地 址 </th><th> 籍 贯 </th><th>毕业学校</th><th> 年 龄 </th><th> 性 别 </th><th> 婚 否 </th></thead>
<tbody align=center>
<SCRIPT LANGUAGE="JavaScript">
document.write("<tr>");
for(var j=0;j<7;j++)
document.write("<td>"+(new Array(10).join("有可能在某一表格行中间分页在某一表格行中间分页"))+"</td>");
document.write("</tr>");
</SCRIPT>
</tbody>
<tfoot><th colspan=7 align=center style="width:100%">这 是 一 个 测 试</th></tfoot>
</TABLE>
</BODY>
<SCRIPT LANGUAGE="JavaScript">
preview();
</SCRIPT>
</HTML> 回复
脚本可以生成任意HTML,当判断表格高度满一页的时候,就利用 page-break-before:always 样式生成一个分页符,再新建一个表格,这个表格就在下一页了,可以通过脚本往里面加入新的内容,表格的表头和表脚都可以用脚本生成。另外,用innerHTML就可以在某标签范围内加入任意HTML语句,所以还可以生成其他的内容。