You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何手动绑定Report Viewer?通过代码实现数据库绑定及表名输入展示报表

Dynamic ReportViewer Binding Without Wizard (Table Name Input)

Got it, let's break down how to bind a ReportViewer to a database table dynamically—no wizard required. The goal is to let users type a table name into a TextBox, then load and display that table's data in the ReportViewer. I'll cover WinForms and ASP.NET Web Forms implementations since those are the most common use cases, with full code examples and key best practices.


WinForms Implementation

Step 1: Set Up Your Form

First, add these controls to your WinForm:

  • TextBox (name: txtTableName) for inputting the table name
  • Button (name: btnLoadReport) to trigger the report load
  • ReportViewer (name: reportViewer1) to display the data

Step 2: Add Required Namespaces

At the top of your form's code file, include these:

using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Configuration;
using Microsoft.Reporting.WinForms;

Step 3: Configure Database Connection

Add your connection string to App.config:

<connectionStrings>
  <add name="MyDbConnection" 
       connectionString="Data Source=YOUR_SERVER_NAME;Initial Catalog=YOUR_DATABASE_NAME;Integrated Security=True;" 
       providerName="System.Data.SqlClient" />
</connectionStrings>

Replace YOUR_SERVER_NAME and YOUR_DATABASE_NAME with your actual database details.

Step 4: Full Form Code

Here's the complete code to handle dynamic data loading and report generation:

public partial class DynamicReportForm : Form
{
    private readonly string _connectionString = ConfigurationManager.ConnectionStrings["MyDbConnection"].ConnectionString;

    public DynamicReportForm()
    {
        InitializeComponent();
        // Initialize ReportViewer to use local processing
        reportViewer1.ProcessingMode = ProcessingMode.Local;
    }

