C# 以编程方式从 SQL 2012 Reporting Services 导出报表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12199995/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 22:26:37  来源:igfitidea点击:

Programmatically exporting reports from SQL 2012 Reporting Services

c#web-servicesreporting-servicessql-server-2012

提问by JustAMartin

I have a console application which needs to connect to SQL Reporting Services on SQL Server Express 2012. All the exporting logic should be implemented in a separate dll, and the paths should be dynamic (I have loop through various settings for various servers/reports and export them to Excel one by one).

我有一个控制台应用程序需要连接到 SQL Server Express 2012 上的 SQL Reporting Services。所有导出逻辑都应该在一个单独的 dll 中实现,并且路径应该是动态的(我循环了各种服务器/报告的各种设置和将它们一一导出到Excel)。

I tried to follow these tutorials:

我试图按照这些教程:

http://www.aspose.com/docs/display/wordsreportingservices/Rendering+Reports+Programmatically

http://www.aspose.com/docs/display/wordsreportingservices/Rendering+Reports+Programmatically

http://blogs.msdn.com/b/selvar/archive/2010/12/13/accessing-the-reportexecutionservice-render-method-when-reporting-service-2008-r2-is-in-forms-based-authentication.aspx

http://blogs.msdn.com/b/selvar/archive/2010/12/13/accessing-the-reportexecutionservice-render-method-when-reporting-service-2008-r2-is-in-forms-based-身份验证.aspx

Basically, I added web references:

基本上,我添加了网络引用:

http://localhost:80/ReportServer_SQLEXPRESS12/ReportExecution2005.asmx

and

http://localhost:80/ReportServer_SQLEXPRESS12/ReportService2010.asmx

