好学IT学院:IT信息技术分享交流平台
标签:.NET  来源:www.hxw.red  作者:本站整理  发布时间:2011-10-26  ★★★加入收藏〗〖手机版
通过ASP.NET实现Web打印的三种方法
摘要:从事过WEB/BS开发的朋友应该都深有体会,在web程序中打印不再象应用程序中那样便于控制了,web程序天生的一些特性造成了这个缺点,如:打印机在本地,而文件确可能在服务器上;格式如何控制和定制等等。都给我们开发中带来了很多问题,虽说有水晶报表等控件来解决但总…

内容提示:从事过WEB/BS开发的朋友应该都深有体会,在web程序中打印不再象应用程序中那样便于控制了,web程序天生的一些特性造成了这个缺点,如:打印机在本地,而文件确可能在服务器上;格式如何控制和定制等等。都给我们开发中带来了很多问题,虽说有水晶报表等控件来解决但总归是不方便。当然有了问题就会有人来研究解决,本文将对目前流行的几种方式做个简单介绍,仅供参考:

1、利用IE直接打印

这个不用多说,直接调用window.print或者webrower控件的ExecWB方法来打印。方便快捷,客户端无需任何设置即可。利用一些办法也可以实现简单的定制,比如做一个模板htm文件,然后在js中动态创建一个隐藏帧来,用脚本来生成其中的数据,再把最后的结果文件写入到隐藏帧打印处理。如果处理的好,实际上效果也是不错。对于简单的打印需求应该是够了。这里我举个实际中的例子来说明这种方式:

开发中经常需要打印一些统计的结果给用户,比如说一个常见的功能是营业报表类的打印:操作员先输入查询条件,然后提交得到查询的结果,点击打印后,按照定义好的格式打印报表。

我们实现上大部分情况会把查询的结果绑定到DataGrid上来,然后打印DataGrid。这种情况的打印一般来说格式比较固定简单,确定后基本不会再作更改。所以可以采用IE直接打印,但若直接调用window.print来打印结果页面,页面上别的无关元素也会被打印出来,页头页尾的格式也不好控制,所以采用把需要打印的数据动态写入到隐藏帧中打印的方式来实现

代码示例:ASP.NET中打印指定的DataGrid内容

其中借用来自微软的一段js代码,整个js代码如下:

//以下脚本实现:打印指定的datagrid

var vGridContent;  //DataGrid的内容
var vHeaderInfo;  //打印的表头
var vTailerInfo;  //打印的表尾

/*
目的:在页面写入隐藏帧并打印
参数:vDataGrid  所要打印的DataGrid句柄
备注:
 代码中调用如下
 btPrint.Attributes.Add("onclick","return PrintDataGrid(document.all('DataGridSheetID'))");
 DataGridSheetID为待打印的DataGrid的ID
*/

function PrintDataGrid(vDataGrid)
{
  PickupHeaderInfo();
  
  document.body.insertAdjacentHTML("beforeEnd",
 "<iframe name=printHiddenFrame width=0 height=0></iframe>");
  var doc = printHiddenFrame.document;
  doc.open();
  doc.write("<body onload=\"setTimeout('parent.onprintHiddenFrame()', 0)\">");
  doc.write("<iframe name=printMe width=0 height=0 ></iframe>");
  doc.write("</body>");
  doc.close();
 
  CreateHtmlReport(printHiddenFrame.printMe,vDataGrid);
  return false;
}

/*
目的:在隐藏帧中写入DataGrid的内容,并重写DataGrid的格式
参数:
vHideFrame 隐藏帧的句柄
vDataGrid  所要打印的DataGrid句柄
备注:
*/

function CreateHtmlReport(vHideFrame,vDataGrid)
{
 vGridContent = vDataGrid.outerHTML;
 // 输出报表头信息及抽取过来的表格
  var doc = vHideFrame.document;
 doc.open();
 doc.write("<html><body>");
 doc.write(vHeaderInfo);
 doc.write(vGridContent);
 doc.write("</body></html>");
 doc.close();
 //重新设置表格样式
 vDataGrid.borderColor = "#000000";
 vDataGrid.width = "100%";
 vDataGrid.style.fontFamily = "Verdana";
 vDataGrid.style.fontSize = "12px";
 vDataGrid.style.borderRight = "2px solid #000000";
 vDataGrid.style.borderTop = "2px solid #000000";
 vDataGrid.style.borderLeft = "2px solid #000000";
 vDataGrid.style.borderBottom = "2px solid #000000";
 vDataGrid.style.borderCollapse = "collapse";
 //重新设置表格头样式
 var TBody = vDataGrid.children(0);
 TBody.children(0).style.fontWeight = "bold";
 TBody.children(0).bgColor = "#E7E7E7";
 //替换原表格底部的页码信息
 var pageInfo = "<td>第 " + ((4 - 3) / 1 + 1) + " 页 / 共 " + "1" + " 页&nbsp;&nbsp;&nbsp;&nbsp;</td>";
}

