如何从 C# 动态分配 telerik 报告中的数据?
How to assign data in telerik report dynamically from c#?
我使用设计器设计了报告 trdp 文件,并添加了 Web 服务作为数据源。
我的计划是,当请求报告而不是 Web 源时,我想使用 linq 提取数据并将该数据注入报告数据源并希望通过报告处理器传递它。
我所做的是:
``
var rng = new Random();
var datas = Enumerable.Range(1, 100).Select(index => new WeatherForecast
{
Category = Summaries[rng.Next(Summaries.Length)],
Date = DateTime.Now.AddDays(index),
TemperatureC = 1
}).ToList();
DataTable dataTable = Newtonsoft.Json.JsonConvert.DeserializeObject<DataTable>(Newtonsoft.Json.JsonConvert.SerializeObject(datas));
Telerik.Reporting.Report report = null;
using (var sourceStream = System.IO.File.OpenRead("Reports\DemoReport.trdp"))
{
var reportPackager = new ReportPackager();
report = (Report)reportPackager.UnpackageDocument(sourceStream);
var dtsrc = new ObjectDataSource();
dtsrc.DataSource = dataTable;
report.DataSource = dtsrc;
}
Telerik.Reporting.Processing.ReportProcessor reportProcessor = new Telerik.Reporting.Processing.ReportProcessor();
System.Collections.Hashtable deviceInfo = new System.Collections.Hashtable();
Telerik.Reporting.Processing.RenderingResult result = reportProcessor.RenderReport("PDF", report, deviceInfo);
var fileName = "adreport.pdf";
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
}
return Ok();
``
这会生成报告,但不是几页,生成的 pdf 报告包含几百页重复相同的数据,这是不寻常的。任何人都可以解释为什么会这样。
听起来您设置的数据源不正确(不止一次,例如,首先是在报告级别以编程方式设置,其次是在报告定义中某处的数据项级别设置 (DemoReport.trdp))并且您收到 cartesian product.
我将尽可能详细地回答这个问题。
对于使用 angular 的 telerik 报告和来自后端代码的动态数据分配,请按照以下步骤操作:-
- 从报表设计器设计报表模板
- 将模板放在 c# folter 中
- 在 angular 项目中包含报表查看器
- 当报表查看器请求报表时,使用 CustomReportResolver 处理它
下面提供了示例代码。
Angular
<tr-viewer #viewer1
[containerStyle]="viewerContainerStyle"
[serviceUrl]="'https://localhost:5001/api/reports/'"
[reportSource]="{
report: 'DemoListReport.trdp',
parameters:
{
}
}"
[viewMode]="'INTERACTIVE'"
[scaleMode]="'SPECIFIC'"
[scale]="1.0"
[ready]="ready"
[viewerToolTipOpening]="viewerToolTipOpening"
[enableAccessibility]="false">
</tr-viewer>
<button (click)="viewer1.refreshReport()">Refresh</button>
<button (click)="viewer1.commands.print.exec()">Print</button>
.NET Core 3.1
Startup.cs
services.TryAddScoped<IReportSourceResolver, CustomReportResolver>();
// Configure dependencies for ReportsController.
services.TryAddSingleton<IReportServiceConfiguration>(sp =>
new ReportServiceConfiguration
{
// The default ReportingEngineConfiguration will be initialized from appsettings.json or appsettings.{EnvironmentName}.json:
ReportingEngineConfiguration = sp.GetService<IConfiguration>(),
// In case the ReportingEngineConfiguration needs to be loaded from a specific configuration file, use the approach below:
// ReportingEngineConfiguration = ResolveSpecificReportingConfiguration(sp.GetService<IHostingEnvironment>()),
HostAppId = "Html5DemoAppCore",
Storage = new Telerik.Reporting.Cache.File.FileStorage(),
ReportSourceResolver = new CustomReportResolver()
});
CustomReportResolver.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Telerik.Reporting;
using Telerik.Reporting.Services;
using Telerik.Reporting.Services.Engine;
namespace MyProject.API.Controllers
{
public class CustomReportResolver: IReportSourceResolver
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
public ReportSource Resolve(string report, OperationOrigin operationOrigin, IDictionary<string, object> currentParameterValues)
{
//data
var rng = new Random();
var datas = Enumerable.Range(1, 500).Select(index => new WeatherForecast
{
Category = Summaries[rng.Next(Summaries.Length)],
Date = DateTime.Now.AddDays(index),
TemperatureC = 1
}).ToList();
var reportPackager = new ReportPackager();
Report reportt = null;
using (var sourceStream = System.IO.File.OpenRead($"Reports\{report}"))
{
reportt = (Report)reportPackager.UnpackageDocument(sourceStream);
}
DetailSection detail = (DetailSection)reportt.Items["detailSection1"];
Table table = (Table)detail.Items["table1"];
table.DataSource = datas.Take(5);
Graph graph = (Graph)detail.Items["graph1"];
graph.DataSource = datas;
InstanceReportSource instanceReportSource = new InstanceReportSource();
instanceReportSource.ReportDocument = reportt;
return instanceReportSource;
}
}
}
此处datas
会将您的数据传递给报告。希望这对以后的其他人有所帮助。
我使用设计器设计了报告 trdp 文件,并添加了 Web 服务作为数据源。 我的计划是,当请求报告而不是 Web 源时,我想使用 linq 提取数据并将该数据注入报告数据源并希望通过报告处理器传递它。 我所做的是: ``
var rng = new Random();
var datas = Enumerable.Range(1, 100).Select(index => new WeatherForecast
{
Category = Summaries[rng.Next(Summaries.Length)],
Date = DateTime.Now.AddDays(index),
TemperatureC = 1
}).ToList();
DataTable dataTable = Newtonsoft.Json.JsonConvert.DeserializeObject<DataTable>(Newtonsoft.Json.JsonConvert.SerializeObject(datas));
Telerik.Reporting.Report report = null;
using (var sourceStream = System.IO.File.OpenRead("Reports\DemoReport.trdp"))
{
var reportPackager = new ReportPackager();
report = (Report)reportPackager.UnpackageDocument(sourceStream);
var dtsrc = new ObjectDataSource();
dtsrc.DataSource = dataTable;
report.DataSource = dtsrc;
}
Telerik.Reporting.Processing.ReportProcessor reportProcessor = new Telerik.Reporting.Processing.ReportProcessor();
System.Collections.Hashtable deviceInfo = new System.Collections.Hashtable();
Telerik.Reporting.Processing.RenderingResult result = reportProcessor.RenderReport("PDF", report, deviceInfo);
var fileName = "adreport.pdf";
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
}
return Ok();
``
这会生成报告,但不是几页,生成的 pdf 报告包含几百页重复相同的数据,这是不寻常的。任何人都可以解释为什么会这样。
听起来您设置的数据源不正确(不止一次,例如,首先是在报告级别以编程方式设置,其次是在报告定义中某处的数据项级别设置 (DemoReport.trdp))并且您收到 cartesian product.
我将尽可能详细地回答这个问题。 对于使用 angular 的 telerik 报告和来自后端代码的动态数据分配,请按照以下步骤操作:-
- 从报表设计器设计报表模板
- 将模板放在 c# folter 中
- 在 angular 项目中包含报表查看器
- 当报表查看器请求报表时,使用 CustomReportResolver 处理它 下面提供了示例代码。
Angular
<tr-viewer #viewer1
[containerStyle]="viewerContainerStyle"
[serviceUrl]="'https://localhost:5001/api/reports/'"
[reportSource]="{
report: 'DemoListReport.trdp',
parameters:
{
}
}"
[viewMode]="'INTERACTIVE'"
[scaleMode]="'SPECIFIC'"
[scale]="1.0"
[ready]="ready"
[viewerToolTipOpening]="viewerToolTipOpening"
[enableAccessibility]="false">
</tr-viewer>
<button (click)="viewer1.refreshReport()">Refresh</button>
<button (click)="viewer1.commands.print.exec()">Print</button>
.NET Core 3.1
Startup.cs
services.TryAddScoped<IReportSourceResolver, CustomReportResolver>();
// Configure dependencies for ReportsController.
services.TryAddSingleton<IReportServiceConfiguration>(sp =>
new ReportServiceConfiguration
{
// The default ReportingEngineConfiguration will be initialized from appsettings.json or appsettings.{EnvironmentName}.json:
ReportingEngineConfiguration = sp.GetService<IConfiguration>(),
// In case the ReportingEngineConfiguration needs to be loaded from a specific configuration file, use the approach below:
// ReportingEngineConfiguration = ResolveSpecificReportingConfiguration(sp.GetService<IHostingEnvironment>()),
HostAppId = "Html5DemoAppCore",
Storage = new Telerik.Reporting.Cache.File.FileStorage(),
ReportSourceResolver = new CustomReportResolver()
});
CustomReportResolver.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Telerik.Reporting;
using Telerik.Reporting.Services;
using Telerik.Reporting.Services.Engine;
namespace MyProject.API.Controllers
{
public class CustomReportResolver: IReportSourceResolver
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
public ReportSource Resolve(string report, OperationOrigin operationOrigin, IDictionary<string, object> currentParameterValues)
{
//data
var rng = new Random();
var datas = Enumerable.Range(1, 500).Select(index => new WeatherForecast
{
Category = Summaries[rng.Next(Summaries.Length)],
Date = DateTime.Now.AddDays(index),
TemperatureC = 1
}).ToList();
var reportPackager = new ReportPackager();
Report reportt = null;
using (var sourceStream = System.IO.File.OpenRead($"Reports\{report}"))
{
reportt = (Report)reportPackager.UnpackageDocument(sourceStream);
}
DetailSection detail = (DetailSection)reportt.Items["detailSection1"];
Table table = (Table)detail.Items["table1"];
table.DataSource = datas.Take(5);
Graph graph = (Graph)detail.Items["graph1"];
graph.DataSource = datas;
InstanceReportSource instanceReportSource = new InstanceReportSource();
instanceReportSource.ReportDocument = reportt;
return instanceReportSource;
}
}
}
此处datas
会将您的数据传递给报告。希望这对以后的其他人有所帮助。