Web打印方案

对于B/S架构的项目中,Web打印最是让程序员头痛的技术,以下几种方式针对不同的目的实现打印

 

一、利用IE 自带的WebBrowser 控件实现打印

<OBJECT id=WebBrowser classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 width=0 VIEWASTEXT>
</OBJECT>
<input type=button value=打印   οnclick="document.all.WebBrowser.ExecWB(6,1)" class="NOPRINT">
<input type=button value=直接打印 οnclick="document.all.WebBrowser.ExecWB(6,6)" class="NOPRINT">
<input type=button value=页面设置 οnclick="document.all.WebBrowser.ExecWB(8,1)" class="NOPRINT">
<input type=button value=打印预览 οnclick="document.all.WebBrowser.ExecWB(7,1)" class="NOPRINT">

 

注意:
1、CSS对打印的控制:
<!--media=print 这个属性可以在打印时有效-->
<style media=print>
.Noprint{display:none;}
.PageNext{page-break-after: always;}
</style>

Noprint样式可以使页面上的打印按钮等不出现在打印页面上
PageNext样式可以设置分页,在需要分页的地方<div class="PageNext"></div>

 

2、表格线粗细的设置,可通过样式表:

<style>
.tdp
{
  border-bottom: 1 solid #000000;
  border-left: 1 solid #000000;
  border-right: 0 solid #ffffff;
  border-top: 0 solid #ffffff;
}
.tabp
{
  border-color: #000000;

    border-collapse:collapse;
}
</style>

 

或者:

<style>
.TdCs1 {
    border:solid windowtext 1.0pt;
}
.TdCs2 {
    border:solid windowtext 1.0pt; border-left:none;
}
.TdCs3 {
    border-top:none;
    border-left:solid windowtext 1.0pt;
    border-bottom:solid windowtext 1.0pt;
      border-right:solid windowtext 1.0pt;
}
.TdCs4 {
    border-top:none;
    border-left:none;
    border-bottom:solid windowtext 1.0pt;
      border-right:solid windowtext 1.0pt;
}
.underline {
    border-top-style: none;
    border-right-style: none;
    border-bottom-style: solid;
    border-left-style: none;
    border-bottom-color: #000000;
}
</style>

 

3、其它的用法

WebBrowser.ExecWB(1,1) 打开
Web.ExecWB(2,1) 关闭现在所有的IE窗口,并打开一个新窗口
Web.ExecWB(4,1) 保存网页
Web.ExecWB(6,1) 打印
Web.ExecWB(7,1) 打印预览
Web.ExecWB(8,1) 打印页面设置
Web.ExecWB(10,1) 查看页面属性
Web.ExecWB(15,1) =========待确认
Web.ExecWB(17,1) 全选
Web.ExecWB(22,1) 刷新
Web.ExecWB(45,1) 关闭窗体无提示

 

 

二、利用IE菜单打印

 

三、将报表导出成Word,Excel或PDF形式打印

 

导出EXCEL有很多的方法不细细描述,该方案的优点是灵活性大些,客户可以在EXCLE中再进行2次数据整理。可以使用第三方的EXCLE组件例如(北京科翰的免费组件等)。下面介绍服务器中EXCLE导出

要在服务器端使用Excel,必须要求服务器端安装Excel,并且要求一定的访问权限。比如,需要添加<identity impersonate="true"/>到web.config中。在本文中,要给予WEB目录可写的权限。

  接下来,使用VS.NET 2003新建一个VB.NET的工程,并添加引用。由于我们要使用的是Excel,所以添加一个关于COM的应用,这里添加的是Microsoft Excel Object Library,之后,添加的代码如下:

