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>