Pennant的日常
分享工作上的点点滴滴
posts - 75,comments - 21,views - 66454

就是通过反射调用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[] { 11 });
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, falsetrue);
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, nullnew 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     }
复制代码
posted on   汝熹  阅读(3728)  评论(7编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
< 2009年5月 >
26 27 28 29 30 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 1 2 3 4 5 6

点击右上角即可分享
微信分享提示