就是通过反射调用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
}