如何在运行时更改SSRS报告中的数据库

时间:2017-12-20 10:55:20

标签: c# sql-server reporting-services

我正在尝试生成一个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的答案,但坦率地说答案毫无意义。

1 个答案:

答案 0 :(得分: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的Web引用。

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