Imports System.Runtime.InteropServices.Marshal
Imports Office
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 '以COM方式处理Excel
 Dim oExcel As New Excel.Application
 Dim oBooks As Excel.Workbooks, oBook As Excel.Workbook
 Dim oSheets As Excel.Sheets, oSheet As Excel.Worksheet
 Dim oCells As Excel.Range
 Dim sFile As String, sTemplate As String
 '定义一个datatable
 Dim dt As DataTable = CType(Application.Item("MyDataTable"), DataTable)

 sFile = Server.MapPath(Request.ApplicationPath) & "/MyExcel.xls"
 '定义模版文件
 sTemplate = Server.MapPath(Request.ApplicationPath) & "/MyTemplate.xls"
 oExcel.Visible = False
 oExcel.DisplayAlerts = False
 '定义一个新的工作簿
 oBooks = oExcel.Workbooks
 oBooks.Open(Server.MapPath(Request.ApplicationPath) & "/MyTemplate.xls") oBook = oBooks.Item(1)
 oSheets = oBook.Worksheets
 oSheet = CType(oSheets.Item(1), Excel.Worksheet)

 '命名该sheet
 oSheet.Name = "First Sheet"
 oCells = oSheet.Cells
 '调用dumpdata过程,将数据导入到Excel中去
 DumpData(dt, oCells)
 '保存
 oSheet.SaveAs(sFile)
 oBook.Close()

 '退出Excel,并且释放调用的COM资源
 oExcel.Quit()
 ReleaseComObject(oCells) : ReleaseComObject(oSheet)
 ReleaseComObject(oSheets) : ReleaseComObject(oBook)
 ReleaseComObject(oBooks) : ReleaseComObject(oExcel)
 oExcel = Nothing : oBooks = Nothing : oBook = Nothing
 oSheets = Nothing : oSheet = Nothing : oCells = Nothing
 System.GC.Collect()
 Response.Redirect(sFile)
End Sub

'将DATATABLE的内容导出到Excel的单元格中去
Private Function DumpData(ByVal dt As DataTable, ByVal oCells As Excel.Range) As String
 Dim dr As DataRow, ary() As Object
 Dim iRow As Integer, iCol As Integer

 '输出列标题
 For iCol = 0 To dt.Columns.Count - 1
  oCells(2, iCol + 1) = dt.Columns(iCol).ToString
 Next

 '将数据导出到相应的单元格
 For iRow = 0 To dt.Rows.Count - 1
  dr = dt.Rows.Item(iRow)
  ary = dr.ItemArray
  For iCol = 0 To UBound(ary)
   oCells(iRow + 3, iCol + 1) = ary(iCol).ToString
   Response.Write(ary(iCol).ToString & vbTab)
  Next
 Next
End Function
End Class

  在上面的代码中,首先,先定义了一些关于Excel的对象,如application,workbook,sheets,sheet等,这些都是在使用Excel的COM对象时,必不可少的。之后,我们事先先定义了一个Excel的模版文件,并且用Excel先打开这个模版文件,再调用一个自定义的过程dumpdata。在这个自定义的过程中,将datatable中的数据,逐一导入到Excel的单元格中去。读者自己可以慢慢体会下,上面的代码中,是如何将datatable中的数据导出到Excel中去的。程序运行后,可以在当前的工作目录下,生成名为myExcel.xls的Excel文件

 

 如果只是单单对数据进行导出,还可以使用简单的格式,比如使用以下的代码:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 Dim dt As DataTable = CType(Application.Item("MyDataTable"), DataTable)

 Response.ContentType = "application/ms-Excel"

 Response.AddHeader("Content-Disposition", "inline;filename=test.xls")

 Response.Write(ConvertDtToTDF(dt))
End Sub

Private Function ConvertDtToTDF(ByVal dt As DataTable) As String
 Dim dr As DataRow, ary() As Object, i As Integer
 Dim iCol As Integer

 ' 输出列标题
 For iCol = 0 To dt.Columns.Count - 1
  Response.Write(dt.Columns(iCol).ToString & vbTab)
 Next
 Response.Write(vbCrLf)

 '输出数据
 For Each dr In dt.Rows
  ary = dr.ItemArray
  For i = 0 To UBound(ary)
   Response.Write(ary(i).ToString & vbTab)
  Next
  Response.Write(vbCrLf)
 Next
End Function
End Class

  在上面的代码中,首先将浏览器的输出类型设置为application/ms-Excel,并设置Excel的输出类型是在浏览器中输出,默认的名字为test.xls,之后,将调用自定义的过程,该自定义的过程将一个datatable里的数据以字符串流的形式输出,其中每个datatable里的数据之间以TAB制表符分隔,最后再输出到浏览器

 

 

四、第3方控件 

 

ScriptX控件实现打印

