web打印技术

来源:互联网 发布:淘宝二维码扫码付款 编辑:程序博客网 时间:2024/05/16 14:59
Web页面打印技术
2008-01-26 11:26

一.概述
对基于B/S架构的应用程序而言,客户端的页面打印一直是比较头疼的问题,简单的做法是:1.使用IE的打印功能;2.使用水晶报表。但以上两种办法,都有很大的局限性,很难实现特殊要求的排版和精确的定位,所以不能满足一些特殊客户的BT要求。为此,本人总结了自己在使用Web打印上的一点经验,和大家分享。
本文涉及以下技术:javascript、ActiveX、ASP.NET、GDI+。


二.基本架构
首先,我们不能使用IE的打印功能,必须自己设计‘打印’按钮。很多人习惯将‘打印’按钮放在要打印的页面上,打印时为了不把这个按钮打印出来,采用办法如下:1.打印前隐藏按钮;2.打印;3.显示按钮。
我觉得这样比较麻烦,所以我采用框架。一共有三个页面:
1.main.htm :框架页面,上面是打印按钮,下面是要显示的页面。
2.header.htm :标题栏,至少包含一个打印按钮。
3.report.aspx :要打印的页面,由用户生成。


//main.htm
<html>
<head>
   <title></title>  
</head>
   <frameset rows="10%,90%" frameborder="0" border="0" frameSpacing="0">
   <frame id="header" name="header" src="Header.htm" noresize scrolling="no">
   <frame id="report" name="report" src="Report.aspx" noresize scrolling="auto">
</frameset>
</html>


//header.htm
<html>
<head>  
   <script id=clientEventHandlersJS language=javascript>
   <!--
   function btnPrint_onclick()
   {
    parent.report.focus();
    parent.report.print();
   }
   //-->
   </script>
</head>
<body>
   <INPUT id="btnPrint" type="button" value="Print" name="Print" onclick="return btnPrint_onclick()">  
</body>
</html>


这样,在点击‘打印’按钮时,将直接打印report.aspx页面的内容,既简单又直观。


三.打印
要完全控制打印,就必须由程序设定页眉、页脚、页边距。每个客户端的IE设置都不尽相同,你可以要求你的客户修改他们的打印设置为你指定的值,显然这不现实。所以正确的做法是:
1.备份客户打印页面设置;
2.设置页眉页脚上下左右边距为自己需要的值;
3.打印;
4.恢复原来的打印页面设置。


这里用到一个叫ScriptX的控件。你需要下载一个文件:smsx.cab,下载地址:http://www.meadroid.com/scriptx/sxdownload.asp。这个地址并不能保证长期有效,你可以在搜索引擎上搜索‘ScriptX’以获得更多相关信息。


在“header.htm”中增加该控件的引用:
<OBJECT id="factory" style="DISPLAY: none" codeBase="http://localhost/WebApplication1/smsx.cab#VVersion=6,3,434,12"
classid="clsid:1663ed61-23eb-11d2-b92f-008048fdd814" viewastext>
</OBJECT>
注意CodeBase指向你的实际存放文件的位置,在客户端第一次浏览该页面时,将下载并安装该控件,请确定客户端的安全设置允许安装控件。
那么此时 header.htm 的内容如下。


//header.htm
<html>
<head>
<script id="clientEventHandlersJS" language="javascript">
<!--
function btnPrint_onclick()
{
//备份客户打印机设置
   var h = factory.printing.header;
   var f = factory.printing.footer;
   var t = factory.printing.topMargin;
   var b = factory.printing.bottomMargin;
   var l = factory.printing.leftMargin;
   var r = factory.printing.rightMargin;

   //设置页眉页脚上下左右边距
   factory.printing.header = "";
factory.printing.footer = "";
factory.printing.topMargin="0";
   factory.printing.bottomMargin="0";
   factory.printing.leftMargin="0";
   factory.printing.rightMargin="0";

   //打印
   parent.report.focus();
   parent.report.print()

   //恢复原来的打印设置
   factory.printing.header = h;
   factory.printing.footer = f;
factory.printing.topMargin=t;
   factory.printing.bottomMargin=b;
   factory.printing.leftMargin=l;
   factory.printing.rightMargin=r;
}
//-->
</script>

<OBJECT id="factory" style="DISPLAY: none" codeBase="http://localhost/WebApplication1/smsx.cab#VVersion=6,3,434,12"
   classid="clsid:1663ed61-23eb-11d2-b92f-008048fdd814" viewastext>
</OBJECT>
</head>
<body bgColor="#9999cc">
<INPUT id="btnPrint" type="button" value="Print" name="Print" onclick="return btnPrint_onclick()">   
</body>
</html>


此时,不管客户端IE设置如何,都能正确打印页面,打印内容将完全取决于页面:report.aspx。


四.动态页面生成
1. 如果你的页面是静态页面,或者页面元素为固定数量,那就非常简单了。只要调整好各个元素位置就行了,绝对所见即所得。要注意的是一个A4纸的大小为21cm×29.7cm,对应象素大约为 794×1123 (系统分辨率96DPI) 。


2.如果你要生成一些图表,可以使用GDI+,你自己绘制的图片绝对能满足客户需求。下面给一个例子,我在页面放一个Label,一个Image。Image动态生成,调整其位置使其打印时出现在第二页的左上角。


1public class Report : System.Web.UI.Page
2 {
3  protected System.Web.UI.WebControls.Image Image1;
4  protected System.Web.UI.WebControls.Label Label1;
5
6   Web 窗体设计器生成的代码Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
7  override protected void OnInit(EventArgs e)
8  {   
9    InitializeComponent();
10   base.OnInit(e);
11   }

12  private void InitializeComponent()
13  {    
14   this.Load += new System.EventHandler(this.Page_Load);
15   }

16  #endregion

17
18  private void Page_Load(object sender, System.EventArgs e)
19  {   
20   if(!Page.IsPostBack)
21   {
22     InitImage();
23    }

24   }

25
26  private void InitImage()
27  {
28    Bitmap bmp = new Bitmap(800,1120);
29    Graphics g =   Graphics.FromImage(bmp);
30
31    g.FillRectangle(Brushes.Gray,0,0,800,1120);
32
33    g.FillRectangle(Brushes.RoyalBlue,0,0,100,600);
34    g.FillRectangle(Brushes.Aqua,600,0,100,600);
35    g.FillRectangle(Brushes.Coral,700,0,100,600);
36
37    g.FillRectangle(Brushes.YellowGreen,0,800,800,100);
38    g.FillRectangle(Brushes.Beige,0,900,800,100);
39    g.FillRectangle(Brushes.SkyBlue,0,1000,800,100);
40    g.FillRectangle(Brushes.Tomato,0,1100,800,20);
41
42   string filename = Server.MapPath("TempImages//img1.jpg");   
43
44    bmp.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg);
45
46   this.Label1.Text = filename;
47   this.Image1.ImageUrl = filename;
48   this.Image1.Attributes["style"]="POSITION: absolute; LEFT: 0cm;   TOP: 29.7cm"; //定位
49   }
  
50 }

51
52