小编典典

C#Winform-如何通过将3个变量传递到ReportViewer来显示实时报告,即Reportname(RDL文件),SQLstring和Connectionstring

sql

将RDL文件,SQL和连接字符串传递到Winform C#项目上的ReportViewer控件以在运行时显示报表的最优雅的方法是什么。

介绍:

  • 我最近开始在Windows上创建报表。我发现RDLC文件充当静态文件,不需要连接字符串或SQL语句,因此我们需要将DataSource传递给它,以便在运行时用数据填充它。这不符合我们的目的。
  • 但是,RDL文件可以采用保存在XML标记中的SQL语句和连接字符串,并用于生成动态报告。

鉴于我有

  1. RDL报告模板
  2. SQL语句
  3. 与数据库的连接字符串

将信息传递到C#Winform中的ReportViewer生成报表的最佳方法是什么?

1)对于用于图书馆管理系统的RDL。(我们无法控制这些文件,这些文件由我们的应用程序的用户使用)。

  <Query>
    <DataSourceName>DS1</DataSourceName>
    <CommandText>select bk_book_details.id, bk_book_details.book_id, bk_book_details.book_no, bk_book_details.book_name, bk_book_details.edition_id, bk_book_details.condition_id, bk_book_details.publication_year, bk_book_details.price, bk_book_details.purchase_price, bk_book_details.reference_no, bk_book_details.book_status, bk_book_details.purchase_id, bk_book_details.purchase_date from bk_book_details</CommandText>
  </Query>

2)这是SQL语句

select bk_book_details.id, bk_book_details.book_id, bk_book_details.book_no, bk_book_details.book_name, bk_book_details.edition_id, bk_book_details.condition_id, bk_book_details.publication_year, bk_book_details.price, bk_book_details.purchase_price, bk_book_details.reference_no, bk_book_details.book_status, bk_book_details.purchase_id, bk_book_details.purchase_date from bk_book_details

3)这是连接字符串

server=localhost;User Id=root;password=root;Persist Security Info=True;database=lms

当前输出: 如在RDLReader.exe应用程序上看到的

用于获取此输出的代码

    private void btnReport_Click(object sender, EventArgs e) {
        string sql = "select bk_book_details.id, bk_book_details.book_id, bk_book_details.book_no, bk_book_details.book_name, bk_book_details.edition_id, bk_book_details.condition_id, bk_book_details.publication_year, bk_book_details.price, bk_book_details.purchase_price, bk_book_details.reference_no, bk_book_details.book_status, bk_book_details.purchase_id, bk_book_details.purchase_date from bk_book_details";
        string RDLReaderApplication = @"""""""" + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @""\ReaderPath\RDLReader.exe"" + @"""""""";
        string reportFile = @"""""""" + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @""\Reports\ReportFile.RDL"" + @"""""""";
        string connectionString = @"""""""" + "server=localhost;User Id=root;password=root;Persist Security Info=True;database=lms" + @"""""""";
        Process.Start(RDLReaderApplication, reportFile + "" "" + @"""""""" + sql + @"""""""" + "" "" + connectionString);
    }

预期产量:

在此处输入图片说明

到目前为止的工作:

表单ReportForm包含ReportViewer停靠在表单上的控件。

附加信息:

1)我希望将这3个数据发送到ReportViewerControl,以不同的形式停靠,然后将报告加载到ReportViewer上。

2)我们的用户不与我们共享连接,因此我们无法在RDL文件中对其进行硬编码。SQL通常是一个常数,并且RDL文件通常根据特定格式的需要设计一次。

3)我们现在使用MySQL数据库。但是任何流行的RDBMS中的解决方案都会有很大帮助。我希望上面的查询能很好地描述正在访问的表的架构(查询包含表中的所有列)。

注意:请在RDL文件而不是RDLC文件中包括答案。

除了@Reza Aghaei给出的答案外,最终为我解决了什么问题