最大弊端就是打印的格式是死的,你要打印出怎样的格式必须自己来做,还有就是打印分页,它是按你设置的纸张大小来分的,所以必须人为控制,ScriptX控件所需文件ScriptX.cab。(ScriptX下载地址http://www.meadroid.com/scriptx/freedep.asp )

 

以下为ASP控制实例

包括三个文件,一个是框架页,一个是工具栏页,还一个就是打印的内容页了。

 

1、框架页:

<html>
<head>
<title>打印 / 预览 / 库存汇总表</title>
<link type="text/css" rel="stylesheet" href="style.css">
<script language="javascript" src="main.js"></script>
<script language="javascript">maxwin();</script>
</head>
<frameset rows="42,*" style="border:none">
<frame src="toolbar.asp" name="toolbar" target="mainbar" frameborder="0" scrolling="no" noresize>
<frame src="kc.asp" name="mainbar" target="mainbar" frameborder="0" scrolling="auto" noresize>
</frameset>
</html>

2、工具栏页:([预览],[设置]和[打印]等按钮,代码里边的图片大家自己去做一个好了)

<body bgcolor="#D4D0C8" topmargin="0" leftmargin="0" rightmargin="0" bottommargin="0" onselectstart="return false" οncοntextmenu="return false">
    <table width="100%" height="41" cellpadding="0" cellspacing="0" border="0" background="../images/bg_toolbar.gif">
     <tr>
      <td width="10"><img src="../images/bar_toolbar.gif"></td>
      <td width="85" align="center"><img src="../images/ico_print.gif" οnmοuseοver="this.src= ../images/ico_print1.gif " οnmοusedοwn="this.src= ../images/ico_print2.gif " οnmοuseοut="this.src= ../images/ico_print.gif " οnclick="top.mainbar.factory.printing.Print(false);"></td>
      <td width="2"><img src="../images/line_toolbar.gif"></td>
      <td width="85" align="center"><img src="../images/ico_setup.gif" οnmοuseοver="this.src= ../images/ico_setup1.gif " οnmοusedοwn="this.src= ../images/ico_setup2.gif " οnmοuseοut="this.src= ../images/ico_setup.gif " οnclick="top.mainbar.factory.printing.PageSetup();"></td>
      <td width="2"><img src="../images/line_toolbar.gif"></td>
      <td width="85" align="center"><img src="../images/ico_view.gif" οnmοuseοver="this.src= ../images/ico_view1.gif " οnmοusedοwn="this.src= ../images/ico_view2.gif " οnmοuseοut="this.src= ../images/ico_view.gif " οnclick="top.mainbar.factory.printing.Preview();"></td>
      <td width="2"><img src="../images/line_toolbar.gif"></td>
      <td>&nbsp;</td>
     </tr>
    </table>
</body>

3、内容页:(代码里边的数据查询请大家换成自己的数据查询)

<style>
td{font-size:14px;line-height:180%}
.ybk{border-right:1px #000000 solid;}
.sbk{border-top:1px #000000 solid;}
</style>
<!--这里调用控件ScriptX.cab-->
<object id="factory" style="display:none" viewastext classid="clsid:1663ed61-23eb-11d2-b92f-008048fdd814" codebase="ScriptX.cab#Version=5,60,0,360"></object>
<script defer>
function window.onload() {
  factory.printing.header = ""         //页眉
  factory.printing.footer = ""        //页脚
  factory.printing.portrait = false    //true为纵向打印,flase为横向打印
  factory.printing.leftMargin = 15.0   //左页边距
  factory.printing.topMargin = 5.0     //上页边距
  factory.printing.rightMargin = 0.75  //右页边距
  factory.printing.bottomMargin = 1.5  //下页边距
  }
</script>
<body οncοntextmenu="return false">

        <!--#include file="conn.asp"--

>
        <%
           sql="exec showkc_print"
           Set rs=Server.CreateObject("Adodb.Recordset")
           rs.open sql,conn,3,2
           If Not rs.eof then
              rs.pagesize=21 每页记录条数即每页打印的条数
              xs=rs.pagesize
              rc=rs.pagecount %>

 

<!--自动分页开始-->

<% for n = 1 to rc
   xs_s=(xs*n-xs)+1 每页起始序数
   xs_e=xs*n 每页结束序数 %>
<p>&nbsp;
<table width="1000" height="700" cellpadding="0" cellspacing="0" border="0">
<tr><td valign="top">
<table width="100%" cellpadding="0" cellspacing="0" border="0">
  <tr><td height="50" align="center" valign="top"><font size="5">库存汇总表</font></td></tr>
</table>

<table width="1000" cellpadding="0" cellspacing="0" style="border:1px #000000 solid" align="center">
 <tr height="20" align="center">
  <td width="5%" class="ybk">序号</td>
  <td width="10%" class="ybk">人工编号</td>
  <td width="15%" class="ybk">材料名称</td>
  <td width="25%" class="ybk">型号规格</td>
  <td width="10%" class="ybk">单价</td>
  <td width="8%" class="ybk">数量</td>
  <td width="12%" class="ybk">金额</td>
  <td width="5%" class="ybk">单位</td>
  <td width="10%">更新日期</td>
 </tr>
<%
   dim i
   i=1
   Do While Not rs.eof and i<=xs %>
 <tr><td colspan="10" height="1"><img src="../images/dot.gif" width="100%" height="1"></td></tr>
 <tr height="20">
  <td width="5%" class="ybk">&nbsp;&nbsp;<%=xs_s+(i-1)%></td>
  <td width="10%" class="ybk">&nbsp;&nbsp;<%=rs("rgbh")%></td>
  <td width="15%" class="ybk">&nbsp;<%=rs("clmc")%></td>
  <td width="25%" class="ybk">&nbsp;<%=rs("clxh")%></td>
  <td width="10%" class="ybk" align="right"><%=FormatNumber(rs("pjj"),3,true)%>&nbsp;</td>
  <td width="8%" class="ybk" align="right"><%=FormatNumber(rs("kcsl"),2,true)%>&nbsp;</td>
  <td width="12%" class="ybk" align="right"><%xj=FormatNumber(rs("pjj"),3)*FormatNumber(rs("kcsl"),2)%><%=FormatNumber(xj,2,true)%>&nbsp;</td>
  <td width="5%" class="ybk">&nbsp;<%=rs("dw")%></td>
  <td width="10%">&nbsp;<%=datevalue(rs("gxsj"))%></td>
 </tr>

<%
   rs.MoveNext
   i=i+1
   hj=hj+xj
   zj=zj+xj
   Loop %>

 <% If rc>1 then %>
 <tr><td colspan="10" height="1"><img src="../images/dot.gif" width="100%" height="1"></td></tr>
 <tr height="20">
  <td width="5%" class="ybk">&nbsp;</td>
  <td width="10%" class="ybk">&nbsp;</td>
  <td width="15%" class="ybk">&nbsp;</td>
  <td width="25%" class="ybk">&nbsp;本 页 合 计</td>
  <td width="8%" class="ybk">&nbsp;</td>
  <td width="8%" class="ybk">&nbsp;</td>
  <td width="12%" class="ybk" align="righ

t"><%=FormatNumber(hj,2,true)%><% hj=0%>&nbsp;</td>
  <td width="5%" class="ybk">&nbsp;</td>
  <td width="10%">&nbsp;</td>
 </tr>
 <% end if %>

 

 <% If n=rc then %>
 <tr><td colspan="10" height="1"><img src="../images/dot.gif" width="100%" height="1"></td></tr>
 <tr height="20">
  <td width="5%" class="ybk">&nbsp;</td>
  <td width="10%" class="ybk">&nbsp;</td>
  <td width="15%" class="ybk">&nbsp;</td>
  <td width="25%" class="ybk">&nbsp;总 计</td>
  <td width="8%" class="ybk">&nbsp;</td>
  <td width="8%" class="ybk">&nbsp;</td>
  <td width="12%" class="ybk" align="right"><%=FormatNumber(zj,2,true)%>&nbsp;</td>
  <td width="5%" class="ybk">&nbsp;</td>
  <td width="10%">&nbsp;<%=now%></td>
 </tr>
 <% end if %>

</table>

<table width="100%" cellpadding="0" cellspacing="0" border="0">
  <tr><td height="15">&nbsp;</td></tr>
  <tr><td height="30" align="center"><font size="3">第<%=n%>页,共<%=rc%>页</font></td></tr>
</table>
</td></tr>
</table>
<% next %>

<!--分页结束-->

<%        
           end if
           rs.close
           Set rs=Nothing
           conn.close
           Set conn=Nothing %>

 

 

 

 

 

 

五、使用自编写xml实现

网上很容易搜索到 卢彦的利用XML实现通用WEB报表打印》思路新颖,实现简单,确实不失为一种通用解决办法,尤其利用XML来描述打印文件的方法给以后的格式的拓展留下很好的接口,非常容易扩充。这种打印方式对于格式变化大,数据量小的应用来说非常合适。这种思路也给了ASP.NET上打印的一种新的思路:自定义一些组件来实现灵活的打印功能。当然缺点也是显而易见:1、需要客户端安装NET framework1.0组件。2、XML的解析上,如果文件较大速度上不是很理想。3、页面首次加载时会有明显的延时。

 

 

 

六、采用Crystal Report  如果我们只需要进行一些小规模的报表打印的话,Crystal Report则显得庞大麻烦了一点,可定制性也不太好,也需要注册

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值