-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add example of writer using Razor template
- Loading branch information
1 parent
d124547
commit f85fe1f
Showing
5 changed files
with
289 additions
and
0 deletions.
There are no files selected for viewing
72 changes: 72 additions & 0 deletions
72
demos/XReports.Demos/Controllers/CustomWriters/RazorWriterController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading.Tasks; | ||
using Bogus; | ||
using Microsoft.AspNetCore.Mvc; | ||
using XReports.Converter; | ||
using XReports.Demos.Models.Shared; | ||
using XReports.Demos.XReports; | ||
using XReports.Html; | ||
using XReports.SchemaBuilders; | ||
using XReports.Table; | ||
|
||
namespace XReports.Demos.Controllers.CustomWriters; | ||
|
||
public class RazorWriterController : Controller | ||
{ | ||
private const int RecordsCount = 10; | ||
|
||
private readonly IServiceProvider serviceProvider; | ||
|
||
public RazorWriterController(IServiceProvider serviceProvider) | ||
{ | ||
this.serviceProvider = serviceProvider; | ||
} | ||
|
||
public async Task<IActionResult> Index() | ||
{ | ||
IReportTable<ReportCell> reportTable = this.BuildReport(); | ||
IReportTable<HtmlReportCell> htmlReportTable = this.ConvertToHtml(reportTable); | ||
string tableHtml = await this.WriteHtmlReportToStringAsync(htmlReportTable); | ||
|
||
return this.View(new ReportViewModel() { ReportTableHtml = tableHtml }); | ||
} | ||
|
||
private IReportTable<ReportCell> BuildReport() | ||
{ | ||
ReportSchemaBuilder<Entity> reportBuilder = new(); | ||
reportBuilder.AddColumn("Name", e => e.Name); | ||
reportBuilder.AddColumn("Score", e => e.Score); | ||
|
||
IReportTable<ReportCell> reportTable = reportBuilder.BuildVerticalSchema().BuildReportTable(this.GetData()); | ||
return reportTable; | ||
} | ||
|
||
private IReportTable<HtmlReportCell> ConvertToHtml(IReportTable<ReportCell> reportTable) | ||
{ | ||
ReportConverter<HtmlReportCell> htmlConverter = new(Array.Empty<IPropertyHandler<HtmlReportCell>>()); | ||
|
||
return htmlConverter.Convert(reportTable); | ||
} | ||
|
||
private Task<string> WriteHtmlReportToStringAsync(IReportTable<HtmlReportCell> htmlReportTable) | ||
{ | ||
return new RazorWriter(this.serviceProvider) | ||
.WriteAsync(htmlReportTable, "~/Views/RazorWriter/Report.cshtml"); | ||
} | ||
|
||
private IEnumerable<Entity> GetData() | ||
{ | ||
return new Faker<Entity>() | ||
.RuleFor(e => e.Name, f => f.Name.FullName()) | ||
.RuleFor(e => e.Score, f => f.Random.Decimal(0, 100)) | ||
.Generate(RecordsCount); | ||
} | ||
|
||
private class Entity | ||
{ | ||
public string Name { get; set; } | ||
|
||
public decimal Score { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
@model XReports.Demos.Models.Shared.ReportViewModel | ||
|
||
@{ | ||
ViewBag.Title = "Razor Writer"; | ||
Layout = "_DemoPageLayout"; | ||
} | ||
|
||
@section Description | ||
{ | ||
<p>This example writer shows how to use Razor syntax for rendering report.</p> | ||
} | ||
|
||
@section ReportTable | ||
{ | ||
@Html.Raw(Model.ReportTableHtml) | ||
} | ||
|
||
@section Code | ||
{ | ||
public class RazorWriter | ||
{ | ||
private readonly ICompositeViewEngine viewEngine; | ||
private readonly ITempDataProvider tempDataProvider; | ||
private readonly IServiceProvider serviceProvider; | ||
|
||
public RazorWriter(IServiceProvider serviceProvider) | ||
{ | ||
this.serviceProvider = serviceProvider; | ||
this.viewEngine = this.serviceProvider.GetRequiredService<ICompositeViewEngine>(); | ||
this.tempDataProvider = this.serviceProvider.GetRequiredService<ITempDataProvider>(); | ||
} | ||
|
||
public Task<string> WriteAsync(IReportTable<HtmlReportCell> report, string viewName) | ||
{ | ||
return this.RenderSimpleViewToStringAsync(viewName, report); | ||
} | ||
|
||
private async Task<string> RenderSimpleViewToStringAsync<TModel>(string viewName, TModel model) | ||
{ | ||
ViewEngineResult viewResult = this.viewEngine.GetView( | ||
executingFilePath: null, | ||
viewPath: viewName, | ||
isMainPage: true); | ||
if (!viewResult.Success) | ||
{ | ||
throw new ArgumentException($"Could not find view: {viewName}", nameof(viewName)); | ||
} | ||
|
||
await using StringWriter writer = new(); | ||
ViewDataDictionary<TModel> viewDictionary = new(new EmptyModelMetadataProvider(), new ModelStateDictionary()) | ||
{ | ||
Model = model, | ||
}; | ||
ViewContext viewContext = new( | ||
new ActionContext( | ||
new DefaultHttpContext() | ||
{ | ||
RequestServices = this.serviceProvider, | ||
}, | ||
new RouteData(), | ||
new ActionDescriptor()), | ||
viewResult.View, | ||
viewDictionary, | ||
new TempDataDictionary(new DefaultHttpContext(), this.tempDataProvider), | ||
writer, | ||
new HtmlHelperOptions() | ||
); | ||
await viewResult.View.RenderAsync(viewContext); | ||
|
||
return writer.ToString(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
@using XReports.Html | ||
@using Microsoft.AspNetCore.Html | ||
@using System.Text | ||
@using System.Net | ||
|
||
@model XReports.Table.IReportTable<XReports.Html.HtmlReportCell> | ||
|
||
@{ | ||
Layout = null; | ||
} | ||
|
||
@functions | ||
{ | ||
public static HtmlString WriteAttributes(HtmlReportCell cell) | ||
{ | ||
StringBuilder sb = new(); | ||
if (cell.CssClasses.Count > 0) | ||
{ | ||
sb | ||
.Append(" class=\"") | ||
.AppendJoin(' ', cell.CssClasses) | ||
.Append('"'); | ||
} | ||
|
||
if (cell.Styles.Count > 0) | ||
{ | ||
sb | ||
.Append(" style=\"") | ||
.AppendJoin(';', cell.Styles.Select(s => $"{s.Key}:{s.Value}")) | ||
.Append('"'); | ||
} | ||
|
||
if (cell.Attributes.Count > 0) | ||
{ | ||
sb | ||
.AppendJoin( | ||
' ', | ||
cell.Attributes.Select(a => $"{a.Key}=\"{WebUtility.HtmlEncode(a.Value)}\"")); | ||
} | ||
|
||
return new HtmlString(sb.ToString()); | ||
} | ||
} | ||
|
||
<table class="table table-striped table-sm"> | ||
<thead> | ||
@foreach (IEnumerable<HtmlReportCell> row in Model.HeaderRows) | ||
{ | ||
<tr> | ||
@foreach (HtmlReportCell cell in row) | ||
{ | ||
<th @WriteAttributes(cell)>@(cell.IsHtml ? Html.Raw(cell.GetValue<string>()) : cell.GetValue<string>())</th> | ||
} | ||
</tr> | ||
} | ||
</thead> | ||
<tbody> | ||
@foreach (IEnumerable<HtmlReportCell> row in Model.Rows) | ||
{ | ||
<tr> | ||
@foreach (HtmlReportCell cell in row) | ||
{ | ||
<td @WriteAttributes(cell)>@(cell.IsHtml ? Html.Raw(cell.GetValue<string>()) : cell.GetValue<string>())</td> | ||
} | ||
</tr> | ||
} | ||
</tbody> | ||
</table> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
using System; | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Abstractions; | ||
using Microsoft.AspNetCore.Mvc.ModelBinding; | ||
using Microsoft.AspNetCore.Mvc.Rendering; | ||
using Microsoft.AspNetCore.Mvc.ViewEngines; | ||
using Microsoft.AspNetCore.Mvc.ViewFeatures; | ||
using Microsoft.AspNetCore.Routing; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using XReports.Html; | ||
using XReports.Table; | ||
|
||
namespace XReports.Demos.XReports; | ||
|
||
public class RazorWriter | ||
{ | ||
private readonly ICompositeViewEngine viewEngine; | ||
private readonly ITempDataProvider tempDataProvider; | ||
private readonly IServiceProvider serviceProvider; | ||
|
||
public RazorWriter(IServiceProvider serviceProvider) | ||
{ | ||
this.serviceProvider = serviceProvider; | ||
this.viewEngine = this.serviceProvider.GetRequiredService<ICompositeViewEngine>(); | ||
this.tempDataProvider = this.serviceProvider.GetRequiredService<ITempDataProvider>(); | ||
} | ||
|
||
public Task<string> WriteAsync(IReportTable<HtmlReportCell> report, string viewName) | ||
{ | ||
return this.RenderSimpleViewToStringAsync(viewName, report); | ||
} | ||
|
||
private async Task<string> RenderSimpleViewToStringAsync<TModel>(string viewName, TModel model) | ||
{ | ||
ViewEngineResult viewResult = this.viewEngine.GetView( | ||
executingFilePath: null, | ||
viewPath: viewName, | ||
isMainPage: true); | ||
if (!viewResult.Success) | ||
{ | ||
throw new ArgumentException($"Could not find view: {viewName}", nameof(viewName)); | ||
} | ||
|
||
await using StringWriter writer = new(); | ||
ViewDataDictionary<TModel> viewDictionary = new(new EmptyModelMetadataProvider(), new ModelStateDictionary()) | ||
{ | ||
Model = model, | ||
}; | ||
ViewContext viewContext = new( | ||
new ActionContext( | ||
new DefaultHttpContext() | ||
{ | ||
RequestServices = this.serviceProvider, | ||
}, | ||
new RouteData(), | ||
new ActionDescriptor()), | ||
viewResult.View, | ||
viewDictionary, | ||
new TempDataDictionary(new DefaultHttpContext(), this.tempDataProvider), | ||
writer, | ||
new HtmlHelperOptions() | ||
); | ||
await viewResult.View.RenderAsync(viewContext); | ||
|
||
return writer.ToString(); | ||
} | ||
} |