WEB上进行报表控制和打印,曾经使用过如下的报表工具:
-国内最强大的润乾报表
-国际最强大的也是最流行的水晶报表
-JAVA开源的JasperReport和设计器iReport的组合
实际使用过程中,难以避免的问题是代价高昂的学习曲线。如果用户并发量并不是很大,完全可以使用WEB自定义HTML的方式进行控制和打印。一方面,能够提供最大的灵活性进行报表的控制;另一方面,鉴于HTML/CSS本身就是开发所必须的技能之一,所以无需学习曲线即可进行开发。但在控制力上还是显得有些不足,尤其是在打印的控制上,因为IE上提供的功能本身就是一个非常简化的版本。如果用户并发量不是很大,且没有太高的要求的话,用这种方法还是显得非常的简便、实用的。
思路如下:
1.建立模板文件,变量部分用特殊字符替代,如@@var@@的形式
2.I/O方式读取相应路径下的模板文件,用系统的变量值,替代特殊字符,同时计算好分页及其他一些需要提前控制的变量。
3.输出到页面上后,利用控制变量和WebBroswer控件(Windows系统默认提供)进行打印控制。打印按钮放置在一个DIV层中,打印时隐藏此部分。
下面以JAVA开发为例
1.模板文件样例,文件名为[模板名].tpl:
<table width='98%' border='0' cellpadding='0' cellspacing='0' class='h1'>
<tr>
<td width='4' height='4'><img src="../images/table_01.gif" mce_src="images/table_01.gif" width='4' height='4' /></td>
<td height='4' background='../images/table_02.gif'><img src="../images/blank.gif" mce_src="images/blank.gif" width='1' height='1' /></td>
<td width='4' height='4'><img src="../images/table_04.gif" mce_src="images/table_04.gif" width='4' height='4' /></td>
</tr>
<tr>
<td background='../images/table_05.gif'><img src="../images/blank.gif" mce_src="images/blank.gif" width='1' height='1' /></td>
<td align='center'><table width='95%' border='0' cellspacing='0' cellpadding='3'>
<tr>
<td align='left'><img src="../images/logo_new_24.png" mce_src="images/logo_new_24.png" width='24' height='24' align='absmiddle' />培训预告</td>
</tr>
<tr>
<td height='3' align='left' background='../images/point.png'> <img src="../images/blank.png" mce_src="images/blank.png" width='1' height='1' /></td>
</tr>
<tr>
<td align='left'>
<table width='100%' border='0' cellpadding='0' cellspacing='0'>
<tr><td >培训开始时间:@@starttime@@</td>
<td >培训结束时间:@@endtime@@</td>
<tr><td colspan='2' align='center'>
<p>@@content@@</p></td></tr>
</table>
</td>
</tr>
<tr>
<td background='../images/point.png' height='3'><img src="../images/blank.png" mce_src="images/blank.png" width='1' height='1' /></td>
</tr>
<tr>
<td align='center'><a href="#" mce_href="#"><img src="../images/logo_edit_profile_24.png" mce_src="images/logo_edit_profile_24.png" width='24' height='24' border='0' align='absmiddle' />我要报名</a></td>
</tr>
</table></td>
<td background='../images/table_07.gif'><img src="/images/blank.gif" mce_src="images/blank.gif" width='1' height='1' /></td>
</tr>
<tr>
<td width='4' height='4'><img src="../images/table_10.gif" mce_src="images/table_10.gif" width='4' height='4' /></td>
<td height='4' background='../images/table_11.gif'><img src="/images/blank.gif" mce_src="images/blank.gif" width='1' height='1' /></td>
<td width='4' height='4'><img src="../images/table_13.gif" mce_src="images/table_13.gif" width='4' height='4' /></td>
</tr>
</table>
2.读取模板文件的方法
private String getOneTrainPreBlock() throws IOException {
TrainPreDao tpdao=(TrainPreDao)DaoConfig.getDaoManager().getDao(TrainPreDao.class);
Date now =new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String curtime=sdf.format(now);
HashMap map= new HashMap();
map.put("curtime", curtime);
map.put("cid", catalog);
TrainPre tp=(TrainPre)tpdao.selectTrainPreByDate(map);
String tplcontent;
if(tp!=null){
//获得模板的绝对路径
String path = (String) ((HttpServletRequest) this.pageContext.getRequest()).getSession().getServletContext().getRealPath("/");
String fileUrl = path + "tpl/"+tpl;
File file=new File(fileUrl);
//按编码格式读取
InputStreamReader read=new InputStreamReader(new FileInputStream(file),"GBK");
BufferedReader reader=new BufferedReader(read);
StringBuilder sb=new StringBuilder();
String line;
while((line=reader.readLine())!=null){
sb.append(line);
}
tplcontent=sb.toString();
//替换变量部分
tplcontent=tplcontent.replace("@@content@@", tp.getContent());
tplcontent=tplcontent.replace("@@starttime@@", sdf.format(tp.getStarttime()));
tplcontent=tplcontent.replace("@@endtime@@", sdf.format(tp.getEndtime()));
}else{
tplcontent="";
}
return tplcontent;
}
3.JSP页面控制打印,分页、边距、内容、循环等。后台的JAVA程序略去。此处的输出变量以JSTL的形式给出
<%@ page language="java" pageEncoding="GBK"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html"
prefix="html"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="ctx" value="${pageContext.request.contextPath}" />
<html>
<head>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
<title>文件夹传阅单</title>
<LINK href="${ctx}/HTML/css/style.css" mce_href="${ctx}/HTML/css/style.css" type=text/css rel=stylesheet>
</head>
<mce:style type="text/css"><!--
.break {page-break-after: always}
.headword { font-size:32px;font-weight:bold;letter-spacing:8px ;color:red } //定义红头文字
.tdhead {font-family:楷体_GB2312;font-size: 22px;text-align:center;} //定义表格中抬头文字
.row { font-family: 楷体_GB2312;font-size:24px } //定义每行的字体
.cellbot{ border-bottom: 1px solid #000000; } //定义每个单元格画底线
.cellbnr{ border-bottom: 1px solid #000000;border-right: 1px solid #000000;} //定义每个单元格画底线及右侧线
--></mce:style><style type="text/css" mce_bogus="1"> .break {page-break-after: always}
.headword { font-size:32px;font-weight:bold;letter-spacing:8px ;color:red } //定义红头文字
.tdhead {font-family:楷体_GB2312;font-size: 22px;text-align:center;} //定义表格中抬头文字
.row { font-family: 楷体_GB2312;font-size:24px } //定义每行的字体
.cellbot{ border-bottom: 1px solid #000000; } //定义每个单元格画底线
.cellbnr{ border-bottom: 1px solid #000000;border-right: 1px solid #000000;} //定义每个单元格画底线及右侧线</style>
<mce:script language="JavaScript"><!--
var HKEY_Root,HKEY_Path,HKEY_Key;
HKEY_Root="HKEY_CURRENT_USER";
HKEY_Path="//Software//Microsoft//Internet Explorer//PageSetup//";
//设置网页打印的页眉页脚为空
function PageSetup_Null()
{
try
{
var Wsh=new ActiveXObject("WScript.Shell");
HKEY_Key="header";
Wsh.RegWrite(HKEY_Root+HKEY_Path+HKEY_Key,"");
HKEY_Key="footer";
Wsh.RegWrite(HKEY_Root+HKEY_Path+HKEY_Key,"");
// 上边页边距
hkey_key="margin_top";
Wsh.RegWrite(HKEY_Root+HKEY_Path+hkey_key,"0.36929");
// 底边页边距
hkey_key="margin_bottom";
Wsh.RegWrite(HKEY_Root+HKEY_Path+hkey_key,"0.38425");
// 左边页边距
hkey_key="margin_left";
Wsh.RegWrite(HKEY_Root+HKEY_Path+hkey_key,"0.24016");
//右边页边距
hkey_key="margin_right";
Wsh.RegWrite(HKEY_Root+HKEY_Path+hkey_key,"0.24016");
}
catch(e){}
}
//设置网页打印的页眉页脚为默认值
function PageSetup_Default()
{
try
{
var Wsh=new ActiveXObject("WScript.Shell");
HKEY_Key="header";
Wsh.RegWrite(HKEY_Root+HKEY_Path+HKEY_Key,"&w&b页码,&p/&P");
HKEY_Key="footer";
Wsh.RegWrite(HKEY_Root+HKEY_Path+HKEY_Key,"&u&b&d");
}
catch(e){}
}
// --></mce:script>
<mce:script type="text/javascript"><!--
function HiddenEle(f){
PageSetup_Null();
document.getElementById(f).style.display = "none";
}
function ShowEle(f){
document.getElementById(f).style.display = "block";
}
function PrintPreview(){
HiddenEle('panelPrint');
document.getElementById('WebBrowser').ExecWB(7,1);
ShowEle('panelPrint');
}
function Print(){
HiddenEle('panelPrint');
document.getElementById('WebBrowser').ExecWB(6,1);
ShowEle('panelPrint');
}
function PrintL(){
HiddenEle('panelPrint');
document.getElementById('WebBrowser').ExecWB(6,6);
ShowEle('panelPrint');
}
function WebFormScroll() {
document.all("panelPrint").style.top = document.body.scrollTop;
}
function TaodaPrint(){
document.forms[0].action="${ctx}/SendFileTaodaReportHtml.do";
document.forms[0].submit();
}
function TaodaBarcodePrint(){
document.forms[0].action="${ctx}/SendFileTaodaBarcodeReportHtml.do";
document.forms[0].submit();
}
function printa4b5(paper){
location.href="${ctx}/HTML/folder/EditAction.do?method=toReadList&paper="+paper+"&folderId=${param.folderId}";
}
// --></mce:script>
<body topMargin="20">
<OBJECT id="WebBrowser" style="WIDTH:0px; HEIGHT:0px"
classid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2">
</OBJECT>
<div id="panelPrint"
style="OVERFLOW: auto; WIDTH: 100%; POSITION: absolute; TOP: 0px;"
align="center">
<table class="Wdate" border="0" width="100%" cellspacing="0"
cellpadding="0" align="center" height="24"
style="font-size:12px;background:#f1f1f1;border: 1px solid #dadada;">
<tr>
<td align="center" width=100%>
<input class="button" type="button" value="关 闭"
onClick="document.getElementById('WebBrowser').ExecWB(45,1);">
<input class="button" type="button" value="打 印"
onClick="javascript:Print();location.reload();">
<input class="button" type="button" value="${paper} 纸"
onClick="javascript:printa4b5('${paper}');">
<input class="button" type="button" value="设 置"
onClick="document.getElementById('WebBrowser').ExecWB(8,1)">
<input class="button" type="button" value="预 览"
onClick="PrintPreview();location.reload();">
</td>
</tr>
</table>
</div>
<div><table><tr height="40"><td></td></tr></table></div>
<c:if test="${pcount > 1}">
<div class="break">
</c:if>
<table width="${pagewidth}" align="center">
<tr>
<td>
<div align="center"
style="font-family:黑体;font-size: 24px;letter-spacing: 3mm">
${foldertype}传阅单
</div>
</td>
</tr>
<tr>
</tr>
<tr>
<td style="font-family:楷体_GB2312;font-size: 23px" mce_style="font-family:楷体_GB2312;font-size: 23px">
<div align="center">
(${vicehead})
</div>
</td>
</tr>
</table>
<table width="${pagewidth}" border="0" align="center" cellpadding="0" cellspacing="0" style="">
<c:forEach items="${leadername}" begin="0" end="11" step="1" var="leader" varStatus="status">
<c:if test="${status.count<=limitsize}">
<c:if test="${(status.count-1)%4==0}">
<tr height="40">
<td style="border-bottom: 1px solid #000;border-left: 1px solid #000;
<c:if test=" mce_style="border-bottom: 1px solid #000;border-left: 1px solid #000;
<c:if test="${status.count==1}">
border-top: 1px solid #000;
</c:if>
">
</td>
</c:if>
<td height="25" align="center" style="font-family:楷体_GB2312;font-size: 22px;border-bottom: 1px solid #000;border-left: 1px solid #000;
<c:if test=" mce_style="font-family:楷体_GB2312;font-size: 22px;border-bottom: 1px solid #000;border-left: 1px solid #000;
<c:if test="${status.count<5}">
border-top: 1px solid #000;
</c:if>
<c:if test="${(status.count-1)%4==3}">
border-right: 1px solid #000;
</c:if>
" colspan="2">
${leader}
</td>
<c:if test="${(status.count-1)%4==3}">
</tr>
<tr height="40">
<td height="109" style="font-family:楷体_GB2312;font-size: 22px;text-align:center;border-bottom: 1px solid #000;border-left: 1px solid #000;" mce_style="font-family:楷体_GB2312;font-size: 22px;text-align:center;border-bottom: 1px solid #000;border-left: 1px solid #000;">
<p>
日
</p>
<p>
期
</p>
</td>
<td width="100" align="center" style="font-family:楷体_GB2312;font-size: 18px;text-align:center;border-bottom: 1px solid #000;border-left: 1px solid #000;">
<!-- <sup>${sday}</sup><font style="font-size:36px" mce_style="font-size:36px">/</font><sub>${smonth}-${syear}</sub>-->
</td>
<td width="100" align="center" style="border-bottom: 1px solid #000;border-left: 1px solid #000;" mce_style="border-bottom: 1px solid #000;border-left: 1px solid #000;" >
</td>
<td width="100" align="center" style="border-bottom: 1px solid #000;border-left: 1px solid #000;" mce_style="border-bottom: 1px solid #000;border-left: 1px solid #000;" >
</td>
<td width="100" align="center" style="border-bottom: 1px solid #000;border-left: 1px solid #000;" mce_style="border-bottom: 1px solid #000;border-left: 1px solid #000;" >
</td>
<td width="100" align="center" style="border-bottom: 1px solid #000;border-left: 1px solid #000;" mce_style="border-bottom: 1px solid #000;border-left: 1px solid #000;" >
</td>
<td width="100" align="center" style="border-bottom: 1px solid #000;border-left: 1px solid #000;" mce_style="border-bottom: 1px solid #000;border-left: 1px solid #000;" >
</td>
<td width="100" align="center" style="border-bottom: 1px solid #000;border-left: 1px solid #000;" mce_style="border-bottom: 1px solid #000;border-left: 1px solid #000;" >
</td>
<td width="100" align="center" style="border-bottom: 1px solid #000;border-left: 1px solid #000;border-right: 1px solid #000;" mce_style="border-bottom: 1px solid #000;border-left: 1px solid #000;border-right: 1px solid #000;" >
</td>
</tr>
</c:if>
</c:if>
</c:forEach>
<tr height="40">
<td width=80 style="font-family:楷体_GB2312;font-size: 22px;text-align:center;border-bottom: 1px solid #000;border-left: 1px solid #000;" mce_style="font-family:楷体_GB2312;font-size: 22px;text-align:center;border-bottom: 1px solid #000;border-left: 1px solid #000;">
<p>
领
</p>
<p>
导
</p>
<p>
批
</p>
<p>
示
</p>
</td>
<td height="237" colspan="9" style="border-bottom: 1px solid #000;border-left: 1px solid #000;border-right: 1px solid #000;" mce_style="border-bottom: 1px solid #000;border-left: 1px solid #000;border-right: 1px solid #000;" >
</td>
</tr>
<tr >
<td width="80" height="${page1height}" style="font-family:楷体_GB2312;font-size: 22px;text-align:center;border-bottom: 1px solid #000;border-left: 1px solid #000;" mce_style="font-family:楷体_GB2312;font-size: 22px;text-align:center;border-bottom: 1px solid #000;border-left: 1px solid #000;">
<p>
文
</p>
<p>
件
</p>
<p>
目
</p>
<p>
录
</p>
</td>
<td colspan="9" align="left" valign="top" style="border-bottom: 1px solid #000;border-left: 1px solid #000;border-right: 1px solid #000;" mce_style="border-bottom: 1px solid #000;border-left: 1px solid #000;border-right: 1px solid #000;">
<table align="left" width="100%" >
<c:forEach items="${filesList}" var="flist" step="1" varStatus="status">
<c:if test="${status.count <= page1}">
<tr valign="top">
<td style="font-family:仿宋_GB2312,楷体_GB2312;font-size: 22px;" mce_style="font-family:仿宋_GB2312,楷体_GB2312;font-size: 22px;">
${status.count}. ${flist.fileTitle}
</td>
</tr>
</c:if>
</c:forEach>
</table>
</td>
</tr>
</table>
<table align="center"><tr><td align="center">
<c:if test="${pcount>1}">
第 1 页 共 ${pcount} 页
</c:if>
</td></tr></table>
<table border="0" width="${pagewidth}" cellspacing="4" cellpadding="0" align="center" height="55">
<tr><td height="30"></td></tr>
<tr>
<td width="500"></td>
<td valign="middle">
<img src="${ImagePath}" mce_src="${ImagePath}" width="220px" height="50px" id="barcode" />
</td>
</tr>
</table>
<c:if test="${pcount > 1}">
</div>
</c:if>
<c:forEach var="x" begin="1" end="${pcount-1}" step="1">
<c:if test="${x != (pcount-1)}">
<div class="break">
</c:if>
<table width="${pagewidth}" border="1" align="center" height="940"
cellpadding="0" cellspacing="0" style="border-collapse:collapse;" mce_style="border-collapse:collapse;">
<tr>
<td width="80" style="font-family:楷体_GB2312;font-size: 22px;text-align:center" mce_style="font-family:楷体_GB2312;font-size: 22px;text-align:center">
<p>
文
</p>
<p>
件
</p>
<p>
目
</p>
<p>
录
</p></td>
<td valign="top">
<table align="left" width="100%" >
<c:forEach items="${filesList}" var="flist" step="1" varStatus="status">
<c:if test="${(status.count > perpagecount*(x-1)+page1)and(status.count <= perpagecount*x+page1)}">
<tr>
<td style="font-family:仿宋_GB2312,楷体_GB2312;font-size: 22px;" mce_style="font-family:仿宋_GB2312,楷体_GB2312;font-size: 22px;">
${status.count}. ${flist.fileTitle}
</td>
</tr>
</c:if>
</c:forEach>
</table>
</td>
</tr></table>
<table align="center"><tr><td align="center">第 ${x+1} 页 共 ${pcount} 页</td></tr></table>
<c:if test="${x != (pcount-1)}">
</div>
</c:if>
</c:forEach>
</body>
</html>