项目有个很变态的需求.由于预计同时打印的报表特别多.所以要给每个打印文档命名,以便知道每个病人报表的打印情况,可是水晶报表似乎并没有提供设置在提交给打印机队列前设置文档名,都是默认是document ,网上找了一天似乎都没结果,要么是根本就是没有实现,要么就是一点理解有问题.
.思考摸索了一天,google了一天,没有合适的解决方案!很遗憾,心一横用了一个周末的时间重写了CrystalReportViewer控件..希望对后来人有帮助..
源代码如下:
Imports CrystalDecisions.Windows.Forms Imports System.Reflection Imports System.ComponentModel Imports System.Drawing.Printing Imports CrystalDecisions.CrystalReports.ViewerObjectModel 'add jove 2010-12-05 Namespace myReportViewerTools ''' ''' 重写的报表打印工具(add jove 2010-12-05) ''' 可以控制打印机队列的中 jobName ''' ''' Public Class myCrystalReportViewer Inherits CrystalReportViewer Private pageView1 As PageView Public Sub New() MyBase.New() End Sub Private _jobName As String = "Doc" & Date.Now.ToString("yyyy-MM-dd HH:mm:ss") ''' ''' 设置打印队列中的名称 ''' ''' ''' Public WriteOnly Property JobName() Set(ByVal value) If Not String.IsNullOrEmpty(value) Then _jobName = value End If End Set End Property Private Sub laog() Handles Me.Load Dim ponfo = GetType(CrystalReportViewer).GetField("pageView", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic) If ponfo IsNot Nothing Then pageView1 = ponfo.GetValue(Me) Dim ponfobtn = GetType(PageView).GetField("printButton", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic) If ponfobtn IsNot Nothing Then Dim btn As ToolStripButton = ponfobtn.GetValue(Me.pageView1) RemoveEvent(btn) 'AddHandler btn.Click, AddressOf showmsg AddHandler btn.Click, AddressOf PrintReport End If End If End Sub ''' ''' 移除控件上的特定类型的委托队列 ''' ''' ''' Private Sub RemoveEvent(ByVal c As ToolStripButton) Dim d As EventHandler = GetDelegate(c, "EventClick") If d IsNot Nothing Then For Each tmp As [Delegate] In d.GetInvocationList() RemoveHandler c.Click, tmp Next End If End Sub ''' ''' 获得某控件上的特定委托 ''' ''' ''' ''' ''' Private Function GetDelegate(ByVal issuer As Component, ByVal keyName As String) As Object Dim key = issuer.GetType() _ .GetField(keyName, BindingFlags.Static Or BindingFlags.NonPublic Or BindingFlags.FlattenHierarchy) _ .GetValue(Nothing) Dim events = GetType(Component).GetField("events", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(issuer) Dim listEntry = GetType(EventHandlerList) _ .GetMethod("Find", BindingFlags.NonPublic Or BindingFlags.Instance) _ .Invoke(events, New Object() {key}) Dim handler = listEntry _ .GetType() _ .GetField("handler", BindingFlags.Instance Or BindingFlags.NonPublic) _ .GetValue(listEntry) Return handler End Function ''' ''' 设置value ''' ''' ''' ''' ''' Private Sub SetPrivat(ByVal obj As Object, ByVal strname As String, ByVal vaule As Object) If obj Is Nothing Then Return End If Dim fd = GetType(ReportDocumentBase).GetField(strname, BindingFlags.Instance Or BindingFlags.NonPublic) fd.SetValue(obj, vaule) End Sub ''' ''' 获得值 ''' ''' ''' ''' ''' Private Function GetPrivat(ByVal obj As Object, ByVal strname As String) As Object If obj Is Nothing Then Return Nothing End If Dim fd = GetType(ReportDocumentBase).GetField(strname, BindingFlags.Instance Or BindingFlags.NonPublic) Return fd.GetValue(obj) End Function ''' ''' 测试代码 ''' ''' Private Sub showmsg() MsgBox(Date.Now.ToLongTimeString) End Sub ''' ''' 重写报表打印方法 ''' ''' Public Overrides Sub PrintReport() Dim activeDocument As ReportDocumentBase = CType(pageView1.GetActiveDocument(), ReportDocumentBase) If (Not activeDocument Is Nothing) Then 'activeDocument.Print() Dim dialog As New PrintDialog dialog.UseEXDialog = True dialog.AllowSomePages = True Dim settings As New PrinterSettings settings.MinimumPage = 1 settings.FromPage = 1 Dim minfo1 = GetType(ReportDocumentBase).GetMethod("GetLastPageNumber", BindingFlags.Instance Or BindingFlags.NonPublic) settings.MaximumPage = minfo1.Invoke(activeDocument, Nothing) settings.ToPage = settings.MaximumPage If (settings.MinimumPage <= settings.MaximumPage) Then Dim document As New PrintDocument document.DocumentName = _jobName document.PrinterSettings = settings Dim minfo2 = GetType(ReportDocumentBase).GetMethod("isPaperLandscape", BindingFlags.Instance Or BindingFlags.NonPublic) document.DefaultPageSettings.Landscape = minfo2.Invoke(activeDocument, Nothing) Dim minfo = GetType(ReportDocumentBase).GetMethod("getPaperKind", BindingFlags.Instance Or BindingFlags.NonPublic) Dim kind As PaperKind = minfo.Invoke(activeDocument, Nothing) Dim size As PaperSize For Each size In settings.PaperSizes If (size.Kind = kind) Then document.DefaultPageSettings.PaperSize = size Exit For End If Next dialog.Document = document Dim oK As DialogResult = DialogResult.OK Dim b = New PrintingPermission(PrintingPermissionLevel.AllPrinting) b.Assert() Try oK = dialog.ShowDialog Catch exception1 As Exception End Try If (oK <> DialogResult.OK) Then settings = Nothing Else AddHandler dialog.Document.PrintPage, New PrintPageEventHandler(AddressOf myPrintPageEventHander) SetPrivat(activeDocument, "CurHorizontalPage", 1) If (settings.PrintRange = PrintRange.AllPages) Then SetPrivat(activeDocument, "FromPage", 1) SetPrivat(activeDocument, "CurPage", 1) SetPrivat(activeDocument, "ToPage", settings.MaximumPage) SetPrivat(activeDocument, "TotalHorizontalPage", 1) Else SetPrivat(activeDocument, "FromPage", settings.FromPage) SetPrivat(activeDocument, "CurPage", settings.FromPage) SetPrivat(activeDocument, "ToPage", settings.ToPage) End If SetPrivat(activeDocument, "PrintCopies", settings.Copies) Try document.Print() Catch exception3 As Exception End Try End If End If End If End Sub Private Sub myPrintPageEventHander(ByVal sender As Object, ByVal e As PrintPageEventArgs) Dim activeDocument As ReportDocumentBase = CType(pageView1.GetActiveDocument(), ReportDocumentBase) Dim minfo2 = GetType(ReportDocumentBase).GetMethod("PrintPageEventHander", BindingFlags.Instance Or BindingFlags.NonPublic) minfo2.Invoke(activeDocument, New Object() {sender, e}) End Sub Private Function getPaperKind(ByRef activeDocument As ReportDocumentBase) As PaperKind Dim defaultPaperSize As CrystalDecisions.Shared.PaperSize = CrystalDecisions.Shared.PaperSize.DefaultPaperSize Dim i As Integer Dim fino = activeDocument.GetType.GetField("pages", BindingFlags.Instance Or BindingFlags.NonPublic) For i = 0 To fino.GetValue(activeDocument).Count - 1 Dim obj2 As PageObject = fino.GetValue(activeDocument).Item(i) If (Not obj2 Is Nothing) Then defaultPaperSize = obj2.PaperSize Exit For End If Next i Select Case defaultPaperSize Case CrystalDecisions.Shared.PaperSize.DefaultPaperSize Return PaperKind.Letter Case CrystalDecisions.Shared.PaperSize.PaperLetter Return PaperKind.Letter Case CrystalDecisions.Shared.PaperSize.PaperLetterSmall Return PaperKind.LetterSmall Case CrystalDecisions.Shared.PaperSize.PaperTabloid Return PaperKind.Tabloid Case CrystalDecisions.Shared.PaperSize.PaperLedger Return PaperKind.Ledger Case CrystalDecisions.Shared.PaperSize.PaperLegal Return PaperKind.Legal Case CrystalDecisions.Shared.PaperSize.PaperStatement Return PaperKind.Statement Case CrystalDecisions.Shared.PaperSize.PaperExecutive Return PaperKind.Executive Case CrystalDecisions.Shared.PaperSize.PaperA3 Return PaperKind.A3 Case CrystalDecisions.Shared.PaperSize.PaperA4 Return PaperKind.A4 Case CrystalDecisions.Shared.PaperSize.PaperA4Small Return PaperKind.A4Small Case CrystalDecisions.Shared.PaperSize.PaperA5 Return PaperKind.A5 Case CrystalDecisions.Shared.PaperSize.PaperB4 Return PaperKind.B4 Case CrystalDecisions.Shared.PaperSize.PaperB5 Return PaperKind.B5 Case CrystalDecisions.Shared.PaperSize.PaperFolio Return PaperKind.Folio Case CrystalDecisions.Shared.PaperSize.PaperQuarto Return PaperKind.Quarto Case CrystalDecisions.Shared.PaperSize.Paper10x14 Return PaperKind.Standard10x14 Case CrystalDecisions.Shared.PaperSize.Paper11x17 Return PaperKind.Standard11x17 Case CrystalDecisions.Shared.PaperSize.PaperNote Return PaperKind.Note Case CrystalDecisions.Shared.PaperSize.PaperEnvelope9 Return PaperKind.Number9Envelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelope10 Return PaperKind.Number10Envelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelope11 Return PaperKind.Number11Envelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelope12 Return PaperKind.Number12Envelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelope14 Return PaperKind.Number14Envelope Case CrystalDecisions.Shared.PaperSize.PaperCsheet Return PaperKind.CSheet Case CrystalDecisions.Shared.PaperSize.PaperDsheet Return PaperKind.DSheet Case CrystalDecisions.Shared.PaperSize.PaperEsheet Return PaperKind.ESheet Case CrystalDecisions.Shared.PaperSize.PaperEnvelopeDL Return PaperKind.DLEnvelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelopeC5 Return PaperKind.C5Envelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelopeC3 Return PaperKind.C3Envelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelopeC4 Return PaperKind.C4Envelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelopeC6 Return PaperKind.C6Envelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelopeC65 Return PaperKind.C65Envelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelopeB4 Return PaperKind.B4Envelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelopeB5 Return PaperKind.B5Envelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelopeB6 Return PaperKind.B6Envelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelopeItaly Return PaperKind.ItalyEnvelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelopeMonarch Return PaperKind.MonarchEnvelope Case CrystalDecisions.Shared.PaperSize.PaperEnvelopePersonal Return PaperKind.PersonalEnvelope Case CrystalDecisions.Shared.PaperSize.PaperFanfoldUS Return PaperKind.USStandardFanfold Case CrystalDecisions.Shared.PaperSize.PaperFanfoldStdGerman Return PaperKind.GermanStandardFanfold Case CrystalDecisions.Shared.PaperSize.PaperFanfoldLegalGerman Return PaperKind.GermanLegalFanfold End Select Return PaperKind.Letter End Function End Class End Namespace