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<Stream> m_pages = new List<Stream>();
        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();
        }

        /// <summary>
        /// 直接打印
        /// </summary>
        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 =
                @"<DeviceInfo>
                    <OutputFormat>EMF</OutputFormat>
                    <PageWidth>{0}</PageWidth>
                    <PageHeight>{1}</PageHeight>
                    <MarginTop>{2}</MarginTop>
                    <MarginLeft>{3}</MarginLeft>
                    <MarginRight>{4}</MarginRight>
                    <MarginBottom>{5}</MarginBottom>
                </DeviceInfo>";

            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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Radish(萝卜)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值