C#打印控件ReportViewer使用总结(四)

直接打印

默认情况ReportViewer是不支持直接打印的,需要借助PrintDocument打印类,这里对此类进行了二次封装继承,直接拿来用就可以,代码如下:

using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.CompilerServices;

namespace WinformReportTest
{
    class AutoPrintCls : PrintDocument
    {
        private PageSettings m_pageSettings;
        private int m_currentPage;
        private List m_pages = new List();
        private bool isPrint = true;
        
        public AutoPrintCls(ServerReport serverReport) : this((Report)serverReport)
        {
            RenderAllServerReportPages(serverReport);
        }
        public AutoPrintCls(LocalReport localReport) : this((Report)localReport)
        {
            RenderAllLocalReportPages(localReport);
        }


        private AutoPrintCls(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();
        }

        ///


        /// 直接打印
        ///

        public void AutoPrint()
        {
            if (isPrint)
            {
                this.Print();
                Dispose(true);
            }
            else
            {
                MessageBox.Show("error: m_pages count is 0.");
            }
        }

        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)
            {
                MessageBox.Show("possible missing information :: " + e);
            }
        }
        private void RenderAllLocalReportPages(LocalReport localReport)
        {
            try
            {
                string deviceInfo = CreateEMFDeviceInfo();
                Warning[] warnings;
                localReport.Render("IMAGE", deviceInfo, LocalReportCreateStreamCallback, out warnings);
                if (m_pages == null || m_pages.Count == 0)
                {
                    isPrint = false;
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("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;

            string deviceInfo =
                @"
                    EMF
                    {0}
                    {1}
                    {2}
                    {3}
                    {4}
                    {5}
               
";

            return string.Format(CultureInfo.InvariantCulture, deviceInfo, ToInches(paperSize.Width), ToInches(paperSize.Height), ToInches(margins.Top), ToInches(margins.Left), ToInches(margins.Right), ToInches(margins.Bottom));
        }


        private static string ToInches(int hundrethsOfInch)
        {
            double inches = hundrethsOfInch / 100.0;
            return inches.ToString(CultureInfo.InvariantCulture) + "in";
        }

    }
}
 

使用实例:https://download.csdn.net/download/sunsddd/87922367

你可能感兴趣的:(c#,c#,开发语言)