C# Winform - 如何通过将 3 个变量传递给 ReportViewer 来显示实时报告,即 Reportname(RDL 文件)、SQLstring 和 Connectionstring
C# Winform - How to display real time reports by passing 3 variables to ReportViewer namely Reportname(RDL file), SQLstring and Connectionstring
将 RDL 文件、SQL 和连接字符串传递到 Winform C# 项目上的 ReportViewer 控件以在 运行 时间显示报告的最优雅方法是什么。
简介:
- 我最近开始在 Windows 上创建报告。我发现
RDLC 文件充当静态文件,不需要连接
字符串或 SQL 语句,因此我们需要将 DataSource 传递给它
以便在 运行 时间用数据填充它。这不符合我们的
目的。
- RDL 文件但是可以采用 SQL 语句和连接字符串
它们保存在 XML 标签中,用于生成动态报告。
因为我有
- RDL 报告模板
- SQL 声明
- 到数据库的连接字符串
将此信息传递给 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 个数据发送到 ReportViewer
控件,它以不同的形式停靠并在 ReportViewer 上加载报告。
2) 我们的用户不与我们共享连接,因此我们不能在 RDL 文件中对其进行硬编码。 SQL 通常是一个常量,RDL 文件通常根据特定形式的需要设计一次。
3) 我们现在使用 MySQL 数据库。但是任何流行的 RDBMS 中的解决方案都会有很大帮助。我希望上面的查询很好地描述了正在访问的 table 的架构(查询包含 table 中的所有列)。
注意:请将答案包含在 RDL 文件中,而不是 RDLC 文件中。
什么终于解决了我的问题,除了@Reza Aghaei给出的答案
报告文件有数据源和数据集的标签,就在 RDL 文件的开头,如以下代码片段
<DataSets>
<DataSet Name="Data">
<Query>
<DataSourceName>DS1</DataSourceName>
来自@Reza Aghaei 的行,询问数据集的名称(数据)而不是数据源名称(DS1)。做出这种区分对于使报告文件正常工作至关重要。
var rds = new Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", this.ReportData);
将其更改为:
var rds = new Microsoft.Reporting.WinForms.ReportDataSource("Data", this.ReportData);
您可以像下面那样使用单个 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();
备注
ReportViewer 控件显示 RDLC 报告。 RDL 报告应托管在 SQL 服务器报告服务上。您似乎希望在客户端机器上而不是在 SSRS 上获得报告。如果是这种情况,您需要 RDLC 报告。尽管 RDL 和 RDLC 具有相同的 XML 架构,但从技术上讲,您似乎需要 RDLC。
你说RDL文件通常设计一次所以客户可以在他们的机器上有报告文件,你可以简单地通过它的地址将报告加载到报告视图中,甚至您可以将这些报告放在解决方案中并将它们作为资源嵌入。当你将它设置为嵌入资源时,你可以通过它的名称加载报告:
reportViewer1.LocalReport.ReportEmbeddedResource = "Sample.Reports.Report1.rdlc";
或按路径加载报告:
var path = System.IO.Path.Combine(Application.StartupPath, "Reports", "Report1.rdlc");
reportViewer1.LocalReport.ReportPath = path;
你说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
事实上sql命令可以是动态的,但它应该保持一个不变的结果模式。结果列名称不应更改,因为报表引擎使用查询列名称来显示报表字段中的数据。因此,您也可以将 Command
属性 创建为 User
设置。
关于但是在任何流行的 RDBMS 中的解决方案,最好使用依赖注入来注入为您加载数据的库。这样您就可以为不同的 DBMS 使用不同的 dll,并在需要时注入合适的 dll。
将 RDL 文件、SQL 和连接字符串传递到 Winform C# 项目上的 ReportViewer 控件以在 运行 时间显示报告的最优雅方法是什么。
简介:
- 我最近开始在 Windows 上创建报告。我发现 RDLC 文件充当静态文件,不需要连接 字符串或 SQL 语句,因此我们需要将 DataSource 传递给它 以便在 运行 时间用数据填充它。这不符合我们的 目的。
- RDL 文件但是可以采用 SQL 语句和连接字符串 它们保存在 XML 标签中,用于生成动态报告。
因为我有
- RDL 报告模板
- SQL 声明
- 到数据库的连接字符串
将此信息传递给 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 个数据发送到 ReportViewer
控件,它以不同的形式停靠并在 ReportViewer 上加载报告。
2) 我们的用户不与我们共享连接,因此我们不能在 RDL 文件中对其进行硬编码。 SQL 通常是一个常量,RDL 文件通常根据特定形式的需要设计一次。
3) 我们现在使用 MySQL 数据库。但是任何流行的 RDBMS 中的解决方案都会有很大帮助。我希望上面的查询很好地描述了正在访问的 table 的架构(查询包含 table 中的所有列)。
注意:请将答案包含在 RDL 文件中,而不是 RDLC 文件中。
什么终于解决了我的问题,除了@Reza Aghaei给出的答案
报告文件有数据源和数据集的标签,就在 RDL 文件的开头,如以下代码片段
<DataSets>
<DataSet Name="Data">
<Query>
<DataSourceName>DS1</DataSourceName>
来自@Reza Aghaei 的行,询问数据集的名称(数据)而不是数据源名称(DS1)。做出这种区分对于使报告文件正常工作至关重要。
var rds = new Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", this.ReportData);
将其更改为:
var rds = new Microsoft.Reporting.WinForms.ReportDataSource("Data", this.ReportData);
您可以像下面那样使用单个 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();
备注
ReportViewer 控件显示 RDLC 报告。 RDL 报告应托管在 SQL 服务器报告服务上。您似乎希望在客户端机器上而不是在 SSRS 上获得报告。如果是这种情况,您需要 RDLC 报告。尽管 RDL 和 RDLC 具有相同的 XML 架构,但从技术上讲,您似乎需要 RDLC。
你说RDL文件通常设计一次所以客户可以在他们的机器上有报告文件,你可以简单地通过它的地址将报告加载到报告视图中,甚至您可以将这些报告放在解决方案中并将它们作为资源嵌入。当你将它设置为嵌入资源时,你可以通过它的名称加载报告:
reportViewer1.LocalReport.ReportEmbeddedResource = "Sample.Reports.Report1.rdlc";
或按路径加载报告:
var path = System.IO.Path.Combine(Application.StartupPath, "Reports", "Report1.rdlc"); reportViewer1.LocalReport.ReportPath = path;
你说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
事实上sql命令可以是动态的,但它应该保持一个不变的结果模式。结果列名称不应更改,因为报表引擎使用查询列名称来显示报表字段中的数据。因此,您也可以将
Command
属性 创建为User
设置。关于但是在任何流行的 RDBMS 中的解决方案,最好使用依赖注入来注入为您加载数据的库。这样您就可以为不同的 DBMS 使用不同的 dll,并在需要时注入合适的 dll。