using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Drawing.Printing; using System.IO; using Microsoft.Reporting.WebForms; using System.Drawing.Imaging; using System.Drawing; using System.Collections.Specialized; using System.Text; using System.Globalization; namespace EmisTerminal { /// /// The ReportPrintDocument will print all of the pages of a ServerReport or LocalReport. /// The pages are rendered when the print document is constructed. Once constructed, /// call Print() on this class to begin printing. /// public class ReportPrintDocument : PrintDocument { private PageSettings m_pageSettings; private int m_currentPage; private List m_pages = new List(); public ReportPrintDocument(ServerReport serverReport) : this((Report)serverReport) { RenderAllServerReportPages(serverReport); } public ReportPrintDocument(LocalReport localReport) : this((Report)localReport) { RenderAllLocalReportPages(localReport); } private ReportPrintDocument(Report report) { // Set the page settings to the default defined in the report ReportPageSettings reportPageSettings = report.GetDefaultPageSettings(); // The page settings object will use the default printer unless // PageSettings.PrinterSettings is changed. This assumes there // is a default printer. m_pageSettings = new PageSettings(); m_pageSettings.PaperSize = reportPageSettings.PaperSize; m_pageSettings.Margins = reportPageSettings.Margins; } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { foreach (Stream s in m_pages) { s.Dispose(); } m_pages.Clear(); } } protected override void OnBeginPrint(PrintEventArgs e) { base.OnBeginPrint(e); m_currentPage = 0; } protected override void OnPrintPage(PrintPageEventArgs e) { base.OnPrintPage(e); Stream pageToPrint = m_pages[m_currentPage]; pageToPrint.Position = 0; // Load each page into a Metafile to draw it. using (Metafile pageMetaFile = new Metafile(pageToPrint)) { Rectangle adjustedRect = new Rectangle( e.PageBounds.Left - (int)e.PageSettings.HardMarginX, e.PageBounds.Top - (int)e.PageSettings.HardMarginY, e.PageBounds.Width, e.PageBounds.Height); // Draw a white background for the report e.Graphics.FillRectangle(Brushes.White, adjustedRect); // Draw the report content e.Graphics.DrawImage(pageMetaFile, adjustedRect); // Prepare for next page. Make sure we haven't hit the end. m_currentPage++; e.HasMorePages = m_currentPage < m_pages.Count; } } protected override void OnQueryPageSettings(QueryPageSettingsEventArgs e) { e.PageSettings = (PageSettings)m_pageSettings.Clone(); } private void RenderAllServerReportPages(ServerReport serverReport) { try { string deviceInfo = CreateEMFDeviceInfo(); // Generating Image renderer pages one at a time can be expensive. In order // to generate page 2, the server would need to recalculate page 1 and throw it // away. Using PersistStreams causes the server to generate all the pages in // the background but return as soon as page 1 is complete. NameValueCollection firstPageParameters = new NameValueCollection(); firstPageParameters.Add("rs:PersistStreams", "True"); // GetNextStream returns the next page in the sequence from the background process // started by PersistStreams. NameValueCollection nonFirstPageParameters = new NameValueCollection(); nonFirstPageParameters.Add("rs:GetNextStream", "True"); string mimeType; string fileExtension; Stream pageStream = serverReport.Render("Image", deviceInfo, firstPageParameters, out mimeType, out fileExtension); // The server returns an empty stream when moving beyond the last page. while (pageStream.Length > 0) { m_pages.Add(pageStream); pageStream = serverReport.Render("Image", deviceInfo, nonFirstPageParameters, out mimeType, out fileExtension); } } catch (Exception e) { throw new Exception("possible missing information :: " + e.Message); } } private void RenderAllLocalReportPages(LocalReport localReport) { try { string deviceInfo = CreateEMFDeviceInfo(); Warning[] warnings; localReport.Render("IMAGE", deviceInfo, LocalReportCreateStreamCallback, out warnings); } catch (Exception e) { throw new Exception("error :: " + e); } } private Stream LocalReportCreateStreamCallback( string name, string extension, Encoding encoding, string mimeType, bool willSeek) { MemoryStream stream = new MemoryStream(); m_pages.Add(stream); return stream; } private string CreateEMFDeviceInfo() { PaperSize paperSize = m_pageSettings.PaperSize; Margins margins = m_pageSettings.Margins; // The device info string defines the page range to print as well as the size of the page. // A start and end page of 0 means generate all pages. return string.Format( CultureInfo.InvariantCulture, "emf00{0}{1}{2}{3}{4}{5}", ToInches(margins.Top + 20), ToInches(margins.Left), ToInches(margins.Right), ToInches(margins.Bottom), ToInches(paperSize.Height), ToInches(paperSize.Width)); } private static string ToInches(int hundrethsOfInch) { double inches = hundrethsOfInch / 100.0; return inches.ToString(CultureInfo.InvariantCulture) + "in"; } } }