繁体   English   中英

直接打印 RDLC 报告而不显示报告查看器

[英]Printing RDLC Report directly without displaying reportviewer

我正在 WPF C# 4.0 项目中工作,在该项目中我试图打印 RDLC 报告,该报告基本上是直接发票而不显示 ReportViewer。 我参考了以下MSDN 链接中的代码并根据我的目的对其进行了修改。

以下是我正在使用的修改后的代码。

using System;
using System.IO;
using System.Data;
using System.Text;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.Collections.Generic;
using System.Windows.Forms;
using Microsoft.Reporting.WinForms;
using System.Xml;
using System.Resources;
using System.Drawing;
using System.Reflection;

namespace POS.Classes
{
    public class DirectReportPrint : IDisposable
    {
        private double[] PageBounds = { 0,0,0,0,0,0};
        private int m_currentPageIndex;
        private IList<Stream> m_streams;

        private DataTable _table = new DataTable();
        /// <summary>
        /// Must set this to get the report data
        /// </summary>
        public DataTable ReportTable
        {
            get { return _table; }
            set { _table = value; }
        }

        // Routine to provide to the report renderer, in order to
        //    save an image for each page of the report.
        private Stream CreateStream(string name,
          string fileNameExtension, Encoding encoding,
          string mimeType, bool willSeek)
        {
            //Stream stream = new FileStream(@"..\..\" + name +
            //   "." + fileNameExtension, FileMode.Create);
            Stream stream = new FileStream(Path.GetTempPath() + "\\" + name +
               "." + fileNameExtension, FileMode.Create);
            m_streams.Add(stream);
            return stream;
        }

        private string ReadEmbeddedResource(string ResourceName)
        {
            var assembly = Assembly.GetExecutingAssembly();
            using (Stream stream = assembly.GetManifestResourceStream(ResourceName))
            using (StreamReader reader = new StreamReader(stream))
            {
                string result = reader.ReadToEnd();
                string temp = result.Replace('\r',' ');
                return temp;
            }
        }

        private string ReadReportXML(string ReportName)
        {
            try
            {
                string s = " ", temp = "", t = "";
                int x, y, z;
                string result = ReadEmbeddedResource(ReportName);
                if (result.Contains("<PageHeight>") && result.Contains("</PageHeight>"))
                {
                    x = result.IndexOf("<PageHeight>");
                    y = result.IndexOf("</PageHeight>");
                    temp = result.Substring(x, y - x);
                    s += temp + "</PageHeight>  ";
                    z = temp.IndexOf('>') + 1;
                    t = temp.Substring(z, temp.Length - z);
                    PageBounds[0] = Math.Round(Convert.ToDouble(t.Substring(0, t.Length - 2)), 2);
                }
                if (result.Contains("<PageWidth>") && result.Contains("</PageWidth>"))
                {
                    x = result.IndexOf("<PageWidth>");
                    y = result.IndexOf("</PageWidth>");
                    temp = result.Substring(x, y - x);
                    s += temp + "</PageWidth>  ";
                    z = temp.IndexOf('>') + 1;
                    t = temp.Substring(z, temp.Length - z);
                    PageBounds[1] = Math.Round(Convert.ToDouble(t.Substring(0, t.Length - 2)), 2);
                }
                if (result.Contains("<LeftMargin>") && result.Contains("</LeftMargin>"))
                {
                    x = result.IndexOf("<LeftMargin>");
                    y = result.IndexOf("</LeftMargin>");
                    temp = result.Substring(x, y - x);
                    s += temp + "</LeftMargin>  ";
                    z = temp.IndexOf('>') + 1;
                    t = temp.Substring(z, temp.Length - z);
                    PageBounds[2] = Math.Round(Convert.ToDouble(t.Substring(0, t.Length - 2)), 2);
                }
                if (result.Contains("<RightMargin>") && result.Contains("</RightMargin>"))
                {
                    x = result.IndexOf("<RightMargin>");
                    y = result.IndexOf("</RightMargin>");
                    temp = result.Substring(x, y - x);
                    s += temp + "</RightMargin>  ";
                    z = temp.IndexOf('>') + 1;
                    t = temp.Substring(z, temp.Length - z);
                    PageBounds[3] = Math.Round(Convert.ToDouble(t.Substring(0, t.Length - 2)), 2);
                }
                if (result.Contains("<TopMargin>") && result.Contains("</TopMargin>"))
                {
                    x = result.IndexOf("<TopMargin>");
                    y = result.IndexOf("</TopMargin>");
                    temp = result.Substring(x, y - x);
                    s += temp + "</TopMargin>  ";
                    z = temp.IndexOf('>') + 1;
                    t = temp.Substring(z, temp.Length - z);
                    PageBounds[4] = Math.Round(Convert.ToDouble(t.Substring(0, t.Length - 2)), 2);
                }
                if (result.Contains("<BottomMargin>") && result.Contains("</BottomMargin>"))
                {
                    x = result.IndexOf("<BottomMargin>");
                    y = result.IndexOf("</BottomMargin>");
                    temp = result.Substring(x, y - x);
                    s += temp + "</BottomMargin>  ";
                    z = temp.IndexOf('>') + 1;
                    t = temp.Substring(z, temp.Length - z);
                    PageBounds[5] = Math.Round(Convert.ToDouble(t.Substring(0, t.Length - 2)), 2);
                }
                return s;
            }
            catch (Exception ex)
            {
                return null;
            }
        }        