//创建表头 表尾
function PickupHeaderInfo()
{
 try
 {
  // 提取报表标题字体大小
  var ReportTitleWithSizeInfo = "<font size='" + "+2" + "'>" + "无费用用户统计" + "</font>"
  var reportDate = "";
  var reportWriter = "";
  var nowdate=new Date();
  reportDate = "<b>统计时间</b>:" +nowdate.toLocaleString() + "<br>";
  reportDate +="<b>营业厅</b>:测试而已<br>";
  //生成报表头信息
  vHeaderInfo = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=gb2312\">";
  vHeaderInfo += "<title>无费用用户统计</title></head>" +
   "<body bgcolor='#FFFFFF' style='color: #000000; font-family: Verdana; font-size:12px; cursor: default'>";
  vHeaderInfo += "<br><p align='center'><b>" + ReportTitleWithSizeInfo + "</b></p>";
  vHeaderInfo += "<p>" + reportDate;
  vHeaderInfo += reportWriter + "</p>";
 }
 catch (e)
 {
  alert("提取报表公共信息失败,打印操作被取消!");
  self.close();
 }
}

//下面的脚本来自msdn
// The code by Captain <cerebrum@iname.com>
// Mead & Company, http://www.meadroid.com/wpm/
// fake print() for IE4.x

if (!printIsNativeSupport())
  window.print = printFrame;

// main stuff
function printFrame(frame, onfinish) {
  if ( !frame ) frame = window;

if ( frame.document.readyState !== "complete" &&
  !confirm("The document to print is not downloaded yet! Continue with printing?") )
  {
  if ( onfinish ) onfinish();
  return;
  }

if ( printIsNativeSupport() ) {
  /* focus handling for this scope is IE5Beta workaround,
  should be gone with IE5 RTM.
  */
  var focused = document.activeElement;
  frame.focus();
  frame.self.print();
  if ( onfinish ) onfinish();
  if ( focused && !focused.disabled ) focused.focus();
  return;
  }

var eventScope = printGetEventScope(frame);
  var focused = document.activeElement;

window.printHelper = function() {
  execScript("on error resume next: printWB.ExecWB 6, 1", "VBScript");
  printFireEvent(frame, eventScope, "onafterprint");
  printWB.outerHTML = "";
  if ( onfinish ) onfinish();
  if ( focused && !focused.disabled ) focused.focus();
  window.printHelper = null;
  }

document.body.insertAdjacentHTML("beforeEnd",
  "<object id=\"printWB\" width=0 height=0 \
  classid=\"clsid:8856F961-340A-11D0-A96B-00C04FD705A2\"></object>");

printFireEvent(frame, eventScope, "onbeforeprint");
  frame.focus();
  window.printHelper = printHelper;
  setTimeout("window.printHelper()", 0);
}

// helpers
function printIsNativeSupport() {
  var agent = window.navigator.userAgent;
  var i = agent.indexOf("MSIE ")+5;
  return parseInt(agent.substr(i)) >= 5 && agent.indexOf("5.0b1") < 0;
}

function printFireEvent(frame, obj, name) {
  var handler = obj[name];
  switch ( typeof(handler) ) {
  case "string": frame.execScript(handler); break;
  case "function": handler();
  }
}

function printGetEventScope(frame) {
  var frameset = frame.document.all.tags("FRAMESET");
  if ( frameset.length ) return frameset[0];
  return frame.document.body;
}

function onprintHiddenFrame() {
  function onfinish() {
  printHiddenFrame.outerHTML = "";
  if ( window.onprintcomplete ) window.onprintcomplete();
  }
  printFrame(printHiddenFrame.printMe, onfinish);
}

程序中在Page_Load里面加上:btPrint.Attributes.Add("onclick","return PrintDataGrid(document.all('DataGridSheetID'))");

注:DataGridSheetID为需要打印的DataGrid ID,在查询后,btPrint为页面上打印按钮的ID

可以将上述脚本代码写在一个js文件中,然后再aspx文件中引用,如<script srcenter.js"></script>  ,上述代码的原理比较简单,我不在多说。上述代码可以实现直接打印页面上指定控件的内容,当然最多还是打印table的内容,如果需要先预览后打印。需要作一个空的html文件,然后动态写入需要打印的内容:

var preDlg = window.open("PrintList.htm");
  CreateHtmlReport(preDlg, true);

使用Visual Studio 2010空白解决方案的三个理由
  在Visual Studio 2010(包括以前的版本中)都提供了很多现成的解决方案,来帮助程序开发人员降低开发的工作量。如多项目…
  • 好学考试H5触屏版开放内测
  • 好学触屏公众号虎力全开、杨帆起航!