    private void btnLoadReport_Click(object sender, EventArgs e)
    {
        string tableName = txtTableName.Text.Trim();
        if (string.IsNullOrEmpty(tableName))
        {
            MessageBox.Show("Please enter a table name!", "Input Required", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }

        try
        {
            // Validate the table exists first (prevents SQL injection and invalid inputs)
            if (!TableExists(tableName))
            {
                MessageBox.Show("Table does not exist in the database!", "Invalid Table", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Fetch data from the specified table
            DataTable tableData = GetTableData(tableName);

            // Generate a dynamic RDLC report definition
            string rdlcContent = GenerateDynamicRdlc(tableData);

            // Load the RDLC into ReportViewer
            reportViewer1.LocalReport.LoadReportDefinition(new StringReader(rdlcContent));

            // Bind the data to the report
            ReportDataSource dataSource = new ReportDataSource("DataSet1", tableData);
            reportViewer1.LocalReport.DataSources.Clear();
            reportViewer1.LocalReport.DataSources.Add(dataSource);

            // Refresh the report to display data
            reportViewer1.RefreshReport();
        }
        catch (Exception ex)
        {
            MessageBox.Show($"Error loading report: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    // Check if the table exists in the database
    private bool TableExists(string tableName)
    {
        using (SqlConnection conn = new SqlConnection(_connectionString))
        {
            string query = "SELECT COUNT(*) FROM sys.tables WHERE name = @TableName";
            SqlCommand cmd = new SqlCommand(query, conn);
            cmd.Parameters.AddWithValue("@TableName", tableName);
            conn.Open();
            int count = (int)cmd.ExecuteScalar();
            return count > 0;
        }
    }

    // Fetch all data from the specified table
    private DataTable GetTableData(string tableName)
    {
        DataTable dt = new DataTable(tableName);
        using (SqlConnection conn = new SqlConnection(_connectionString))
        {
            // Use square brackets to handle table names with spaces/special characters
            string query = $"SELECT * FROM [{tableName}]";
            SqlDataAdapter adapter = new SqlDataAdapter(query, conn);
            adapter.Fill(dt);
        }
        return dt;
    }

    // Generate a dynamic RDLC report with columns matching the table
    private string GenerateDynamicRdlc(DataTable dt)
    {
        // Build the RDLC XML structure
        string rdlc = $@"<?xml version=""1.0"" encoding=""utf-8""?>
<Report xmlns=""http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition"" xmlns:rd=""http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"">
  <DataSources>
    <DataSource Name=""DataSet1"">
      <ConnectionProperties>
        <DataProvider>SQL</DataProvider>
        <ConnectString/>
      </ConnectionProperties>
      <rd:DataSourceID>00000000-0000-0000-0000-000000000000</rd:DataSourceID>
    </DataSource>
  </DataSources>
  <DataSets>
    <DataSet Name=""DataSet1"">
      <Query>
        <DataSourceName>DataSet1</DataSourceName>
        <CommandText>SELECT * FROM [{dt.TableName}]</CommandText>
      </Query>
      <Fields>";

        // Add fields for each column in the table
        foreach (DataColumn col in dt.Columns)
        {
            rdlc += $@"
        <Field Name=""{col.ColumnName}"">
          <DataField>{col.ColumnName}</DataField>
          <rd:TypeName>{MapDataType(col.DataType)}</rd:TypeName>
        </Field>";
        }

        rdlc += @"
      </Fields>
    </DataSet>
  </DataSets>
  <Body>
    <ReportItems>
      <Tablix Name=""Table1"">
        <TablixBody>
          <TablixColumns>";

        // Add columns to the table
        foreach (DataColumn col in dt.Columns)
        {
            rdlc += $@"
            <TablixColumn>
              <Width>1.5in</Width>
            </TablixColumn>";
        }

        rdlc += @"
          </TablixColumns>
          <TablixRows>
            <!-- Header Row -->
            <TablixRow>
              <Height>0.25in</Height>
              <TablixCells>";

        // Add header cells
        foreach (DataColumn col in dt.Columns)
        {
            rdlc += $@"
                <TablixCell>
                  <CellContents>
                    <Textbox Name=""{col.ColumnName}_Header"">
                      <Paragraphs>
                        <Paragraph>
                          <TextRuns>
                            <TextRun>
                              <Value>{col.ColumnName}</Value>
                              <Style><FontWeight>Bold</FontWeight></Style>
                            </TextRun>
                          </TextRuns>
                        </Paragraph>
                      </Paragraphs>
                      <Style><Border><Style>Solid</Style><Color>LightGray</Color></Border><Padding>2pt</Padding></Style>
                    </Textbox>
                  </CellContents>
                </TablixCell>";
        }

        rdlc += @"
              </TablixCells>
            </TablixRow>
            <!-- Data Row -->
            <TablixRow>
              <Height>0.25in</Height>
              <TablixCells>";

        // Add data cells
        foreach (DataColumn col in dt.Columns)
        {
            rdlc += $@"
                <TablixCell>
                  <CellContents>
                    <Textbox Name=""{col.ColumnName}"">
                      <Paragraphs>
                        <Paragraph>
                          <TextRuns>
                            <TextRun>
                              <Value>=Fields!{col.ColumnName}.Value</Value>
                            </TextRun>
                          </TextRuns>
                        </Paragraph>
                      </Paragraphs>
                      <Style><Border><Style>Solid</Style><Color>LightGray</Color></Border><Padding>2pt</Padding></Style>
                    </Textbox>
                  </CellContents>
                </TablixCell>";
        }

        rdlc += @"
              </TablixCells>
            </TablixRow>
          </TablixRows>
        </TablixBody>
        <TablixColumnHierarchy>
          <TablixMembers>";

        foreach (DataColumn col in dt.Columns)
        {
            rdlc += $@"
            <TablixMember>
              <KeepWithGroup>After</KeepWithGroup>
            </TablixMember>";
        }

        rdlc += @"
          </TablixMembers>
        </TablixColumnHierarchy>
        <TablixRowHierarchy>
          <TablixMembers>
            <TablixMember>
              <Group Name=""HeaderGroup"" />
              <TablixHeader>
                <Size>0.3in</Size>
                <CellContents>
                  <Textbox Name=""ReportTitle"">
                    <Paragraphs>
                      <Paragraph>
                        <TextRuns>
                          <TextRun>
                            <Value>{dt.TableName} Data</Value>
                            <Style><FontSize>14pt</FontSize><FontWeight>Bold</FontWeight></Style>
                          </TextRun>
                        </TextRuns>
                      </Paragraph>
                    </Paragraphs>
                  </Textbox>
                </CellContents>
              </TablixHeader>
            </TablixMember>
            <TablixMember>
              <Group Name=""DetailsGroup"">
                <GroupExpressions></GroupExpressions>
              </Group>
            </TablixMember>
          </TablixMembers>
        </TablixRowHierarchy>
        <Top>0.25in</Top>
        <Left>0.25in</Left>
        <Width>" + (dt.Columns.Count * 1.5) + @"in</Width>
      </Tablix>
    </ReportItems>
    <Height>" + (dt.Rows.Count > 0 ? 0.5 + (dt.Rows.Count * 0.25) : 1) + @"in</Height>
  </Body>
  <Width>" + (dt.Columns.Count * 1.5 + 0.5) + @"in</Width>
  <Page>
    <PageHeight>8.5in</PageHeight>
    <PageWidth>11in</PageWidth>
    <Margins>
      <Left>0.5in</Left>
      <Right>0.5in</Right>
      <Top>0.5in</Top>
      <Bottom>0.5in</Bottom>
    </Margins>
  </Page>
</Report>";

        return rdlc;
    }

    // Map .NET data types to RDLC-compatible types
    private string MapDataType(Type dataType)
    {
        if (dataType == typeof(int)) return "System.Int32";
        if (dataType == typeof(string)) return "System.String";
        if (dataType == typeof(DateTime)) return "System.DateTime";
        if (dataType == typeof(decimal)) return "System.Decimal";
        if (dataType == typeof(bool)) return "System.Boolean";
        // Add more mappings as needed for your database types
        return "System.String";
    }
}

ASP.NET Web Forms Implementation

Step 1: Set Up Your Page

Add this markup to your ASPX page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DynamicReport.aspx.cs" Inherits="YourProjectNamespace.DynamicReport" %>
<%@ Register Assembly="Microsoft.ReportViewer.WebForms" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Dynamic Table Report</title>
</head>
<body>
    <form id="form1" runat="server">
        <div style="margin: 20px;">
            <asp:TextBox ID="txtTableName" runat="server" placeholder="Enter table name" style="padding: 8px; width: 250px;"></asp:TextBox>
            <asp:Button ID="btnLoadReport" runat="server" Text="Load Report" OnClick="btnLoadReport_Click" style="padding: 8px 16px; margin-left: 10px;" />
            <hr />
            <rsweb:ReportViewer ID="ReportViewer1" runat="server" Width="100%" Height="600px" />
        </div>
    </form>
</body>
</html>

Step 2: Backend Code

Most of the logic is similar to WinForms—here's the code-behind:

using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Web.Configuration;
using Microsoft.Reporting.WebForms;

namespace YourProjectNamespace
{
    public partial class DynamicReport : System.Web.UI.Page
    {
        private readonly string _connectionString = WebConfigurationManager.ConnectionStrings["MyDbConnection"].ConnectionString;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ReportViewer1.ProcessingMode = ProcessingMode.Local;
            }
        }

        protected void btnLoadReport_Click(object sender, EventArgs e)
        {
            string tableName = txtTableName.Text.Trim();
            if (string.IsNullOrEmpty(tableName))
            {
                ShowAlert("Please enter a table name!");
                return;
            }

            try
            {
                if (!TableExists(tableName))
                {
                    ShowAlert("Table does not exist in the database!");
                    return;
                }

                DataTable tableData = GetTableData(tableName);
                string rdlcContent = GenerateDynamicRdlc(tableData);

                ReportViewer1.LocalReport.LoadReportDefinition(new StringReader(rdlcContent));
                ReportDataSource dataSource = new ReportDataSource("DataSet1", tableData);
                ReportViewer1.LocalReport.DataSources.Clear();
                ReportViewer1.LocalReport.DataSources.Add(dataSource);
                ReportViewer1.LocalReport.Refresh();
            }
            catch (Exception ex)
            {
                ShowAlert($"Error loading report: {ex.Message}");
            }
        }

        private void ShowAlert(string message)
        {
            ClientScript.RegisterStartupScript(GetType(), "alert", $"alert('{message.Replace("'", "\\'")}');", true);
        }

        // Reuse the helper methods from the WinForms code
        private bool TableExists(string tableName)
        {
            // Same as WinForms implementation
        }

        private DataTable GetTableData(string tableName)
        {
            // Same as WinForms implementation
        }

        private string GenerateDynamicRdlc(DataTable dt)
        {
            // Same as WinForms implementation
        }

        private string MapDataType(Type dataType)
        {
            // Same as WinForms implementation
        }
    }
}

Key Notes & Best Practices

  • Security First: Always validate the table name exists before executing queries (we do this with the TableExists method) to prevent SQL injection. Never trust raw user input directly in queries.
  • Database Permissions: Use a database user with only read access to the tables users should be able to view—minimize permissions to reduce risk.
  • Data Type Mapping: Extend the MapDataType method if you use less common data types (like float, byte[], etc.) in your tables.
  • Error Handling: Add more specific error handling based on your needs (e.g., handle connection failures separately from invalid table names).

内容的提问来源于stack exchange,提问作者Chrollo Lucifer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:54:32