        // Export the given report as an EMF (Enhanced Metafile) file.
        private void Export(LocalReport report, string ReportName)
        {
            try
            {
                string temp = ReadReportXML(ReportName);
                if (temp != null)
                {
                    string deviceInfo =
                      "<DeviceInfo>" +
                      "  <OutputFormat>EMF</OutputFormat>"
                      + temp +
                      "</DeviceInfo>";

                    Warning[] warnings;
                    m_streams = new List<Stream>();
                    report.Render("Image", deviceInfo, CreateStream,
                       out warnings);
                    foreach (Stream stream in m_streams)
                        stream.Position = 0;
                }
                else
                {
                    throw new Exception("Something went wrong. Unable to Print Report");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                MessageBox.Show(ex.InnerException.Message);
            }
        }

        // Handler for PrintPageEvents
        private void PrintPage(object sender, PrintPageEventArgs ev)
        {
            Metafile pageImage = new
            Metafile(m_streams[m_currentPageIndex]);

            // Adjust rectangular area with printer margins.
            Rectangle adjustedRect = new Rectangle(
                ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX,
                ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY,
                ev.PageBounds.Width,
                ev.PageBounds.Height);

            // Draw a white background for the report
            ev.Graphics.FillRectangle(Brushes.White, adjustedRect);

            // Draw the report content
            ev.Graphics.DrawImage(pageImage, adjustedRect);

            // Prepare for the next page. Make sure we haven't hit the end.
            m_currentPageIndex++;
            ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
        }

        private void Print()
        {
            PrinterSettings settings = new PrinterSettings();

            if (m_streams == null || m_streams.Count == 0)
                return;
            PrintDocument printDoc = new PrintDocument();
            printDoc.PrinterSettings.PrinterName = settings.PrinterName;

            PaperSize CustomSize = new PaperSize("Custom", (int)PageBounds[1]*100, (int)PageBounds[0]*100);
            CustomSize.RawKind = (int)PaperKind.Custom;
            printDoc.DefaultPageSettings.PaperSize = CustomSize;


            if (!printDoc.PrinterSettings.IsValid)
            {
                string msg = String.Format(
                   "Can't find printer \"{0}\".", settings.PrinterName);
                MessageBox.Show(msg, "Print Error");
                return;
            }
            printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
            printDoc.Print();
        }

        /// <summary>
        ///  Create a local report for Report.rdlc, load the data,
        ///  export the report to an .emf file, and print it.
        /// Prints the report directly
        /// </summary>
        /// <param name="ReportName">Name of the report</param>
        /// <param name="DS_Name">Dataset name for the report. Provide the name which was used during RDLC file creation</param>
        public void Run(string ReportName, string DS_Name)
        {
            LocalReport report = new LocalReport();
            report.ReportEmbeddedResource = ReportName;
            report.DataSources.Add(new ReportDataSource(DS_Name, ReportTable));
            Export(report, ReportName);
            m_currentPageIndex = 0;
            Print();
            Dispose();
        }

        public void Dispose()
        {
            if (m_streams != null)
            {
                foreach (Stream stream in m_streams)
                    stream.Close();
                m_streams = null;
            }
        }
    }
}

调用 Run 方法的代码

Classes.DirectReportPrint drp = new Classes.DirectReportPrint();
drp.ReportTable = Classes.Class_Sales_Bill.GetBillDetails(this.saleObj.Row_ID);
drp.Run("POS.Reports.Rpt_Anil_Sale_Bill.rdlc", "DataSet1");

当我使用 Visual Studio 调试器执行它时,此代码运行良好。 但是,如果我发布我的项目,安装它的设置,然后尝试运行它的 exe (Weird Behaviour) ,它就会失败。

如果我运行 exe,它适用于我尝试打印的第一张发票。 对于后续发票,我收到以下错误

An error occurred during local report processing. Access to the Path 'c:\Users\Rpt_Anil_Sale_Bill_0.EMF' is denied.

这里Rpt_Anil_Sale_Bill是我的 RDLC 文件的名称。

在进一步挖掘时,我发现 exe 代码在此路径中创建了一个中间 EMF 文件C:\\Users\\Nilesh\\AppData\\Local\\Apps\\2.0\\BWQ6XD5A.DB0

在此处输入图片说明

如果我尝试打开此文件,则会出现以下错误:

在此处输入图片说明

需要帮助确定代码出了什么问题。

任何帮助表示赞赏。 谢谢!!

我使用了这段代码,它对我来说效果很好。

首先将此类添加到您的项目中

然后使用以下代码直接打印到默认打印机:

LocalReport report = new LocalReport();
report.ReportEmbeddedResource = ReportSource;
report.DataSources.Add(myDataSource);
report.PrintToPrinter();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM