您的位置:首页 > 其它

[续]基于XML的WEB系统报表精确打印实现

2008-01-13 21:32 435 查看
[续]基于XML的WEB系统报表精确打印实现

前一段时间写了篇《Web嵌入.net打印控件》http://www.blog.163.com/yixiao.he/blog/static/3889872005105846190/

但因这半年在做一WIN项目,所以一直未完善,近来又做一WEB项目,所以将该打印控件进行了完善。

一、WEB表单页面中XML传递

由于并非所有用户都需要进行预览和打印,所以打印控件最好不放在表单页面,在需要打印时,在表单页面生成需要打印的XML文档,通过session传给 reports/printbill.aspx文件,该文件再根据打印模式 printmode 属性的设置进行相应的操作。也就是说,整个项目打印全部都用printbill.aspx文件进行打印

二、控件与页面之间的XML传递

有几种方法,有些可行,有些有问题,有些不可行!

(一) 页面生成一个xml文件,随机或按用户名命名,形一个文件放在WEB服务器上,然后将文件名传给打印控件,打印控件根据传过来的参数取到要打印的XML文件路径,如http://localhost/tdxd/reports/temp/1.xml

但这种办法存在一个问题是形成的xml文件会越来越多,没有合适的方法去删除这些文件,而且读写文件,效率可能会低一些。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Try
doc.Load(strXml) 'strXML为从页面传来的参数
Me.Label1.Text = "OK"
Catch ex As Exception
Me.Label1.Text = "Error"
End Try
End Sub

(二) 通过WebServices来传递数据。

这样做法的好处是将所以打印的程序,如打开XML模板,并根据要打印的数据形成最终打印XML,都放在一个WEBServices的函数里来处理,这样系统会更清晰。

但WEB引用在需要改变时,需要把XML引用的URL行为改为动态

系统会自动加一个 app.config文件

<appSettings><add key="WinCtlLib.wsPrint.WSPrint" value="http://localhost/tdxd/WebServices/WSPrint.asmx"/></appSettings>

在使用单独的WEB项目或WIN项目时,这种方案都是比较好的,但现在是将WIN控件嵌入到WEB页面中,没有app.config文件,所以更改WebServices路径后会出错

Try

Dim ws As New wsPrint.WSPrint
doc.LoadXml(ws.PrintXmlDoc(sXmlName, sTableName, sRecNo))
Me.Label1.Text = "OK"
Catch ex As Exception
Me.Label1.Text = "Error" & ex.Message
End Try
(三)

即本文开始说的方法,通过SESSION将待打印的XML文件传给printBill.aspx 该文件再将该XML传给控件

<OBJECT style="WIDTH: 480px; HEIGHT: 160px" classid="http:WinCtlLib.dll#WinCtlLib.ctlXmlPrint"
VIEWASTEXT>
<PARAM VALUE="<%=sXml%>">
</OBJECT>

控件代码

Imports System.Xml
Imports WinCtlLib.Hot.Print.RemotePrint
Imports System.Drawing.Printing
Public Class ctlXmlPrint
Inherits System.Windows.Forms.UserControl

#Region " Windows 窗体设计器生成的代码 "

Public Sub New()
MyBase.New()

'该调用是 Windows 窗体设计器所必需的。
InitializeComponent()

'在 InitializeComponent() 调用之后添加任何初始化
AddHandler PrintDocument1.PrintPage, AddressOf pd_PrintPage

End Sub

'UserControl1 重写 dispose 以清理组件列表。
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Windows 窗体设计器所必需的
Private components As System.ComponentModel.IContainer

'注意: 以下过程是 Windows 窗体设计器所必需的
'可以使用 Windows 窗体设计器修改此过程。
'不要使用代码编辑器修改它。
Friend WithEvents PageSetupDialog1 As System.Windows.Forms.PageSetupDialog
Friend WithEvents PrintDocument1 As System.Drawing.Printing.PrintDocument
Friend WithEvents PrintPreviewDialog1 As System.Windows.Forms.PrintPreviewDialog
Friend WithEvents btnShowXml As System.Windows.Forms.Button
Friend WithEvents lblMsg As System.Windows.Forms.Label
Friend WithEvents btnPreview As System.Windows.Forms.Button
Friend WithEvents btnPrint As System.Windows.Forms.Button
Friend WithEvents btnPageSetting As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(ctlXmlPrint))
Me.PageSetupDialog1 = New System.Windows.Forms.PageSetupDialog
Me.PrintDocument1 = New System.Drawing.Printing.PrintDocument
Me.PrintPreviewDialog1 = New System.Windows.Forms.PrintPreviewDialog
Me.lblMsg = New System.Windows.Forms.Label
Me.btnShowXml = New System.Windows.Forms.Button
Me.btnPreview = New System.Windows.Forms.Button
Me.btnPrint = New System.Windows.Forms.Button
Me.btnPageSetting = New System.Windows.Forms.Button
Me.SuspendLayout()
'
'PageSetupDialog1
'
Me.PageSetupDialog1.Document = Me.PrintDocument1
'
'PrintPreviewDialog1
'
Me.PrintPreviewDialog1.AutoScrollMargin = New System.Drawing.Size(0, 0)
Me.PrintPreviewDialog1.AutoScrollMinSize = New System.Drawing.Size(0, 0)
Me.PrintPreviewDialog1.ClientSize = New System.Drawing.Size(400, 300)
Me.PrintPreviewDialog1.Document = Me.PrintDocument1
Me.PrintPreviewDialog1.Enabled = True
Me.PrintPreviewDialog1.Icon = CType(resources.GetObject("PrintPreviewDialog1.Icon"), System.Drawing.Icon)
Me.PrintPreviewDialog1.Location = New System.Drawing.Point(290, 17)
Me.PrintPreviewDialog1.MinimumSize = New System.Drawing.Size(375, 250)
Me.PrintPreviewDialog1.Name = "PrintPreviewDialog1"
Me.PrintPreviewDialog1.TransparencyKey = System.Drawing.Color.Empty
Me.PrintPreviewDialog1.Visible = False
'
'lblMsg
'
Me.lblMsg.Location = New System.Drawing.Point(0, 25)
Me.lblMsg.Name = "lblMsg"
Me.lblMsg.Size = New System.Drawing.Size(296, 12)
Me.lblMsg.TabIndex = 0
Me.lblMsg.Text = "测试"
'
'btnShowXml
'
Me.btnShowXml.BackColor = System.Drawing.Color.Azure
Me.btnShowXml.FlatStyle = System.Windows.Forms.FlatStyle.Flat
Me.btnShowXml.Location = New System.Drawing.Point(0, 0)
Me.btnShowXml.Name = "btnShowXml"
Me.btnShowXml.TabIndex = 6
Me.btnShowXml.Text = "显示Xml"
Me.btnShowXml.TextAlign = System.Drawing.ContentAlignment.TopCenter
'
'btnPreview
'
Me.btnPreview.BackColor = System.Drawing.Color.Azure
Me.btnPreview.FlatStyle = System.Windows.Forms.FlatStyle.Flat
Me.btnPreview.Location = New System.Drawing.Point(75, 0)
Me.btnPreview.Name = "btnPreview"
Me.btnPreview.TabIndex = 7
Me.btnPreview.Text = "预览"
Me.btnPreview.TextAlign = System.Drawing.ContentAlignment.TopCenter
'
'btnPrint
'
Me.btnPrint.BackColor = System.Drawing.Color.Azure
Me.btnPrint.FlatStyle = System.Windows.Forms.FlatStyle.Flat
Me.btnPrint.Location = New System.Drawing.Point(150, 0)
Me.btnPrint.Name = "btnPrint"
Me.btnPrint.TabIndex = 8
Me.btnPrint.Text = "打印"
Me.btnPrint.TextAlign = System.Drawing.ContentAlignment.TopCenter
'
'btnPageSetting
'
Me.btnPageSetting.BackColor = System.Drawing.Color.Azure
Me.btnPageSetting.FlatStyle = System.Windows.Forms.FlatStyle.Flat
Me.btnPageSetting.Location = New System.Drawing.Point(225, 0)
Me.btnPageSetting.Name = "btnPageSetting"
Me.btnPageSetting.TabIndex = 9
Me.btnPageSetting.Text = "页面设置"
Me.btnPageSetting.TextAlign = System.Drawing.ContentAlignment.TopCenter
'
'ctlXmlPrint
'
Me.BackColor = System.Drawing.SystemColors.Window
Me.Controls.Add(Me.btnPageSetting)
Me.Controls.Add(Me.btnPrint)
Me.Controls.Add(Me.btnPreview)
Me.Controls.Add(Me.btnShowXml)
Me.Controls.Add(Me.lblMsg)
Me.Name = "ctlXmlPrint"
Me.Size = New System.Drawing.Size(302, 40)
Me.ResumeLayout(False)

End Sub

#End Region
Private doc As New XmlDocument
Public Shared Pages As Integer = 1

#Region " 属性定义 "
'要打印的XML文档
Dim _sXml As String
Public Property sXml() As String
Get
Return _sXml
End Get
Set(ByVal Value As String)
_sXml = Value
End Set
End Property

Enum emPrintMode
预览 = 1
打印 = 2
页面设置 = 3
End Enum

