LocalReport Print with C# C#打印RDLC

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

代码
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 绑定打印机列表

代码
  #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;
       }

from:http://www.cnblogs.com/rwecho/archive/2010/04/08/1707507.html

时间: 2024-11-05 16:04:37

LocalReport Print with C# C#打印RDLC的相关文章

python print实现不换行打印

一.环境以及背景 winows10 + python2.7 + python3.5 需要使用python2.7 中的print并且不换行 二.使用方法  1. 在结尾添加一个逗号         print "hello world", 问题: 在输出结果后会多一个空格,这个空格把我坑了  2. 使用sys模块         import sys      sys.stdout.write("hello world")         sys.stdout.flu

生活在别处——“Samsung Cloud Print”云打印体验

据工信部发布的数据信息显示,截至8月底,我国移动互联网用户总数已达9.46亿户规模,其中手机上网总数超过9亿户.移动互联网用户规模的不断扩大,进一步证明拥抱移动互联网已成为不可扭转的趋势,也是各互联网设备及平台的全新机会. 云打印技术是一种基于这样的背景而诞生的新型打印方式,其依托云计算与大数据.移动终端设备等特点,使得用户可实现随时随地的打印需求.在最近2年的发展历程中,这种云打印方式因为具备便捷.高效.不受时间地域限制等优点,日趋成为商务市场的绝佳伴侣,三星"Samsung Cloud Pr

window.print()打印页面指定内容(使用iframe保证原页面不失效)

使用window.print()时会出现两个问题: (1)直接使用window.print() 打印的是整页内容-->无法实现打印指定区域 (2)打印时替换body中的内容,打印完成后再替换回来-->这样会导致原来页面事件失效 使用iframe即可打印指定内容,也可保证页面不失效,具体方法如下: 1.将打印的内容独立出来为一个print.html文件,并为页面添加打印事件 <!DOCTYPE html> <html> <head> ... </head

关于页面打印window.print()的样式问题

当我们打印网页的时候.有时候会发现.打印出来的.跟网页上看到的样式的差别有点大.这其中可能有的问题是.样式问题. 当调用打印(window.print())方法时.打印机会在网页的样式中查找 @media print{}的样式,并适应到要打印的网页中. 所以 如果要打印的页面符合看到的页面效果,最好在写套 样式 <style type="text/css"> /* @media print 为打印时适应的样式表*/ @media print { body { font-si

开启打印服务Print Spooler

windows系统需要开启Print Spooler才能进行打印,如果不开启,可能造成很多现象和原因,比如windows打印机队列的打印机全部消失,用Lodop打印的时候提示"Printer selected is not valid",或类似 请在操作系统安装打印机并开启打印服务 的提示.例如,图中就是在我以前的win8电脑上找到该服务的方法.(1)在 控制版面-管理工具-服务里面,找到Print Spooler并开启.(2)用win+R快捷键打开运行窗口,输入service.msc

C#制作RDLC报表

报表以前我只做过水晶报表,但是最近发现家里的VS上面居然没有水晶报表,发现水晶报表现在貌似已经不能完全免费的使用了,为了保险起见,就用了VS自带的RDLC报表,用完感觉其实也是够用的嘛~ 建立一RDLC报表的过程主要是: 1.新建一个windows窗口,拖一个Reportview控件在上面,用来显示报表 2.新建一个类,构成数据源: 需要哪些字段,就在类中添加哪些,比如简单的如下: using System; using System.Collections.Generic; using Sys

使用for循环打印矩形和三角形、菱形、空心菱形

打印矩形 **************************************************************************************************** public class Demo3_712 { public static void main(String args[]){ for(int i=1;i<=10;i++){ //控制行 for(int j=1;j<=10;j++){ //控制列 System.out.print(&

java简单打印金字塔(案例)

学习编程语言,打印简单的金字塔是基础的案例,在这里就简单的写了个案例,希望能帮助到各位 代码 效果 class  kinTa{    public static void main(String[] args) {        Scanner input = new Scanner(System.in);        for(int i = 1; i < 8; i++){   //控制行数            for(int j = 0; j < 8-i;j++){   //每行要打印的

打印流: PrintStream 和 PrintWriter

/* * 1.打印流: PrintStream 和 PrintWriter 两个. * * 1) PrintStream 字节的打印流, PrintWriter 字符的打印流. * * 2) 功能: 打印流均属于输出流.因此,用来以模拟打印机的方式来输出数据. * * 3) 它的常用方法: print() 和 println(); * * 4) 打印流具有自动刷新功能.即:自动调用 flush()方法. * * 5) 打印流还具有自动实现字符与字节的转换功能. * * 6) 以打印流方式实现数据