Создание отчета RDLC динамически во время выполнения из DataGridView
У меня есть форма AdvancedSearchForm с DataGridView control dgrData и кнопка Report В C# Winform. При нажатии на кнопку Report, я хочу, чтобы форма с ReportView управления будет отображаться с теми же столбцами, как в DataGridView с теми же заголовками столбцов.
Форма с DataGridView и кнопкой
Ожидаемый результат при нажатии кнопки "отчет":
Мой DatagridView (dgrData) контроль связан с
- SQL
“Select Id, c_Name from Country”
- ConnectionString
server=localhost;User Id=root;password=root;Persist Security Info=True;database=country_state
Чтобы загрузить данные в сетку во время выполнения, я готовлю следующий DataAdapter :
DataAdapter dataAdapter = DataAdapter.Current;
// I am passing the SQL statement and the table name to my database which knows the ConnectionString within the LoadData function
DataTable dt0 = dataAdapter.LoadData("select Id, c_Name from `country`", "country");
if (dt0 != null) {
dgrData.DataSource = dt0;
}
Можно ли вызвать дочернюю форму, содержащую элемент управления default reportviewer , который показывает отчет с таблицей, содержащей столбцы, соответствующие datagridview (dgrData) вместе с данными динамически во время выполнения?
Ожидание выхода подробно:
- по нажатию кнопки, reportviewer на целевой форме должен получить
связанный с источником данных из значений в
DataGridView . Таким образом, элемент управления ReportViewer ничего не знает о данных в отчете, пока пользователь не нажмет на отчет
Кнопка во время выполнения. - я желаю, чтобы решение не требовало создания отдельного RDLC
файл, потому что это вызывает внешнюю зависимость, чтобы остановить текущий поток
и создайте файл отчета в конструкторе файлов отчетов, который может быть
чрезмерное внимание к пользователям. - я ничего не знаю о конструкторе RDLC и ассоциирующем источнике данных (я
готов учиться ( ^ _ ^ ), но я не могу навязать это требование обучения
в моей команде) и привязка данных к отчету. Я был бы признателен
рабочие примеры кодирования, если ваша помощь содержит теорию. - я знаю, что элемент был вокруг в течение довольно долгое время сейчас. Желание
тот пример решения для 1-1 сопоставления данных между data-grid и
Элемент был легче найти кого-то в будущем так.
Примечание: пожалуйста, дайте мне знать, если какие-либо дополнительные данные требуются с моей стороны в комментариях. Чтобы показать текущее решение, мне пришлось создать файл RDLC, в который я должен был поместить строку подключения и SQL во время разработки, чего я хочу избежать в решении, которое я ищу. Я хочу найти решение, где создается файл RDLC через некоторый модульный код, который можно использовать и на других решениях, а не разрабатывать его для каждой формы, где у меня есть DataGrids.
1 ответ:
В качестве опции для динамического создания отчета
RDLCво время выполнения можно использовать текстовые Шаблоны во время выполнения.В приведенном ниже примере я создал простой сеточный отчет, который можно использовать для динамического создания отчета во время выполнения. Вы можете динамически добавлять столбцы в отчет и задавать заголовок, ширину, цвет заголовка для столбца.
В примере я заполнил шаблон, используя
DataGridView. Но вы можете использовать эту технику в зависимости от любого вида контралола или даже использовать ее в веб-форма.Пример использования-создание и отображение динамического отчета
Для создания и отображения динамического отчета достаточно добавить несколько столбцов в
ReportForm, а затем задать данные и показать форму.var f = new ReportForm(); f.ReportColumns = this.dataGridView1.Columns.Cast<DataGridViewColumn>() .Select(x => new ReportColumn(x.DataPropertyName) { Title = x.HeaderText, Width = x.Width }).ToList(); f.ReportData = this.dataGridView1.DataSource; f.ShowDialog();Путь к решению
Достаточно добавить
ReportColumnиDynamicReport.ttиReportFormв приложение или даже в многократно используемую библиотеку один раз, а затем просто использовать, как в приведенном выше примере. Для создания динамического отчета выполните следующие действия шаблон.Модель Столбца Отчета
Создайте модель столбца отчета, содержащую свойства заголовка, выражения, цвета и т. д. Мы будем использовать это для добавления столбцов в отчет.
using System; using System.Drawing; public class ReportColumn { public ReportColumn(string name) { Name = name; Title = name; Type = typeof(System.String); Width = GetPixelFromInch(1); Expression = string.Format("=Fields!{0}.Value", name); HeaderBackColor = Color.LightGray; } public string Name { get; set; } public string Title { get; set; } public Type Type { get; set; } public int Width { get; set; } public float WidthInInch { get { return GetInchFromPixel(Width); } } public string Expression { get; set; } public Color HeaderBackColor { get; set; } public string HeaderBackColorInHtml { get { return ColorTranslator.ToHtml(HeaderBackColor); } } private int GetPixelFromInch(float inch) { using (var g = Graphics.FromHwnd(IntPtr.Zero)) return (int)(g.DpiY * inch); } private float GetInchFromPixel(int pixel) { using (var g = Graphics.FromHwnd(IntPtr.Zero)) return (float)pixel / g.DpiY; } }Шаблон Отчета
Добавьте шаблон времени выполнения (также известный как шаблон предварительной обработки) в проект и назовите его
DynamicReport.ttи скопируйте это содержимое в файл:<#@ template language="C#" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Collections.Generic" #> <#@ parameter name="Model" type="System.Collections.Generic.List<ReportColumn>"#> <?xml version="1.0" encoding="utf-8"?> <Report xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition"> <DataSources> <DataSource Name="DataSource1"> <ConnectionProperties> <DataProvider>System.Data.DataSet</DataProvider> <ConnectString>/* Local Connection */</ConnectString> </ConnectionProperties> <rd:DataSourceID>e9784bb0-a630-49cc-b7f9-8495aca23a6c</rd:DataSourceID> </DataSource> </DataSources> <DataSets> <DataSet Name="DataSet1"> <Fields> <# foreach(ReportColumn column in Model){#> <Field Name="<#=column.Name#>"> <DataField><#=column.Name#></DataField> <rd:TypeName><#=column.Type.Name#></rd:TypeName> </Field> <# }#> </Fields> <Query> <DataSourceName>DataSource1</DataSourceName> <CommandText>/* Local Query */</CommandText> </Query> <rd:DataSetInfo> <rd:DataSetName /> <rd:TableName /> <rd:ObjectDataSourceType /> </rd:DataSetInfo> </DataSet> </DataSets> <Body> <ReportItems> <Tablix Name="Tablix1"> <TablixBody> <TablixColumns> <# foreach(ReportColumn column in Model){#> <TablixColumn> <Width><#=column.WidthInInch#>in</Width> </TablixColumn> <# }#> </TablixColumns> <TablixRows> <TablixRow> <Height>0.25in</Height> <TablixCells> <# foreach(ReportColumn column in Model){#> <TablixCell> <CellContents> <Textbox Name="<#=column.Name#>TextBox"> <CanGrow>true</CanGrow> <KeepTogether>true</KeepTogether> <Paragraphs> <Paragraph> <TextRuns> <TextRun> <Value><#=column.Title#></Value> <Style /> </TextRun> </TextRuns> <Style /> </Paragraph> </Paragraphs> <rd:DefaultName><#=column.Name#>TextBox</rd:DefaultName> <Style> <Border> <Color>LightGrey</Color> <Style>Solid</Style> </Border> <BackgroundColor><#=column.HeaderBackColorInHtml#></BackgroundColor> <PaddingLeft>2pt</PaddingLeft> <PaddingRight>2pt</PaddingRight> <PaddingTop>2pt</PaddingTop> <PaddingBottom>2pt</PaddingBottom> </Style> </Textbox> </CellContents> </TablixCell> <# }#> </TablixCells> </TablixRow> <TablixRow> <Height>0.25in</Height> <TablixCells> <# foreach(ReportColumn column in Model){#> <TablixCell> <CellContents> <Textbox Name="<#=column.Name#>"> <CanGrow>true</CanGrow> <KeepTogether>true</KeepTogether> <Paragraphs> <Paragraph> <TextRuns> <TextRun> <Value><#=column.Expression#></Value> <Style /> </TextRun> </TextRuns> <Style /> </Paragraph> </Paragraphs> <rd:DefaultName><#=column.Name#></rd:DefaultName> <Style> <Border> <Color>LightGrey</Color> <Style>Solid</Style> </Border> <PaddingLeft>2pt</PaddingLeft> <PaddingRight>2pt</PaddingRight> <PaddingTop>2pt</PaddingTop> <PaddingBottom>2pt</PaddingBottom> </Style> </Textbox> </CellContents> </TablixCell> <# }#> </TablixCells> </TablixRow> </TablixRows> </TablixBody> <TablixColumnHierarchy> <TablixMembers> <# foreach(ReportColumn column in Model){#> <TablixMember /> <# }#> </TablixMembers> </TablixColumnHierarchy> <TablixRowHierarchy> <TablixMembers> <TablixMember> <KeepWithGroup>After</KeepWithGroup> </TablixMember> <TablixMember> <Group Name="Details" /> </TablixMember> </TablixMembers> </TablixRowHierarchy> <DataSetName>DataSet1</DataSetName> <Top>0.15625in</Top> <Left>0.125in</Left> <Height>0.5in</Height> <Width>2in</Width> <Style> <Border> <Style>None</Style> </Border> </Style> </Tablix> </ReportItems> <Height>0.82292in</Height> <Style /> </Body> <Width>6.5in</Width> <Page> <LeftMargin>1in</LeftMargin> <RightMargin>1in</RightMargin> <TopMargin>1in</TopMargin> <BottomMargin>1in</BottomMargin> <Style /> </Page> <rd:ReportID>60987c40-62b1-463b-b670-f3fa81914e33</rd:ReportID> <rd:ReportUnitType>Inch</rd:ReportUnitType> </Report>Форма Отчета
Добавляем
Formк проекту и добавитьReportViewerуправление формой и поместить этот код в класс:public partial class ReportForm : Form { public ReportForm() { InitializeComponent(); ReportColumns = new List<ReportColumn>(); this.Load+=new EventHandler(ReportForm_Load); } public List<ReportColumn> ReportColumns { get; set; } public Object ReportData { get; set; } private void ReportForm_Load(object sender, EventArgs e) { var report = new DynamicReport(); report.Session = new Dictionary<string, object>(); report.Session["Model"] = this.ReportColumns; report.Initialize(); var rds = new Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", this.ReportData); this.reportViewer1.LocalReport.DataSources.Clear(); this.reportViewer1.LocalReport.DataSources.Add(rds); var reportContent = System.Text.Encoding.UTF8.GetBytes(report.TransformText()); using (var stream = new System.IO.MemoryStream(reportContent)) { this.reportViewer1.LocalReport.LoadReportDefinition(stream); } this.reportViewer1.RefreshReport(); } }Примечание
Вы можете просто расширить модель
ReportColumn, а такжеDynamicReport.tt. Я создал шаблон, используя выходящий отчет, я просто использовал некоторые теги кода t4, чтобы сделать его динамичным.Пример
Вы можете клонировать или загрузить рабочий пример:



Comments