#region public static /// <summary> /// 获取指定ReportViewer总物理页数 /// guog2009-05-06新增 /// </summary> /// <param name="reportViewer">ReportViewer控件</param> /// <returns>总物理页数,默认值为0</returns> public static int GetTotalPage(ReportViewer reportViewer) { int result = 0; //设置为打印预览模式 reportViewer.SetDisplayMode(DisplayMode.PrintLayout); //记录当前页 int currentPage = reportViewer.CurrentPage; if (reportViewer.LocalReport.GetTotalPages() > 0) {//自带的GetTotalPages()方法返回的是逻辑页面总数,所以这里重新处理 while (true) { try { reportViewer.CurrentPage += 1; } catch { reportViewer.CurrentPage -= 1; result = reportViewer.CurrentPage; break; } finally { //指定到原始位置 reportViewer.CurrentPage = currentPage; } } } return result; } #endregion public static
打印代码:
#region 打印 #region 判断是否为横向 /// <summary> /// 判断是否为横向 /// </summary> /// <param name="stm">Rdlc文件流</param> /// <returns></returns> private bool IsLandSapces(Stream stm) { string strPageWidth = ""; string strPageHeight = ""; XmlReader xmlReader = XmlReader.Create(stm); if (xmlReader.ReadToFollowing("PageWidth")) { strPageWidth = xmlReader.ReadElementString("PageWidth"); } xmlReader.Close(); return strPageWidth == "29.7cm"; } #endregion 读取XML文件 /// <summary> /// 提供 Stream 对象以进行呈现的 CreateStreamCallback 委托指向的方法 /// 这里为将报表的每一个页面作为一个EMF图片存放,通常用于报表呈现 /// </summary> /// <param name="name">流的名称</param> /// <param name="fileNameExtension">创建文件流时要使用的文件扩展名</param> /// <param name="encoding">指定流的字符编码的 Encoding 枚举器值。如果流不包含字符,则此值可能为 null。</param> /// <param name="mimeType">一个包含流的 MIME 类型的 string</param> /// <param name="willSeek">指示流是否需要支持查找的 Boolean 值。如果值为 false,则流将为只前推,并将按其创建顺序发送到块区中的客户端。如果值为 true,则流可以任何顺序写入。</param> /// <returns>ReportViewer 控件可以写入数据的 Stream 对象</returns> private Stream CreateStream(string name,string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) { Stream stream = new FileStream(Path.GetTempPath() + name +"." + fileNameExtension, FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite); //Stream stream = new FileStream(Path.GetTempFileName(), FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite,8000,true); m_streams.Add(stream); return stream; } /// <summary> /// 导出报表的每一个页面到一个EMF文件 /// </summary> /// <param name="report">ReportViewer.LocalReport</param> /// <param name="pageSettings">页面设置</param> private void Export(LocalReport report,PageSettings pageSettings) { StringBuilder sbDeviceInfo = new StringBuilder(); if (pageSettings != null) { sbDeviceInfo.AppendLine("<DeviceInfo>"); sbDeviceInfo.AppendLine(" <OutputFormat>EMF</OutputFormat>"); sbDeviceInfo.AppendLine(String.Format(" <PageWidth>{0}cm</PageWidth>", FromInchToCM(pageSettings.PaperSize.Width))); sbDeviceInfo.AppendLine(String.Format(" <PageHeight>{0}cm</PageHeight>", FromInchToCM(pageSettings.PaperSize.Height))); sbDeviceInfo.AppendLine(String.Format(" <MarginTop>{0}cm</MarginTop>", FromInchToCM(pageSettings.Margins.Top))); sbDeviceInfo.AppendLine(String.Format(" <MarginLeft>{0}cm</MarginLeft>", FromInchToCM(pageSettings.Margins.Left))); sbDeviceInfo.AppendLine(String.Format(" <MarginRight>{0}cm</MarginRight>", FromInchToCM(pageSettings.Margins.Right))); sbDeviceInfo.AppendLine(String.Format(" <MarginBottom>{0}cm</MarginBottom>", FromInchToCM(pageSettings.Margins.Bottom))); sbDeviceInfo.AppendLine("</DeviceInfo>"); } else { string deviceInfo = "<DeviceInfo>" + " <OutputFormat>EMF</OutputFormat>" + " <PageWidth>21cm</PageWidth>" + " <PageHeight>29.7cm</PageHeight>" + " <MarginTop>2.5cm</MarginTop>" + " <MarginLeft>2.5cm</MarginLeft>" + " <MarginRight>2.5cm</MarginRight>" + " <MarginBottom>2.5cm</MarginBottom>" + "</DeviceInfo>"; sbDeviceInfo.AppendLine(deviceInfo); } Warning[] warnings; m_streams = new List<Stream>(); report.Render("Image", sbDeviceInfo.ToString(), new CreateStreamCallback(CreateStream), out warnings); foreach (Stream stream in m_streams) stream.Position = 0; } /// <summary> /// 当前页打印的输出 /// </summary> /// <param name="sender"></param> /// <param name="ev"></param> private void PrintPage(object sender, PrintPageEventArgs ev) { if (this.m_duplex) {//双面打印 #region 双面打印 //获取每份页数 int pagePerCopy = GetPageCountPerCopy(this.m_streams.Count, this.m_chkedCount); if (this.m_currentPageIndex > 0 && (this.m_currentPageIndex + 1) % pagePerCopy == 1 && this.m_isBlank && pagePerCopy % 2 != 0) {//输出空白页 //当前页面不是第一页,且当前页面为此份报表第一页,且每份报表页数为奇数 Bitmap emptyImage = new Bitmap(10, 10); if (ev.PageSettings.Landscape) { ev.Graphics.DrawImage(emptyImage, new Rectangle(0, 0, ev.PageBounds.Height, ev.PageBounds.Width)); } else { ev.Graphics.DrawImage(emptyImage, ev.PageBounds); } //标记已经打印空白页 this.m_isBlank = false; } else { Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]); if (ev.PageSettings.Landscape) { ev.Graphics.DrawImage(pageImage, new Rectangle(0, 0, ev.PageBounds.Height, ev.PageBounds.Width)); } else { ev.Graphics.DrawImage(pageImage, ev.PageBounds); } m_currentPageIndex++; //标记等待打印下一个空白页 this.m_isBlank = true; } #endregion 双面打印 } else {//单面打印 #region 单面打印 Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]); if (ev.PageSettings.Landscape) { ev.Graphics.DrawImage(pageImage, new Rectangle(0, 0, ev.PageBounds.Height, ev.PageBounds.Width)); } else { ev.Graphics.DrawImage(pageImage, ev.PageBounds); } m_currentPageIndex++; #endregion 单面打印 } ev.HasMorePages = (m_currentPageIndex < m_streams.Count); } /// <summary> /// 打印开始 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BeginPrint(object sender, PrintEventArgs e) { this.btnPrint.Enabled = false; } /// <summary> /// 打印结束 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void EndPrint(object sender, PrintEventArgs e) { this.btnPrint.Enabled = true; }
调用打印代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using yxsoft.emcms.cs.ReportPrintBaseLib; using yxsoft.emcms.common; using System.Reflection; using Microsoft.Reporting.WinForms; using Guog.Emcms.Win.Business.GeneralDataQuery.VerifyPrintView; using System.Drawing.Printing; using System.IO; using System.Drawing.Imaging; using System.Xml; namespace Guog.Emcms.Win.YXEmcms.Forms { public partial class FrmMeterVerifyPrintView : Form { #region 成员变量 /// <summary> /// 打印的对象 /// </summary> private PrintDocument m_printDocument = new PrintDocument(); /// <summary> /// 页面设置 /// </summary> private PageSettings m_pageSettings = new PageSettings(); /// <summary> /// 打印文件流列表 /// </summary> private IList<Stream> m_streams = new List<Stream>(); /// <summary> /// 当前呈现的页 /// </summary> private int m_currentPageIndex = 0; /// <summary> /// 是否横向打印,true表示横向,false表示纵向 /// </summary> private bool m_isLandSapce = false; /// <summary> /// 打印输出的对象 /// </summary> private ReportPrintBase m_reportPrintBase = null; /// <summary> /// 要打印输出的记录总数 /// </summary> private int m_chkedCount = 0; /// <summary> /// 空白页 /// </summary> private bool m_isBlank = true; /// <summary> /// 双面打印 /// </summary> private bool m_duplex = false; #endregion 成员变量 #region 窗体事件 public FrmMeterVerifyPrintView(ReportPrintBase reportPrintBase,int chkedCount) { InitializeComponent(); this.m_chkedCount = chkedCount; this.m_reportPrintBase = reportPrintBase; this.m_isLandSapce=this.IsLandSapces(this.m_reportPrintBase.MainReport.ReportFileStream); this.DoubleBuffered = true; } private void FrmMeterVerifyPrintView_Load(object sender, EventArgs e) { BindPrinters(); } private void FrmMeterVerifyPrintView_Shown(object sender, EventArgs e) { if (m_reportPrintBase != null && m_reportPrintBase.MainReport != null && m_reportPrintBase.MainReport.Validate) { BindReportData(this.m_reportPrintBase); } this.rptView.SetDisplayMode(DisplayMode.PrintLayout); this.rptView.ZoomMode = ZoomMode.PageWidth; //this.rptView.ZoomPercent = 100; } #region 加载报表数据 private void BindReportData(ReportPrintBase reportPrintBase) { //报表信息有效 if (reportPrintBase != null && reportPrintBase.MainReport != null && reportPrintBase.MainReport.Validate) {//支持的打印类型 #region 添加子报表加载事件,向子报表提供数据源支持 if (reportPrintBase.subreportProcessingEventHandler != null) { //加载子报表指定的事件,每个子报表加载时通过此事件指向的方法添加对应的数据源 this.rptView.LocalReport.SubreportProcessing += reportPrintBase.subreportProcessingEventHandler; } #endregion 加载子报表事件 #region 添加报表 //加载主报表文件流 this.rptView.LocalReport.LoadReportDefinition(reportPrintBase.MainReport.ReportFileStream); //添加主报表数据源 this.rptView.LocalReport.DataSources.Add(reportPrintBase.MainReport.DataSource); if (reportPrintBase.SubReports != null && reportPrintBase.SubReports.Count > 0) { foreach (ReportBaseInfo rpt in reportPrintBase.SubReports) { //加载子报表文件流 this.rptView.LocalReport.LoadSubreportDefinition(rpt.Name, rpt.ReportFileStream); } } #endregion 添加报表 //重新呈现(刷新)ReportViewer this.rptView.RefreshReport(); }//报表信息有效 } #endregion 加载报表数据 private void FrmMeterVerifyPrintView_FormClosing(object sender, FormClosingEventArgs e) { this.rptView.Reset(); CloseStreams(); Application.DoEvents(); } /// <summary> /// 关闭当前所有文件流 /// </summary> private void CloseStreams() { if (this.m_streams != null && this.m_streams.Count > 0) { foreach (Stream s in this.m_streams) { s.SetLength(0); s.Flush(); s.Close(); } this.m_streams.Clear(); } } #endregion #region 获取所有打印机 /// <summary> /// 获取当前安装在计算机上的所有打印机名称 /// </summary> /// <returns></returns> public static PrinterSettings.StringCollection GetAllPrintNames() { return System.Drawing.Printing.PrinterSettings.InstalledPrinters; } #endregion 获取所有打印机 #region 绑定打印机列表 private void BindPrinters() { cmbSelectPrinter.Items.Clear(); cmbSelectPrinter.DropDownStyle = ComboBoxStyle.DropDownList; string printerName; //获取默认打印机 string defaultPrinterName = this.m_printDocument.PrinterSettings.PrinterName; for (int i = 0; i < PrinterSettings.InstalledPrinters.Count; i++) { printerName = PrinterSettings.InstalledPrinters[i]; cmbSelectPrinter.Items.Add(printerName); if (printerName == defaultPrinterName) { cmbSelectPrinter.SelectedIndex = i; } } } #endregion 绑定打印机列表