【问题标题】:How to change the database in an SSRS report at run-time如何在运行时更改 SSRS 报告中的数据库
【发布时间】:2017-12-20 10:55:20
【问题描述】:

我正在尝试生成一个 c# 程序来在多个相同数据库中的任何一个上运行 SSRS 报告,目标数据库将在运行时指定。为此,我创建了一个解决方案和项目,并在该项目中包含一个 SSRS 报告。此报告有一个数据集LegislationData,它调用样本数据库中的存储过程。

我现在正试图让它在 C# 项目中运行。我创建了一个带有报表查看器和执行按钮的表单,并尝试设置报表。我设想了一些代码如下:-

MyReport my_report = new MyReport();

my_report.ConnectionString = "blah blah";               // or
my_report.DataSet.ConnectionString = "blah blah";       // or
my_report.LegislationData.ConnectionString = "blah blah"

然后

report_viewer.Report = my_report;        // or
report_viewer.LocalReport = my_report;   // or
report_viewer.SetReport(my_report);

但这些东西实际上都不存在。

有人可以非常缓慢地用一个音节向我解释我需要在这里做什么吗?我查看了herehere 类似问题的答案,但坦率地说,这些答案毫无意义。

【问题讨论】:

    标签: c# sql-server reporting-services


    【解决方案1】:

    您需要意识到的第一件事是必须将 SSRS 作为 Web 参考添加到您的 C# 应用程序中。这里有一个关于如何做到这一点的指南:https://msdn.microsoft.com/en-gb/library/ms169926.aspx。基本上听起来比实际更糟糕,配置所有这些应该只需要几分钟。我发现 MSDN 链接对我来说已损坏,所以这里是另一个讨论如何执行此操作的地方:https://sqluninterrupted.com/2012/03/04/adding-a-reporting-services-web-reference-to-net-application/

    从 C# 应用程序运行报表后,您需要决定要对输出做什么、将其转换为 PDF、将其流式传输到屏幕、将其保存为 Excel 等。

    我以前没有这样做过,但看起来您可以将数据源嵌入到使用基于参数的表达式的报表中。因此,您将传入一个参数来运行作为连接字符串的报告。您还需要传入报告中可能包含的任何其他参数。

    所以第 1 步添加 SSRS 的网络参考。

    第 2 步添加一些代码来运行您的报告,例如这是一个将报告作为 PDF 格式的字节数组返回的示例:

    public byte[] RenderReport(ReportExecutionService rs, string reportName, int variant)
    {
        Console.WriteLine("Rendering " + reportName + "_" + variant.ToString("00"));
    
        byte[] result = null;
        string reportPath = "/Prototypes/Inheritance Letters/" + reportName;
        const string format = "PDF";
        const string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
    
        //Prepare report parameters
        var parameters = new ParameterValue[2];
        parameters[0] = new ParameterValue { Name = "row_id", Value = variant.ToString() };
        parameters[1] = new ParameterValue { Name = "bulk_run", Value = "1" };
        rs.ExecutionHeaderValue = new ExecutionHeader();
        rs.LoadReport(reportPath, null);
        rs.SetExecutionParameters(parameters, "en-gb");
        try
        {
            string encoding;
            string mimeType;
            string extension;
            Warning[] warnings;
            string[] streamIDs;
            result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
            rs.GetExecutionInfo();
            return result;
        }
        catch (SoapException e)
        {
            Console.WriteLine(e.Detail.OuterXml);
            return null;
        }
    }
    

    第 3 步将连接字符串作为参数之一传递,并使用报表中嵌入数据源中的表达式来获取并使用它。

    第 4 步决定如何处理渲染的输出。例如,这里我呈现一个报告,然后将输出保存为 PDF:

            byte[] result = new Render().RenderReport(rs, "ACQ_Welcome_Letter", i);
            new Render().CreatePDF(i, "Welcome Letter", "ACQ_Welcome_Letter" + "_" + fuelType, result);
    

    这里是 CreatePDF 方法,对于我的特定解决方案,它还有很多其他垃圾,但它让您体验了如何做到这一点:

    public string CreatePDF(int variant, string subFolder, string reportName, byte[] result)
    {
        //We want 16 variants, but we pass in a number from 1 to 48, so use modulo division to convert this back to a 1 to 16 range
        variant = (variant - 1) % 16 + 1;
        Console.WriteLine("Saving " + reportName + "_Variant_" + variant.ToString("00") + ".pdf");
        try
        {
            //Determine the target folder/ filename for the PDF
            //Snail Mail has its own folder, all PDFs go into that folder and then are manually processed
            string folder = @"S:\Change Management Documents\SMETS1\Inheritance Comms\" + subFolder + @"\";
            string filename = reportName + "_Variant_" + variant.ToString("00") + ".pdf";
    
            //Remove any existing content
            string[] filePaths = Directory.GetFiles(folder, filename);
            foreach (string filePath in filePaths)
                File.Delete(filePath);
    
            //Now save the PDF
            string path = folder + @"\" + filename;
            FileStream stream = File.Create(path, result.Length);
            stream.Write(result, 0, result.Length);
            stream.Close();
            return filename;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return "";
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-09
      • 1970-01-01
      • 1970-01-01
      • 2011-10-09
      • 1970-01-01
      相关资源
      最近更新 更多