2014-02-14 3 views
3

Я работаю над проектом WPF C# 4.0, в котором Я пытаюсь распечатать отчет RDLC, который в основном представляет собой счет, без отображения ReportViewer. Я ссылался на код из MSDN link и менял его для своей цели.Печать отчета RDLC напрямую без отображения reportviewer

Ниже приведен модифицированный код, который я использую.

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; 
      } 
     } 
    } 
} 

код, который Запускает Выполнить метод

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.

О дальнейшем копании я определил, что код ехе создает промежуточный файл EMF в этом пути C:\Users\Nilesh\AppData\Local\Apps\2.0\BWQ6XD5A.DB0

enter image description here

Если я пытаюсь открыть этот файл, я получаю следующую ошибку:

enter image description here

Нужна помощь в определении того, что происходит с кодом.

Любая помощь приветствуется. Благодаря!!

+0

ли вы получили решение этой проблемы? –

+0

У меня тоже есть эта проблема. Он печатает для первого отчета. а затем не удается распечатать последующие отчеты. – Smith

ответ

1

Я использовал этот код, и он очень хорошо работает для меня.

Сначала добавьте этот класс в проект enter link description here

Затем используйте следующий код для печати непосредственно на принтер по умолчанию:

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

его работа. Спасибо тебе –

Смежные вопросы