网上找来的RDLC报表打印实例,比较全面的实例,包括双面打印,XML操作等

定义一个静态:代码:
 #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 绑定打印机列表



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值