to my dll. Looks good so far, except those nasty app.config settings (I'll have to adjust them dynamically later).

到我的 dll。到目前为止看起来不错,除了那些讨厌的 app.config 设置(稍后我必须动态调整它们)。

Then I tried to do as in the example:

然后我尝试按照示例进行操作:

// Create Web service proxies.
ReportingService2010.ReportingService2010 rs = new ReportingService2010.ReportingService2010();
ReportExecutionService.ReportExecutionService rsExec = new ReportExecutionService.ReportExecutionService();

and got some troubles:

并遇到了一些麻烦:

Error   76  The type or namespace name 'ReportExecutionService' does not exist in the namespace 'MyDllNamespace.ReportExecutionService' (are you missing an assembly reference?)    

Error   74  The type or namespace name 'ReportingService2010' does not exist in the namespace 'MyDllNamespace.ReportingService2010' (are you missing an assembly reference?)

Now where do I go next, how do I use the Reporting Services API, if I cannot even create a proxy object? Or should I better use ServerReport class form the Winforms ReportViewer instead of these web references?

现在我下一步该去哪里,如果我什至无法创建代理对象,我该如何使用 Reporting Services API?或者我应该更好地使用 Winforms ReportViewer 中的 ServerReport 类而不是这些 Web 引用?

Even one of Microsoft examples is using ReportViewer in a console application, but it seems a bit awkward to import Winforms in a console app.

甚至微软的一个例子是在控制台应用程序中使用 ReportViewer,但在控制台应用程序中导入 Winforms 似乎有点尴尬。

采纳答案by tschmit007

I hope the following will help (extract of pertinent parts of code)

我希望以下内容会有所帮助(代码相关部分的摘录)

            using (ZUtilities.SSRS.Report report = new ZUtilities.SSRS.Report {
                ReportServerPath = VParameter.GetValue("SSRS_WebServiceUrl", _repo.Parameters).ToString(),
                Format = rformat,
                ReportPath = "some_path_on_ssrs_server"
            }) {
                report.Params.Add("Id", id.ToString());
                report.Credentials = nwc;
                MemoryStream ms = new MemoryStream();
                report.Render().CopyTo(ms);
                FileContentResult fsr = new FileContentResult(ms.ToArray(), rctype);
                fsr.FileDownloadName = String.Format("EPV-{0}-{1:yyyyMMdd}.{2}", epv.ExternalReference, DateTime.Now, fext);
                ms.Close();
                return fsr;
            }

with the following (be carefull to the stream management)

与以下(小心流管理)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;

namespace ZUtilities.SSRS {
    public enum ReportFormats {
        Html = 1,
        MHtml,
        Pdf,
        Xlsx,
        Docx
    }

    public class ReportFormat {
        static ReportFormat() {
            Html = new ReportFormat { Code = ReportFormats.Html, Instruction = "HTML4.0" };
            MHtml = new ReportFormat { Code = ReportFormats.MHtml, Instruction = "MHTML" };
            Pdf = new ReportFormat { Code = ReportFormats.Pdf, Instruction = "PDF" };
            Xlsx = new ReportFormat { Code = ReportFormats.Xlsx, Instruction = "EXCELOPENXML" };
            Docx = new ReportFormat { Code = ReportFormats.Docx, Instruction = "WORDOPENXML" };
        }

        private ReportFormat() {
        }

        public ReportFormats Code { get; set; }
        public String Instruction { get; set; }

        public static ReportFormat Html { get; private set; }
        public static ReportFormat MHtml { get; private set; }
        public static ReportFormat Pdf { get; private set; }
        public static ReportFormat Xlsx { get; private set; }
        public static ReportFormat Docx { get; private set; }

        public static ReportFormat ByCode(ReportFormats code) {
            switch (code) {
                case ReportFormats.Html: return Html;
                case ReportFormats.MHtml: return Html; //<<======================
                case ReportFormats.Pdf: return Pdf;
                case ReportFormats.Xlsx: return Xlsx;
                case ReportFormats.Docx: return Docx;
                default : return null;
            }
        }
    }

    public class Report : IDisposable {
        private HttpWebRequest _httpWReq;
        private WebResponse _httpWResp;

        public Report() {
            _httpWReq = null;
            _httpWResp = null;
            Format = ReportFormats.Html;
            Params = new Dictionary<String, String>();
        }

        public Dictionary<String, String> Params { get; set; }

        public String ReportServerPath { get; set; }
        public String ReportPath { get; set; }
        public ReportFormats Format { get; set; }
        public NetworkCredential Credentials { get; set; }

        //public String PostData { get { return String.Format("rs:Command=Render&rs:Format={0}", ReportFormat.ByCode(Format).Instruction); } }
        public String PostData { get {
            StringBuilder sb = new StringBuilder(1024);
            sb.AppendFormat("rs:Command=Render&rs:Format={0}", ReportFormat.ByCode(Format).Instruction);
            if (Format == ReportFormats.Html) {
                sb.Append("&rc:Toolbar=false");
            }
            foreach (var kv in Params) {
                sb.AppendFormat("&{0}={1}", kv.Key, kv.Value);
            }

            return sb.ToString();
        } }

        public String ReportFullPath { get { return ReportServerPath + "?/" +  ReportPath; } }

        public Stream Render() {
            _httpWReq = (HttpWebRequest)HttpWebRequest.Create(ReportFullPath);
            _httpWReq.Method = "POST";
            if (Credentials != null)
                _httpWReq.Credentials = Credentials;

            byte[] byteArray = Encoding.UTF8.GetBytes(PostData);
            _httpWReq.ContentType = "application/x-www-form-urlencoded";
            _httpWReq.ContentLength = byteArray.Length;
            Stream dataStream = _httpWReq.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();

            if (_httpWResp != null )
                _httpWResp.Close();
                            _httpWResp = _httpWReq.GetResponse();               

            return _httpWResp.GetResponseStream();
        }

        public void RenderTo(String fileName) {            
            Stream receiveStream = Render();
            Stream ds = File.Open(fileName, FileMode.Create);
            receiveStream.CopyTo(ds);
            ds.Close();
            receiveStream.Close();            
        }

        public void Dispose() {
            if (_httpWResp != null) {
                _httpWResp.Close();
                _httpWResp = null;
            }

            if (_httpWReq != null) {
                _httpWReq = null;
            }
        }
    }
}