c# printing report server-side silent

c# - Imprimir un servidor de informes y silenciosamente



printing report (3)

EDITAR
También pegué el código para la implementación ReportViewerDisposer que estoy usando.

Junto con la clase ReportViewerDisposer encuentra aquí , estoy usando el siguiente código, que es parte de un proyecto más grande, pero debería ser capaz de adaptarlo fácilmente:

private string m_printerName; private string m_server; private string m_path; private string m_name; private Dictionary<string, string> m_parameters; private SizeF m_pageSize; private float m_marginLeft; private float m_marginTop; private float m_marginRight; private float m_marginBottom; private short m_copies; private int m_currentPageIndex; private List<Stream> m_reportStreams; public void PrintReport() { string mime, extension; ReportViewer viewer = new ReportViewer(); ReportViewerDisposer disposer = new ReportViewerDisposer(viewer); try { viewer.ProcessingMode = ProcessingMode.Remote; viewer.ServerReport.ReportServerUrl = new Uri(String.Format("http://{0}/ReportServer", m_server)); viewer.ServerReport.ReportPath = String.Format("/{0}/{1}", m_path, m_name); List<ReportParameter> param = new List<ReportParameter>(); foreach (ReportParameterInfo paramInfo in viewer.ServerReport.GetParameters()) { if (m_parameters.ContainsKey(paramInfo.Name.ToUpperInvariant())) { string value = m_parameters[paramInfo.Name.ToUpperInvariant()]; param.Add(new ReportParameter(paramInfo.Name, value)); } } viewer.ServerReport.SetParameters(param); viewer.RefreshReport(); CultureInfo us = new CultureInfo("en-US"); string deviceInfo = String.Format( "<DeviceInfo>" + " <OutputFormat>EMF</OutputFormat>" + " <PageWidth>{0}cm</PageWidth>" + " <PageHeight>{1}cm</PageHeight>" + " <MarginTop>{2}cm</MarginTop>" + " <MarginLeft>{3}cm</MarginLeft>" + " <MarginRight>{4}cm</MarginRight>" + " <MarginBottom>{5}cm</MarginBottom>" + "</DeviceInfo>", Math.Round(m_pageSize.Width, 2).ToString(us), Math.Round(m_pageSize.Height, 2).ToString(us), Math.Round(m_marginTop, 2).ToString(us), Math.Round(m_marginLeft, 2).ToString(us), Math.Round(m_marginRight, 2).ToString(us), Math.Round(m_marginBottom, 2).ToString(us)); m_reportStreams = new List<Stream>(); try { NameValueCollection urlAccessParameters = new NameValueCollection(); urlAccessParameters.Add("rs:PersistStreams", "True"); Stream s = viewer.ServerReport.Render("IMAGE", deviceInfo, urlAccessParameters, out mime, out extension); m_reportStreams.Add(s); urlAccessParameters.Remove("rs:PersistStreams"); urlAccessParameters.Add("rs:GetNextStream", "True"); do { s = viewer.ServerReport.Render("IMAGE", deviceInfo, urlAccessParameters, out mime, out extension); if (s.Length != 0) m_reportStreams.Add(s); } while (s.Length > 0); DoPrint(); } finally { foreach (Stream s in m_reportStreams) { s.Close(); s.Dispose(); } m_reportStreams = null; } } finally { disposer.CollectGarbageOnDispose = true; disposer.Dispose(); } } private void DoPrint() { m_currentPageIndex = 0; PrintDocument printDoc = new PrintDocument(); try { printDoc.PrintController = new StandardPrintController(); printDoc.PrinterSettings.PrinterName = m_printerName; printDoc.PrinterSettings.Copies = m_copies; if (!printDoc.PrinterSettings.IsValid) { throw new ArgumentException(String.Format("Drucker ''{0}'' ist nicht gültig!", m_printerName)); } // Drucke das Dokument aus printDoc.PrintPage += new PrintPageEventHandler(PrintPage); printDoc.QueryPageSettings += new QueryPageSettingsEventHandler(QueryPageSettings); printDoc.Print(); } finally { printDoc.PrintPage -= new PrintPageEventHandler(PrintPage); printDoc.QueryPageSettings -= new QueryPageSettingsEventHandler(QueryPageSettings); printDoc.Dispose(); } } private void PrintPage(object sender, PrintPageEventArgs ev)         { if (m_currentPageIndex < m_reportStreams.Count) { Metafile mf = new Metafile(m_reportStreams[m_currentPageIndex++]); try { ev.Graphics.DrawImage(mf, ev.PageBounds); } finally { mf.Dispose(); } } ev.HasMorePages = m_currentPageIndex < m_reportStreams.Count; } private void QueryPageSettings(object sender, QueryPageSettingsEventArgs e) { e.PageSettings.Landscape = m_pageSize.Width > m_pageSize.Height; } private class ReportViewerDisposer : IDisposable { // Fields private bool _CollectGarbageOnDispose = true; private ReportViewer _ReportViewer; private bool disposedValue = false; private const string EVENTHANDLER_ON_USER_PREFERENCE_CHANGED = "OnUserPreferenceChanged"; private const string LIST_HANDLERS = "_handlers"; private const string ON_USER_PREFERENCE_CHANGED_EVENT = "OnUserPreferenceChangedEvent"; private const string SYSTEM_EVENT_INVOKE_INFO = "SystemEventInvokeInfo"; private const string TARGET_DELEGATE = "_delegate"; private const string TOOLSTRIP_CONTROL_NAME = "reportToolBar"; private const string TOOLSTRIP_TEXTBOX_CONTROL_NAME_CURRENT_PAGE = "currentPage"; private const string TOOLSTRIP_TEXTBOX_CONTROL_NAME_TEXT_TO_FIND = "textToFind"; // Methods public ReportViewerDisposer(ReportViewer rptv) { if (rptv == null) { throw new ArgumentNullException("ReportViewer cannot be null."); } this._ReportViewer = rptv; } public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!this.disposedValue && disposing) { this.TearDownReportViewer(); this._ReportViewer.Dispose(); if (this._CollectGarbageOnDispose) { GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); } } this.disposedValue = true; } private void NullRefOnUserPreferenceChanged(object o, string field) { try { FieldInfo fi = o.GetType().GetField(field, BindingFlags.NonPublic | BindingFlags.Instance); if (fi != null) { int i; ToolStripTextBox tb = (ToolStripTextBox)fi.GetValue(o); object tbc = tb.Control; Delegate d = Delegate.CreateDelegate(typeof(UserPreferenceChangedEventHandler), tbc, EVENTHANDLER_ON_USER_PREFERENCE_CHANGED); object handlers = typeof(SystemEvents).GetField(LIST_HANDLERS, BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); object upcHandler = typeof(SystemEvents).GetField(ON_USER_PREFERENCE_CHANGED_EVENT, BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); object systemEventInvokeInfo = typeof(SystemEvents).GetNestedType(SYSTEM_EVENT_INVOKE_INFO, BindingFlags.NonPublic | BindingFlags.Instance); IList upcHandlerList = (IList)((IDictionary)handlers)[upcHandler]; int targetCount = 0; for (i = 0; i < upcHandlerList.Count; i++) { systemEventInvokeInfo = upcHandlerList[i]; Delegate target = (Delegate)systemEventInvokeInfo.GetType().GetField(TARGET_DELEGATE, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(systemEventInvokeInfo); if (target.Target == d.Target) { targetCount++; } } for (i = 1; i <= targetCount; i++) { SystemEvents.UserPreferenceChanged -= ((UserPreferenceChangedEventHandler)d); } } } catch { } } private void TearDownReportViewer() { FieldInfo fi = this._ReportViewer.GetType().GetField(TOOLSTRIP_CONTROL_NAME, BindingFlags.NonPublic | BindingFlags.Instance); if (fi != null) { object o = fi.GetValue(this._ReportViewer); this.NullRefOnUserPreferenceChanged(o, TOOLSTRIP_TEXTBOX_CONTROL_NAME_CURRENT_PAGE); this.NullRefOnUserPreferenceChanged(o, TOOLSTRIP_TEXTBOX_CONTROL_NAME_TEXT_TO_FIND); } } // Properties public bool CollectGarbageOnDispose { get { return this._CollectGarbageOnDispose; } set { this._CollectGarbageOnDispose = value; } } }

Estoy tratando de escribir un programa que me permita imprimir un informe ssrs (archivo .rdl) desde el código del lado del servidor a una impresora predeterminada sin ningún mensaje emergente que me pregunte qué impresora quiero usar ¿se puede hacer esto?


En primer lugar, debe presentar su informe SSRS en formato PDF y luego puede imprimir el archivo PDF directamente sin abrir ninguna ventana emergente. Consulte el siguiente código:

public void PrintPreviewSSRSReport(string reportName) { try { string reportPath = string.Empty; string historyID = null; string deviceInfo = null; string extension = null; string encoding = null; string mimeType = null; string[] streamIDs = null; string format = "PDF"; Byte[] result; ReportExecution2005.Warning[] warnings = null; ExecutionInfo execInfo = new ExecutionInfo(); TrustedUserHeader trusteduserHeader = new TrustedUserHeader(); ExecutionHeader execHeader = new ExecutionHeader(); ServerInfoHeader serviceInfo = new ServerInfoHeader(); MHTools.ReportExecution2005.ReportParameter[] _parameters = null; ParameterValue[] _ParameterValue = null; //Set the report path reportPath = "/Reports/SalesReport"; //Create the object of report execution web service ReportExecutionServiceSoapClient rsExec = new ReportExecutionServiceSoapClient(); //Use this if you don''t need to pass the credentials from code rsExec.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation; //Load the reports rsExec.LoadReport(trusteduserHeader, reportPath, historyID, out serviceInfo, out execInfo); execHeader.ExecutionID = execInfo.ExecutionID; //Get the parameters details from load report and eet the value in paremeters if any _parameters = execInfo.Parameters; _ParameterValue = new ParameterValue[1]; _ParameterValue[0] = new ParameterValue(); _ParameterValue[0].Name = _parameters[0].Name; _ParameterValue[0].Value = "12345"; //Set the parameters rsExec.SetExecutionParameters(execHeader, null, _ParameterValue, "en-us", out execInfo); //Render the report rsExec.Render(execHeader, null, format, deviceInfo, out result, out extension, out mimeType, out encoding, out warnings, out streamIDs); //pass the file path where pdf file will be saved using (FileStream stream = File.OpenWrite(PDFFile)) { stream.Write(result, 0, result.Length); } //send the padf file path to printer SendFileToPrinter(PDFFile); } catch (Exception ex) { // } } #region Print SSRS Report [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] private class DOCINFOA { [MarshalAs(UnmanagedType.LPStr)] public string pDocName; [MarshalAs(UnmanagedType.LPStr)] public string pOutputFile; [MarshalAs(UnmanagedType.LPStr)] public string pDataType; } [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd); [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool ClosePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di); [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool EndDocPrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool StartPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool EndPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten); [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool GetDefaultPrinter(StringBuilder pszBuffer, ref int size); /// <summary> /// This function gets the pdf file name. /// This function opens the pdf file, gets all its bytes & send them to print. /// </summary> /// <param name="szPrinterName">Printer Name</param> /// <param name="szFileName">Pdf File Name</param> /// <returns>true on success, false on failure</returns> public bool SendFileToPrinter(string pdfFileName) { try { #region Get Connected Printer Name PrintDocument pd = new PrintDocument(); StringBuilder dp = new StringBuilder(256); int size = dp.Capacity; if (GetDefaultPrinter(dp, ref size)) { pd.PrinterSettings.PrinterName = dp.ToString().Trim(); } #endregion Get Connected Printer Name // Open the PDF file. FileStream fs = new FileStream(pdfFileName, FileMode.Open); // Create a BinaryReader on the file. BinaryReader br = new BinaryReader(fs); Byte[] bytes = new Byte[fs.Length]; bool success = false; // Unmanaged pointer. IntPtr ptrUnmanagedBytes = new IntPtr(0); int nLength = Convert.ToInt32(fs.Length); // Read contents of the file into the array. bytes = br.ReadBytes(nLength); // Allocate some unmanaged memory for those bytes. ptrUnmanagedBytes = Marshal.AllocCoTaskMem(nLength); // Copy the managed byte array into the unmanaged array. Marshal.Copy(bytes, 0, ptrUnmanagedBytes, nLength); // Send the unmanaged bytes to the printer. success = SendBytesToPrinter(pd.PrinterSettings.PrinterName, ptrUnmanagedBytes, nLength); // Free the unmanaged memory that you allocated earlier. Marshal.FreeCoTaskMem(ptrUnmanagedBytes); return success; } catch (Exception ex) { throw new Exception(ex.Message); } } /// <summary> /// This function gets the printer name and an unmanaged array of bytes, the function sends those bytes to the print queue. /// </summary> /// <param name="szPrinterName">Printer Name</param> /// <param name="pBytes">No. of bytes in the pdf file</param> /// <param name="dwCount">Word count</param> /// <returns>True on success, false on failure</returns> private bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount) { try { Int32 dwError = 0, dwWritten = 0; IntPtr hPrinter = new IntPtr(0); DOCINFOA di = new DOCINFOA(); bool success = false; // Assume failure unless you specifically succeed. di.pDocName = Path.GetFileNameWithoutExtension(PDFFile); di.pDataType = "RAW"; // Open the printer. if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) { // Start a document. if (StartDocPrinter(hPrinter, 1, di)) { // Start a page. if (StartPagePrinter(hPrinter)) { // Write the bytes. success = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten); EndPagePrinter(hPrinter); } EndDocPrinter(hPrinter); } ClosePrinter(hPrinter); } // If print did not succeed, GetLastError may give more information about the failure. if (success == false) { dwError = Marshal.GetLastWin32Error(); } return success; } catch (Exception ex) { throw new Exception(ex.Message); } } #endregion


  1. Primero agregue una referencia web al servicio web de Reporting Services en su proyecto de desarrollo que apunta a su servidor de informes. Esto se puede hacer haciendo clic derecho en su proyecto en Visual Studio y seleccionando Agregar referencia web ... Debe agregar una referencia a un servidor de informes local (localhost) en " http: //localhost/reportserver/reportservice.asmx ".
  2. Use la clase ReportingService para imprimir usando algunos pasos.

sigue esto

Enlaces de referencia:
Imprimir automáticamente el informe de SSRS?
Impresión de SSRS sin showind Imprimir cuadro de diálogo
Impresión de informes mediante programación de C # y SQL Server 2000 Reporting Services
Imprimir el informe de SSRS automáticamente
Impresión de Reporting Services 2005 Reports