就是通过反射调用ReportViewer里的函数实现套打功能,在WinForm下测试并正在使用,WebForm下未经测试,不知可否使用。
在使用套打前不能ReportViewer.SetDisplayMode,Set后会造成打印两份文件出来,原因不清楚。
1 public static class ReportViewerExt
2 {
3 /// <summary>
4 /// 用默认打印机直接打印。
5 /// </summary>
6 /// <param name="reportViewer"></param>
7 public static void DirectPrint(this ReportViewer reportViewer)
8 {
9 Type reportViewerType = reportViewer.GetType();
10
11 FieldInfo printFieldInfo = reportViewerType.GetField("Print",
12 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
13 CancelEventHandler printEvent = (CancelEventHandler)printFieldInfo.GetValue(reportViewer);
14 if (printEvent != null) { printEvent(reportViewer, null); }
15
16 Object createEMFDeviceInfo = reportViewerType.InvokeMember("CreateEMFDeviceInfo",
17 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null,
18 reportViewer, new object[] { 1, 1 });
19 Delegate createAndRegisterStream = Delegate.CreateDelegate(typeof(CreateAndRegisterStream),
20 reportViewer, reportViewerType.GetMethod("CreateStreamEMFPrintOnly",
21 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod));
22 Type internalRenderingCompleteDelegateType =
23 reportViewerType.Assembly.GetType("Microsoft.Reporting.WinForms.InternalRenderingCompleteDelegate");
24 Delegate internalRenderingCompleteDelegate = Delegate.CreateDelegate(internalRenderingCompleteDelegateType,
25 reportViewer, reportViewerType.GetMethod("OnRenderingCompletePrintOnly",
26 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod));
27 Type postRenderArgsType = reportViewerType.Assembly.GetType("Microsoft.Reporting.WinForms.PostRenderArgs");
28 Object postRenderArgs = Activator.CreateInstance(postRenderArgsType, false, true);
29 Object report = reportViewerType.InvokeMember("Report", BindingFlags.NonPublic | BindingFlags.GetProperty |
30 BindingFlags.Instance, null, reportViewer, null);
31 Object backgroundThread = reportViewerType.InvokeMember("BackgroundThread", BindingFlags.NonPublic |
32 BindingFlags.GetProperty | BindingFlags.Instance, null, reportViewer, null);
33 backgroundThread.GetType().InvokeMember("BeginRender", BindingFlags.Public | BindingFlags.InvokeMethod |
34 BindingFlags.Instance, null, backgroundThread, new object[] { "IMAGE", true, createEMFDeviceInfo,
35 createAndRegisterStream, internalRenderingCompleteDelegate, postRenderArgs, report });
36
37 Type reportDocumentType = reportViewerType.Assembly.GetType("Microsoft.Reporting.WinForms.ReportPrintDocument");
38 Object currentReport = reportViewerType.InvokeMember("CurrentReport", BindingFlags.NonPublic |
39 BindingFlags.GetProperty | BindingFlags.Instance, null, reportViewer, null);
40 Object fileManager = currentReport.GetType().InvokeMember("FileManager", BindingFlags.GetProperty, null,
41 currentReport, null);
42 Object pageSettings = reportViewerType.InvokeMember("PageSettings", BindingFlags.NonPublic |
43 BindingFlags.GetProperty | BindingFlags.Instance, null, reportViewer, null);
44 Object pageSettingsClone = ((ICloneable)pageSettings).Clone();
45 ConstructorInfo constructorInfo = reportDocumentType.GetConstructor(BindingFlags.NonPublic |
46 BindingFlags.Instance, null, new Type[] { fileManager.GetType(), pageSettings.GetType() }, null);
47
48 PrintDocument document = (PrintDocument)constructorInfo.Invoke(new object[] { fileManager, pageSettingsClone });
49
50 document.DocumentName = (String)report.GetType().InvokeMember("DisplayNameForUse", BindingFlags.NonPublic |
51 BindingFlags.GetProperty | BindingFlags.Instance, null, report, null);
52 document.PrinterSettings = (PrinterSettings)reportViewerType.InvokeMember("CreateDefaultPrintSettings",
53 BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance, null, reportViewer, null);
54 document.PrinterSettings.PrintRange = PrintRange.AllPages;
55 document.Print();
56 }
57 }
2 {
3 /// <summary>
4 /// 用默认打印机直接打印。
5 /// </summary>
6 /// <param name="reportViewer"></param>
7 public static void DirectPrint(this ReportViewer reportViewer)
8 {
9 Type reportViewerType = reportViewer.GetType();
10
11 FieldInfo printFieldInfo = reportViewerType.GetField("Print",
12 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
13 CancelEventHandler printEvent = (CancelEventHandler)printFieldInfo.GetValue(reportViewer);
14 if (printEvent != null) { printEvent(reportViewer, null); }
15
16 Object createEMFDeviceInfo = reportViewerType.InvokeMember("CreateEMFDeviceInfo",
17 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null,
18 reportViewer, new object[] { 1, 1 });
19 Delegate createAndRegisterStream = Delegate.CreateDelegate(typeof(CreateAndRegisterStream),
20 reportViewer, reportViewerType.GetMethod("CreateStreamEMFPrintOnly",
21 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod));
22 Type internalRenderingCompleteDelegateType =
23 reportViewerType.Assembly.GetType("Microsoft.Reporting.WinForms.InternalRenderingCompleteDelegate");
24 Delegate internalRenderingCompleteDelegate = Delegate.CreateDelegate(internalRenderingCompleteDelegateType,
25 reportViewer, reportViewerType.GetMethod("OnRenderingCompletePrintOnly",
26 BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod));
27 Type postRenderArgsType = reportViewerType.Assembly.GetType("Microsoft.Reporting.WinForms.PostRenderArgs");
28 Object postRenderArgs = Activator.CreateInstance(postRenderArgsType, false, true);
29 Object report = reportViewerType.InvokeMember("Report", BindingFlags.NonPublic | BindingFlags.GetProperty |
30 BindingFlags.Instance, null, reportViewer, null);
31 Object backgroundThread = reportViewerType.InvokeMember("BackgroundThread", BindingFlags.NonPublic |
32 BindingFlags.GetProperty | BindingFlags.Instance, null, reportViewer, null);
33 backgroundThread.GetType().InvokeMember("BeginRender", BindingFlags.Public | BindingFlags.InvokeMethod |
34 BindingFlags.Instance, null, backgroundThread, new object[] { "IMAGE", true, createEMFDeviceInfo,
35 createAndRegisterStream, internalRenderingCompleteDelegate, postRenderArgs, report });
36
37 Type reportDocumentType = reportViewerType.Assembly.GetType("Microsoft.Reporting.WinForms.ReportPrintDocument");
38 Object currentReport = reportViewerType.InvokeMember("CurrentReport", BindingFlags.NonPublic |
39 BindingFlags.GetProperty | BindingFlags.Instance, null, reportViewer, null);
40 Object fileManager = currentReport.GetType().InvokeMember("FileManager", BindingFlags.GetProperty, null,
41 currentReport, null);
42 Object pageSettings = reportViewerType.InvokeMember("PageSettings", BindingFlags.NonPublic |
43 BindingFlags.GetProperty | BindingFlags.Instance, null, reportViewer, null);
44 Object pageSettingsClone = ((ICloneable)pageSettings).Clone();
45 ConstructorInfo constructorInfo = reportDocumentType.GetConstructor(BindingFlags.NonPublic |
46 BindingFlags.Instance, null, new Type[] { fileManager.GetType(), pageSettings.GetType() }, null);
47
48 PrintDocument document = (PrintDocument)constructorInfo.Invoke(new object[] { fileManager, pageSettingsClone });
49
50 document.DocumentName = (String)report.GetType().InvokeMember("DisplayNameForUse", BindingFlags.NonPublic |
51 BindingFlags.GetProperty | BindingFlags.Instance, null, report, null);
52 document.PrinterSettings = (PrinterSettings)reportViewerType.InvokeMember("CreateDefaultPrintSettings",
53 BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance, null, reportViewer, null);
54 document.PrinterSettings.PrintRange = PrintRange.AllPages;
55 document.Print();
56 }
57 }