报表文件在RDL文件的开头就具有用于数据源和数据集的标签,如以下代码段所示

  <DataSets>
    <DataSet Name="Data">
      <Query>
        <DataSourceName>DS1</DataSourceName>

来自@Reza
Aghaei的行,要求提供数据集(Data)的名称,而不是DataSourceName(DS1)的名称。区分这一点对于使报告文件正常工作至关重要。

var rds = new Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", this.ReportData);

更改为:

var rds = new Microsoft.Reporting.WinForms.ReportDataSource("Data", this.ReportData);

阅读 290

收藏
2021-04-14

共1个答案

小编典典

您可以使用ReportForm下面的单个符号,并将数据和报告名称传递给它。报告表单应包含一个ReportViewer控件和以下代码:

public partial class ReportForm : Form
{
    public ReportForm()
    {
        InitializeComponent();
        this.Load+=new EventHandler(ReportForm_Load);
    }

    public Object ReportData { get; set; }
    public string ReportName { get; set; }

    private void ReportForm_Load(object sender, EventArgs e)
    {
        var rds = new Microsoft.Reporting.WinForms.ReportDataSource("DataSet1",
            this.ReportData);
        this.reportViewer1.LocalReport.DataSources.Clear();
        this.reportViewer1.LocalReport.DataSources.Add(rds);         
        var path = System.IO.Path.Combine(Application.StartupPath, 
            "Reports", this.ReportName);
        reportViewer1.LocalReport.ReportPath = path;
        this.reportViewer1.RefreshReport();
    }
}

用法

您可以使用ReportForm这种方式:

var f = new ReportForm();
DataTable table = new DataTable(); 
var command = Properties.Settings.Default.Command;        /*SELECT Statement*/
var connection = Properties.Settings.Default.Connection;  /*Connection String*/
using (var adapter = new SqlDataAdapter(command, connection))
    adapter.Fill(table)
f.ReportName = "Report1.rdlc" /*Or any other name*/
f.ReportData = table;
f.ShowDialog();

笔记

  1. ReportViewer控件显示RDLC报告。RDL报表应托管在SQL Server报表服务上。看来您想在客户端计算机上而不是在SSRS上获得报告。如果是这种情况,则需要RDLC报告。尽管RDL和RDLC具有相同的XML模式,但是从技术上讲,您似乎需要RDLC。

  2. 您说过, RDL文件通常是设计一次的, 因此客户可以在其计算机上拥有报告文件,并且您可以仅按报告的地址将报告加载到报告视图中,甚至可以将这些报告放入解决方案中并将其嵌入为资源。将报表设置为嵌入式资源时,可以按其名称加载报表:

    reportViewer1.LocalReport.ReportEmbeddedResource = "Sample.Reports.Report1.rdlc";
    

或按路径加载报告:

    var path = System.IO.Path.Combine(Application.StartupPath, "Reports", "Report1.rdlc");
reportViewer1.LocalReport.ReportPath = path;
  1. 您说过 ,SQL通常是一个常量。 并且 我们的用户不与我们共享连接, 因此您可以使用Settings.settings并添加2个属性(Command应用程序范围Connection和用户范围)。因此,您可以让用户在运行时更改连接字符串,然后以这种方式加载数据并将数据传递给您ReportForm

    DataTable table = new DataTable();
    

    var command = Properties.Settings.Default.Command;
    var connection = Properties.Settings.Default.Connection;
    using (var adapter = new SqlDataAdapter(command, connection))
    adapter.Fill(table)
    //Pass table to ReportForm

  2. 实际上,sql命令可以是动态的,但它应保持恒定的结果模式。结果列名称不应更改,因为报表引擎使用查询列名称在报表字段中显示数据。因此,您也可以将Command属性创建为User设置。

  3. 关于 But但是,在任何流行的RDBMS中都是一种解决方案, 最好使用依赖项注入来注入可以为您加载数据的库。这样,您可以为不同的DBMS使用不同的dll,并在需要时注入合适的dll。

2021-04-14