代码
1 #region public static
2 /// <summary>
3 /// 获取指定ReportViewer总物理页数
4 /// guog2009-05-06新增
5 /// </summary>
6 /// <param name="reportViewer">ReportViewer控件</param>
7 /// <returns>总物理页数,默认值为0</returns>
8   public static int GetTotalPage(ReportViewer reportViewer)
9 {
10 int result = 0;
11 //设置为打印预览模式
12   reportViewer.SetDisplayMode(DisplayMode.PrintLayout);
13
14 //记录当前页
15   int currentPage = reportViewer.CurrentPage;
16 if (reportViewer.LocalReport.GetTotalPages() > 0)
17 {//自带的GetTotalPages()方法返回的是逻辑页面总数,所以这里重新处理
18  
19 while (true)
20 {
21 try
22 {
23 reportViewer.CurrentPage += 1;
24 }
25 catch
26 {
27 reportViewer.CurrentPage -= 1;
28 result = reportViewer.CurrentPage;
29 break;
30 }
31 finally
32 {
33 //指定到原始位置
34   reportViewer.CurrentPage = currentPage;
35 }
36 }
37 }
38
39 return result;
40 }
41
42
43 #endregion public static

 

 

代码
1 using System;
2  using System.Collections.Generic;
3  using System.ComponentModel;
4  using System.Data;
5  using System.Drawing;
6  using System.Text;
7  using System.Windows.Forms;
8 using yxsoft.emcms.cs.ReportPrintBaseLib;
9 using yxsoft.emcms.common;
10 using System.Reflection;
11 using Microsoft.Reporting.WinForms;
12 using Guog.Emcms.Win.Business.GeneralDataQuery.VerifyPrintView;
13 using System.Drawing.Printing;
14 using System.IO;
15 using System.Drawing.Imaging;
16 using System.Xml;
17
18 namespace Guog.Emcms.Win.YXEmcms.Forms
19 {
20 public partial class FrmMeterVerifyPrintView : Form
21 {
22
23 #region 成员变量
24 /// <summary>
25 /// 打印的对象
26 /// </summary>
27 private PrintDocument m_printDocument = new PrintDocument();
28 /// <summary>
29 /// 页面设置
30 /// </summary>
31 private PageSettings m_pageSettings = new PageSettings();
32 /// <summary>
33 /// 打印文件流列表
34 /// </summary>
35 private IList<Stream> m_streams = new List<Stream>();
36 /// <summary>
37 /// 当前呈现的页
38 /// </summary>
39 private int m_currentPageIndex = 0;
40 /// <summary>
41 /// 是否横向打印,true表示横向,false表示纵向
42 /// </summary>
43 private bool m_isLandSapce = false;
44 /// <summary>
45 /// 打印输出的对象
46 /// </summary>
47 private ReportPrintBase m_reportPrintBase = null;
48 /// <summary>
49 /// 要打印输出的记录总数
50 /// </summary>
51 private int m_chkedCount = 0;
52 /// <summary>
53 /// 空白页
54 /// </summary>
55 private bool m_isBlank = true;
56 /// <summary>
57 /// 双面打印
58 /// </summary>
59 private bool m_duplex = false;
60 #endregion 成员变量
61
62 #region 窗体事件
63 public FrmMeterVerifyPrintView(ReportPrintBase reportPrintBase,int chkedCount)
64 {
65 InitializeComponent();
66 this.m_chkedCount = chkedCount;
67 this.m_reportPrintBase = reportPrintBase;
68 this.m_isLandSapce=this.IsLandSapces(this.m_reportPrintBase.MainReport.ReportFileStream);
69 this.DoubleBuffered = true;
70 }
71
72 private void FrmMeterVerifyPrintView_Load(object sender, EventArgs e)
73 {
74 BindPrinters();
75 }
76
77 private void FrmMeterVerifyPrintView_Shown(object sender, EventArgs e)
78 {
79 if (m_reportPrintBase != null && m_reportPrintBase.MainReport != null &&
80 m_reportPrintBase.MainReport.Validate)
81 {
82 BindReportData(this.m_reportPrintBase);
83 }
84 this.rptView.SetDisplayMode(DisplayMode.PrintLayout);
85 this.rptView.ZoomMode = ZoomMode.PageWidth;
86 //this.rptView.ZoomPercent = 100;
87 }
88
89 #region 加载报表数据
90
91 private void BindReportData(ReportPrintBase reportPrintBase)
92 {
93 //报表信息有效
94 if (reportPrintBase != null && reportPrintBase.MainReport != null && reportPrintBase.MainReport.Validate)
95 {//支持的打印类型
96 #region 添加子报表加载事件,向子报表提供数据源支持
97 if (reportPrintBase.subreportProcessingEventHandler != null)
98 {
99 //加载子报表指定的事件,每个子报表加载时通过此事件指向的方法添加对应的数据源
100 this.rptView.LocalReport.SubreportProcessing += reportPrintBase.subreportProcessingEventHandler;
101 }
102 #endregion 加载子报表事件
103 #region 添加报表
104
105 //加载主报表文件流
106 this.rptView.LocalReport.LoadReportDefinition(reportPrintBase.MainReport.ReportFileStream);
107 //添加主报表数据源
108 this.rptView.LocalReport.DataSources.Add(reportPrintBase.MainReport.DataSource);
109 if (reportPrintBase.SubReports != null && reportPrintBase.SubReports.Count > 0)
110 {
111 foreach (ReportBaseInfo rpt in reportPrintBase.SubReports)
112 {
113 //加载子报表文件流
114 this.rptView.LocalReport.LoadSubreportDefinition(rpt.Name, rpt.ReportFileStream);
115 }
116 }
117
118 #endregion 添加报表
119 //重新呈现(刷新)ReportViewer
120 this.rptView.RefreshReport();
121 }//报表信息有效
122
123 }
124
125 #endregion 加载报表数据
126
127 private void FrmMeterVerifyPrintView_FormClosing(object sender, FormClosingEventArgs e)
128 {
129 this.rptView.Reset();
130 CloseStreams();
131 Application.DoEvents();
132 }
133
134 /// <summary>
135 /// 关闭当前所有文件流
136 /// </summary>
137 private void CloseStreams()
138 {
139 if (this.m_streams != null && this.m_streams.Count > 0)
140 {
141 foreach (Stream s in this.m_streams)
142 {
143 s.SetLength(0);
144 s.Flush();
145 s.Close();
146 }
147 this.m_streams.Clear();
148 }
149 }
150
151 #endregion
152
153 #region 获取所有打印机
154 /// <summary>
155 /// 获取当前安装在计算机上的所有打印机名称
156 /// </summary>
157 /// <returns></returns>
158 public static PrinterSettings.StringCollection GetAllPrintNames()
159 {
160 return System.Drawing.Printing.PrinterSettings.InstalledPrinters;
161 }
162 #endregion 获取所有打印机
163
164 #region 绑定打印机列表
165 private void BindPrinters()
166 {
167 cmbSelectPrinter.Items.Clear();
168 cmbSelectPrinter.DropDownStyle = ComboBoxStyle.DropDownList;
169 string printerName;
170 //获取默认打印机
171 string defaultPrinterName = this.m_printDocument.PrinterSettings.PrinterName;
172 for (int i = 0; i < PrinterSettings.InstalledPrinters.Count; i++)
173 {
174 printerName = PrinterSettings.InstalledPrinters[i];
175 cmbSelectPrinter.Items.Add(printerName);
176 if (printerName == defaultPrinterName)
177 {
178 cmbSelectPrinter.SelectedIndex = i;
179 }
180 }
181 }
182 #endregion 绑定打印机列表
183

 

 

代码
1 #region 打印
2
3 #region 判断是否为横向
4 /// <summary>
5 /// 判断是否为横向
6 /// </summary>
7 /// <param name="stm">Rdlc文件流</param>
8 /// <returns></returns>
9 private bool IsLandSapces(Stream stm)
10 {
11 string strPageWidth = "";
12 string strPageHeight = "";
13 XmlReader xmlReader = XmlReader.Create(stm);
14
15 if (xmlReader.ReadToFollowing("PageWidth"))
16 {
17 strPageWidth = xmlReader.ReadElementString("PageWidth");
18 }
19
20 xmlReader.Close();
21
22 return strPageWidth == "29.7cm";
23 }
24
25 #endregion 读取XML文件
26
27 /// <summary>
28 /// 提供 Stream 对象以进行呈现的 CreateStreamCallback 委托指向的方法
29 /// 这里为将报表的每一个页面作为一个EMF图片存放,通常用于报表呈现
30 /// </summary>
31 /// <param name="name">流的名称</param>
32 /// <param name="fileNameExtension">创建文件流时要使用的文件扩展名</param>
33 /// <param name="encoding">指定流的字符编码的 Encoding 枚举器值。如果流不包含字符,则此值可能为 null。</param>
34 /// <param name="mimeType">一个包含流的 MIME 类型的 string</param>
35 /// <param name="willSeek">指示流是否需要支持查找的 Boolean 值。如果值为 false,则流将为只前推,并将按其创建顺序发送到块区中的客户端。如果值为 true,则流可以任何顺序写入。</param>
36 /// <returns>ReportViewer 控件可以写入数据的 Stream 对象</returns>
37 private Stream CreateStream(string name,string fileNameExtension, Encoding encoding,
38 string mimeType, bool willSeek)
39 {
40 Stream stream = new FileStream(Path.GetTempPath() + name +"." + fileNameExtension, FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite);
41 //Stream stream = new FileStream(Path.GetTempFileName(), FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite,8000,true);
42 m_streams.Add(stream);
43 return stream;
44 }
45
46 /// <summary>
47 /// 导出报表的每一个页面到一个EMF文件
48 /// </summary>
49 /// <param name="report">ReportViewer.LocalReport</param>
50 /// <param name="pageSettings">页面设置</param>
51 private void Export(LocalReport report,PageSettings pageSettings)
52 {
53 StringBuilder sbDeviceInfo = new StringBuilder();
54 if (pageSettings != null)
55 {
56 sbDeviceInfo.AppendLine("<DeviceInfo>");
57 sbDeviceInfo.AppendLine(" <OutputFormat>EMF</OutputFormat>");
58 sbDeviceInfo.AppendLine(String.Format(" <PageWidth>{0}cm</PageWidth>", FromInchToCM(pageSettings.PaperSize.Width)));
59 sbDeviceInfo.AppendLine(String.Format(" <PageHeight>{0}cm</PageHeight>", FromInchToCM(pageSettings.PaperSize.Height)));
60 sbDeviceInfo.AppendLine(String.Format(" <MarginTop>{0}cm</MarginTop>", FromInchToCM(pageSettings.Margins.Top)));
61 sbDeviceInfo.AppendLine(String.Format(" <MarginLeft>{0}cm</MarginLeft>", FromInchToCM(pageSettings.Margins.Left)));
62 sbDeviceInfo.AppendLine(String.Format(" <MarginRight>{0}cm</MarginRight>", FromInchToCM(pageSettings.Margins.Right)));
63 sbDeviceInfo.AppendLine(String.Format(" <MarginBottom>{0}cm</MarginBottom>", FromInchToCM(pageSettings.Margins.Bottom)));
64 sbDeviceInfo.AppendLine("</DeviceInfo>");
65 }
66 else
67 {
68 string deviceInfo =
69 "<DeviceInfo>" +
70 " <OutputFormat>EMF</OutputFormat>" +
71 " <PageWidth>21cm</PageWidth>" +
72 " <PageHeight>29.7cm</PageHeight>" +
73 " <MarginTop>2.5cm</MarginTop>" +
74 " <MarginLeft>2.5cm</MarginLeft>" +
75 " <MarginRight>2.5cm</MarginRight>" +
76 " <MarginBottom>2.5cm</MarginBottom>" +
77 "</DeviceInfo>";
78
79 sbDeviceInfo.AppendLine(deviceInfo);
80 }
81 Warning[] warnings;
82 m_streams = new List<Stream>();
83 report.Render("Image", sbDeviceInfo.ToString(), new CreateStreamCallback(CreateStream), out warnings);
84 foreach (Stream stream in m_streams)
85 stream.Position = 0;
86
87 }
88
89 /// <summary>
90 /// 当前页打印的输出
91 /// </summary>
92 /// <param name="sender"></param>
93 /// <param name="ev"></param>
94 private void PrintPage(object sender, PrintPageEventArgs ev)
95 {
96 if (this.m_duplex)
97 {//双面打印
98 #region 双面打印
99 //获取每份页数
100 int pagePerCopy = GetPageCountPerCopy(this.m_streams.Count, this.m_chkedCount);
101 if (this.m_currentPageIndex > 0 && (this.m_currentPageIndex + 1) % pagePerCopy == 1 && this.m_isBlank && pagePerCopy % 2 != 0)
102 {//输出空白页
103 //当前页面不是第一页,且当前页面为此份报表第一页,且每份报表页数为奇数
104 Bitmap emptyImage = new Bitmap(10, 10);
105 if (ev.PageSettings.Landscape)
106 {
107 ev.Graphics.DrawImage(emptyImage, new Rectangle(0, 0, ev.PageBounds.Height, ev.PageBounds.Width));
108 }
109 else
110 {
111 ev.Graphics.DrawImage(emptyImage, ev.PageBounds);
112 }
113 //标记已经打印空白页
114 this.m_isBlank = false;
115 }
116 else
117 {
118 Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);
119 if (ev.PageSettings.Landscape)
120 {
121 ev.Graphics.DrawImage(pageImage, new Rectangle(0, 0, ev.PageBounds.Height, ev.PageBounds.Width));
122 }
123 else
124 {
125 ev.Graphics.DrawImage(pageImage, ev.PageBounds);
126 }
127 m_currentPageIndex++;
128 //标记等待打印下一个空白页
129 this.m_isBlank = true;
130 }
131 #endregion 双面打印
132 }
133 else
134 {//单面打印
135 #region 单面打印
136 Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);
137 if (ev.PageSettings.Landscape)
138 {
139 ev.Graphics.DrawImage(pageImage, new Rectangle(0, 0, ev.PageBounds.Height, ev.PageBounds.Width));
140 }
141 else
142 {
143 ev.Graphics.DrawImage(pageImage, ev.PageBounds);
144 }
145 m_currentPageIndex++;
146 #endregion 单面打印
147 }
148 ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
149 }
150 /// <summary>
151 /// 打印开始
152 /// </summary>
153 /// <param name="sender"></param>
154 /// <param name="e"></param>
155 private void BeginPrint(object sender, PrintEventArgs e)
156 {
157 this.btnPrint.Enabled = false;
158 }
159 /// <summary>
160 /// 打印结束
161 /// </summary>
162 /// <param name="sender"></param>
163 /// <param name="e"></param>
164 private void EndPrint(object sender, PrintEventArgs e)
165 {
166 this.btnPrint.Enabled = true;
167 }
168

 

 

 

感谢CSDN上面的大大 感谢goga21cn 发布的代码,通过这个我可以控制RDLC的打印了。还希望可以帮助别人!

 

 

posted on 2010-04-08 16:43  rwecho  阅读(4564)  评论(0)    收藏  举报