'打印模式
Dim _PrintMode As emPrintMode
Property PrintMode() As emPrintMode
Get
Return _PrintMode
End Get
Set(ByVal Value As emPrintMode)
_PrintMode = Value
End Set
End Property
#End Region

#Region " 函数定义 "
'预览
Public Function PrintPreview()
Try
Call SettingPrinter(doc("root")("pagesetting"))
Me.PrintPreviewDialog1.ShowDialog()
Me.lblMsg.Text = "预览完成"
Catch ex As Exception
Me.lblMsg.Text = "预览失败:" & ex.Message
End Try

End Function
'打印
Public Function Print()
Try
Call SettingPrinter(doc("root")("pagesetting"))
Me.PrintDocument1.Print()
Me.lblMsg.Text = "打印完成"
Catch ex As Exception
Me.lblMsg.Text = "打印失败:" & ex.Message
End Try
End Function
'页面设置
Public Function PrintSetting()
Try
Me.PageSetupDialog1.ShowDialog()
Me.lblMsg.Text = "已打开页面设置"
Catch ex As Exception
Me.lblMsg.Text = "开页面设置打开失败:" & ex.Message
End Try

End Function
'根据 PrintMode 设置 自动调用相应函数
Public Function PirntAuto()
Select Case Me.PrintMode
Case emPrintMode.预览
Call Me.PrintPreview()
Case emPrintMode.打印
Call Me.Print()
Case emPrintMode.页面设置
Call Me.PrintSetting()
End Select
End Function
#End Region

#Region " 打印函数 "
Private Sub pd_PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)
Dim g As Graphics = ev.Graphics
Dim HasMorePages As Boolean = False
Dim printElement As PrintElement = Nothing

Dim node As XmlNode
For Each node In doc("root")("reporttable").ChildNodes
printElement = Parser.CreateElement(node) '调用解析器生成相应的对象

Try
HasMorePages = printElement.Draw(g) '是否需要分页
Catch ex As Exception
Me.lblMsg.Text = ex.Message
End Try
Next node

'在页底中间输出页码
Dim font As New Font("黑体", 12.0F)
Dim brush = New SolidBrush(Color.Black)
g.DrawString("第 " + Pages.ToString() + " 页", font, brush, ev.MarginBounds.Width / 2 + ev.MarginBounds.Left - 30, ev.PageBounds.Height - 60)

If HasMorePages Then
Pages += 1
End If
ev.HasMorePages = HasMorePages
End Sub 'pd_PrintPage

Private Sub SettingPrinter(ByVal ps As XmlNode)
'打印方向(纵/横)
Me.PrintDocument1.DefaultPageSettings.Landscape = Boolean.Parse(ps("landscape").InnerText)
'设置纸张类型
Dim papername As String = ps("paperkind").InnerText
Dim fitpaper As Boolean = False
'获取打印机支持的所有纸张类型
Dim size As PaperSize
For Each size In Me.PrintDocument1.PrinterSettings.PaperSizes
If papername = size.PaperName Then '看该打印机是否有我们需要的纸张类型
Me.PrintDocument1.DefaultPageSettings.PaperSize = size
fitpaper = True
End If
Next size
If Not fitpaper Then
'假如没有我们需要的标准类型,则使用自定义的尺寸
Me.PrintDocument1.DefaultPageSettings.PaperSize = New PaperSize("Custom", Integer.Parse(ps("paperwidth").InnerText), Integer.Parse(ps("paperheight").InnerText))
End If

'设置页边距
Me.PrintDocument1.DefaultPageSettings.Margins.Left = Integer.Parse(ps("pageleft").InnerText)
Me.PrintDocument1.DefaultPageSettings.Margins.Top = Integer.Parse(ps("pagetop").InnerText)
Me.PrintDocument1.DefaultPageSettings.Margins.Right = Integer.Parse(ps("pageright").InnerText)
Me.PrintDocument1.DefaultPageSettings.Margins.Bottom = Integer.Parse(ps("pagebottom").InnerText)
End Sub 'SettingPrinter
#End Region

Private Sub btnShowXml_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnShowXml.Click
MsgBox(doc.OuterXml.ToString.Replace("""", "'"))
System.Windows.Forms.Clipboard.SetDataObject(doc.OuterXml.ToString.Replace("""", "'"))
End Sub

Private Sub btnPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPreview.Click
Call Me.PrintPreview()
End Sub

Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click
Call Me.Print()
End Sub

Private Sub btnPageSetting_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPageSetting.Click
Call Me.PrintSetting()
End Sub

Private Sub ctlXmlPrint_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
doc.LoadXml(sXml)
Me.lblMsg.Text = "数据加载完成"
Catch ex As Exception
Me.lblMsg.Text = "数据加载失败:" & ex.Message
End Try
End Sub
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: