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
View Code
代碼
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();
/// 頁面設定
private PageSettings m_pageSettings = new PageSettings();
/// 列印檔案流清單
private IList<Stream> m_streams = new List<Stream>();
/// 目前呈現的頁
private int m_currentPageIndex = 0;
/// 是否橫向列印,true表示橫向,false表示縱向
private bool m_isLandSapce = false;
/// 列印輸出的對象
private ReportPrintBase m_reportPrintBase = null;
/// <summary>
/// 要列印輸出的記錄總數
/// </summary>
private int m_chkedCount = 0;
/// 空白頁
private bool m_isBlank = true;
/// 雙面列印
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 擷取所有列印機
/// 擷取目前安裝在計算機上的所有列印機名稱
/// <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 判斷是否為橫向
/// 判斷是否為橫向
/// <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檔案
/// 提供 Stream 對象以進行呈現的 CreateStreamCallback 委托指向的方法
/// 這裡為将報表的每一個頁面作為一個EMF圖檔存放,通常用于報表呈現
/// <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;
}
/// 導出報表的每一個頁面到一個EMF檔案
/// <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;
/// 目前頁列印的輸出
/// <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]);
ev.Graphics.DrawImage(pageImage, new Rectangle(0, 0, ev.PageBounds.Height, ev.PageBounds.Width));
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));
ev.Graphics.DrawImage(pageImage, ev.PageBounds);
m_currentPageIndex++;
#endregion 單面列印
ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
/// 列印開始
/// <param name="e"></param>
private void BeginPrint(object sender, PrintEventArgs e)
this.btnPrint.Enabled = false;
/// 列印結束
private void EndPrint(object sender, PrintEventArgs e)
this.btnPrint.Enabled = true;