FastReport教程:如何在Angular单页面应用程序中使用Online Designer

下载FastReport.Net最新版本

在本文中,我们将介绍在基于Angular框架和ASP .Net Core的单页面应用程序中使用FastReport Online Designer的方法。由于此SPA应用程序的后端是在ASP .Net Core上实现的,因此我们可以轻松使用FastReport库。仍然只有一个问题:如何在Angular客户端应用程序中显示Web报表对象。

您可能知道第一个版本中的Angular框架是在JavaScript中实现的。所有后续版本都是用TypeScript编写的。现在,Angular的第一个版本被称为AngularJS,而其他版本则有数字索引:2,3,... 7.我们将基于Angular 7创建一个演示应用程序。

在我们开始开发之前,让我们为环境做好准备。您需要安装Node js平台。它将在服务器端启用JavaScript。从制造商的网站https://nodejs.org/en/下载该发行版并安装。Node js包含NPM包管理器,它允许我们使用控制台命令安装用JavaScript编写的必要库。此外,您必须安装.Net Core SDK 2.0及更高版本。

要快速创建演示应用程序,请使用Windows命令提示符。我们启动cmd,然后传递到我们要创建项目的目录。我们执行命令:

dotnet new angular -o AngularOnlineDesignerFRCore

接下来,我们需要一个在线设计器。首先需要在设计器中为.Net Core框架组装一个新的在线设计器

FastReport教程:如何在Angular单页面应用程序中使用Online Designer

在Visual Studio中打开我们的项目。使用在线设计器下载存档后,将其解压缩到项目中的wwwroot文件夹。

现在我们将使用NuGet包管理器将FastReport库添加到项目中。在管理器的右上角有一个包源的下拉列表。我们需要一个本地来源。但是你需要配置它。要执行此操作,请单击下一个齿轮形式的图标。接下来,选择本地源并为其设置本地磁盘上目录的路径:

C:\ Program Files(x86)\ FastReports \ FastReport.Net \ Nugets。完成设置后,安装两个可用的软件包:FastReport.Core和FastReport.Web。

FastReport教程:如何在Angular单页面应用程序中使用Online Designer

要在项目中使用FastReport,还需要在指定的方法中将以下行添加到Sturtup.cs文件中:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
 {
…
 app.UseFastReport();
…
}

要将报表上传到设计器,我们需要将必要的报表模板添加到服务器。为此,请在项目根目录中创建App_Data文件夹。从FastReport.Net delivery,Demos / Reports文件夹中添加几个报告模板。另外,从此文件夹中复制nwind.xml数据文件:

FastReport教程:如何在Angular单页面应用程序中使用Online Designer

现在我们可以开始编程。我们有一个控制器 - SampleDataController。由于我们使用示例页面创建了一个演示应用程序,因此我们在控制器和客户端中都有不必要的元素。让我们从SampleDataController.cs控制器中删除所有方法并添加我们自己的方法。

using System;
using Microsoft.AspNetCore.Mvc;
using FastReport.Web;
using System.IO;
 
namespace AngularOnlineDesignerFRCore.Controllers
{
 [Route("api/[controller]")]
 public class SampleDataController : Controller
 {
 [HttpGet("[action]")]
 public IActionResult Design(string report)
 {
 WebReport WebReport = new WebReport();
 WebReport.Width = "1000";
 WebReport.Height = "1000";
 WebReport.Report.Load("App_Data/"+report+".frx"); // Load the report into the WebReport object
 System.Data.DataSet dataSet = new System.Data.DataSet(); // Create a data source
 dataSet.ReadXml("App_Data/nwind.xml"); // Open the xml database
 WebReport.Report.RegisterData(dataSet, "NorthWind"); // Registering the data source in the report
 WebReport.Mode = WebReportMode.Designer; // Set the web report object mode - designer display
 WebReport.DesignerLocale = "en";
 WebReport.DesignerPath = @"WebReportDesigner/index.html"; // We set the URL of the online designer
 WebReport.DesignerSaveCallBack = @"api/SampleData/SaveDesignedReport"; // Set the view URL for the report save method
 WebReport.Debug = true;
 ViewBag.WebReport = WebReport; // pass the report to View
 return View();
 }
 
 [HttpPost("[action]")]
 // call-back for save the designed report
 public IActionResult SaveDesignedReport(string reportID, string reportUUID)
 {
 ViewBag.Message = String.Format("Confirmed {0} {1}", reportID, reportUUID); // We set the message for representation
 Stream reportForSave = Request.Body; // Write the result of the Post request to the stream.
 string pathToSave = @"App_Data/TestReport.frx"; // get the path to save the file
 using (FileStream file = new FileStream(pathToSave, FileMode.Create)) // Create a file stream
 {
 reportForSave.CopyTo(file); // Save query result to file
 }
 return View();
 }
 }
}

第一个Design方法采用report参数,该参数是要加载的报表的名称。我们创建报表对象,将报表模板加载到报表对象中并连接数据源。接下来,打开报表对象的设计模式,设置设计器在线页面的路径以及报表保存方法的路径。

第二种方法是保存报表的回调。通过单击设计器中的“保存”按钮,我们将启动一个将触发此回调的保存事件。在此方法中,我们实现了将报表文件保存在服务器上作为TestReport。

对于这些方法,您需要创建视图。但在我们的项目中没有Views文件夹。让我们在项目的根目录创建它。在其中,您需要创建另一个文件夹 - SampleData。在这里我们添加视图。首先是Design方法。该文件以相同的方式调用,其内容非常简洁:

@await ViewBag.WebReport.Render();

 我们只输出Web报表对象。Render方法将其转换为html。为SaveDesignedReport方法添加另一个视图:

@ ViewBag.Message

此视图显示保存报表事件的状态消息。

在这个阶段,服务器端编程可以被认为是完整的。去前端。

与单页应用程序相关的所有内容都位于ClientApp目录中。将其部署到解决方案浏览器。在里面我们对src文件夹感兴趣,然后是应用程序。

对于显示主页面组件,app.component.ts负责。我们要编辑它:

import { Component } from '@angular/core';
 
@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css'],
})
 
export class AppComponent {
}

但首先,请考虑app.component.html文件中的页面模板:

<div class='container-fluid'>
 <div class='row'>
 <div>
 <input type="radio" id="reportChoice1"
 name="report" value="Text" (click)="this.report = 'Text'">
 <label for="reportChoice1">Text</label>
 <input type="radio" id="reportChoice2"
 name="report" value="Master-Detail" (click)="this.report = 'Master-Detail'">
 <label for="reportChoice2">Master-Detail</label>
 </div>
 <div>
 <input type="button" (click)="Clicked()" value="Show Online Designer" />
 <div *ngIf="flag" [innerHTML]="html | safeHtml"></div>
 </div>
 </div>
</div>

你注意到的第一件事是单选按钮。使用它们,我们将选择需要在在线设计器中打开的两个报表一。单选按钮订阅了该事件(单击)。此事件设置变量报表的值。我们将在最终确定应用程序组件时讨论它。

接下来是按钮,它也订阅了click事件。Clicked()函数由此事件调用。下一个div有一个条件 - 如果flag变量为true,则显示嵌套的html代码,我们从html变量中获取。但要注意safeHtml函数,我们通过管道将其应用于html变量。此函数规范化html代码,使其安全且适合嵌入DOM。

我们必须实现此功能。为此,请在当前文件夹中创建一个新的打样文件 - app。我们称之为safeHtml.pipe.ts:

import { PipeTransform, Pipe } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
 
@Pipe({ name: 'safeHtml' })
export class SafeHtmlPipe implements PipeTransform {
 constructor(private sanitized: DomSanitizer) { }
 transform(value) {
 return this.sanitized.bypassSecurityTrustHtml(value);
 }
}

DomSanitizer库为我们完成所有工作,您只需要将html代码提供给bypassSecurityTrustHtml方法。

让我们回到应用程序组件。我们在其中实现了Clicked()函数

import { Component } from '@angular/core';
import { HttpClient } from "@angular/common/http";
 
@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css'],
 providers: [HttpService]
})
export class AppComponent {
 html: string;
 flag: boolean;
 report: string;
 
constructor(private http: HttpClient){ }
 Clicked() {
this.flag = false;
this.http.get('api/SampleData/Design?report='+report, { headers: { 'Accept': 'text/html' }, responseType: 'text' as 'text' }).).subscribe((data: string) => { this.html = data; this.flag = true });
 }
}

我们添加了一个接受HttpClient的类构造函数。我们需要它来完成获取请求。Clicked()函数设置flag变量的默认值。接下来,它对Design控制器方法执行get请求。变量报告中的报告名称作为参数传递。如果get请求收到成功响应,则flag变量设置为true。这将显示报表设计器将显示的div。

但是,从组件向单独的服务发出请求是一种好习惯。在当前app目录中创建http.service.ts脚本:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
 
@Injectable()
export class HttpService {
 constructor(private http: HttpClient) { }
 
 getData(report) {
 return this.http.get('api/SampleData/Design?report='+report, { headers: { 'Accept': 'text/html' }, responseType: 'text' as 'text' });
 }
}

 现在让我们转换app.component.ts来使用它:

import { Component } from '@angular/core';
import { HttpService } from "./http.service";
 
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [HttpService]
})
export class AppComponent {
html: string;
flag: boolean;
report: string;
 
constructor(private httpService: HttpService) {
}
 
Clicked() {
this.flag = false;
this.httpService.getData(this.report).subscribe((data: string) => { this.html = data; this.flag = true });
}
}

 为了在组件中加载和提供添加的模块,需要将它们添加到app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { SafeHtmlPipe } from './safeHtml.pipe';
 
@NgModule({
 declarations: [
 AppComponent,
 NavMenuComponent,
 SafeHtmlPipe
 ],
 imports: [
 BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
 HttpClientModule,
 FormsModule
 ],
 providers: [],
 bootstrap: [AppComponent]
})
export class AppModule { }

现在,服务和管道都可以在AppComponent中使用。

这足以启动应用程序并使用下载的报表显示报表设计器。但有一个细微差别。由于WebReportDesigner应位于wwwroot目录中,因此无法使用后端的视图来处理保存报表的事件。

我们将通过代理后端的客户来解救。因此,我们指出必须将请求发送到服务器端口,在我们的例子中是ng服务器。

要配置代理,您需要在src目录中创建proxy.config.json文件:

{
 "/": {
 "target": "http://localhost:4200/",
 "secure": false,
 "logLevel": "debug"
 }
}

 在我们的例子中,ng服务器端口是4200,但它可以是不同的。您可以通过从控制台运行服务器来学习它。为此,请运行Windows命令行,使用cd命令转到ClientApp目录,然后运行:npm start。从下一个显示的文本中,您可以看到所需的端口号。

现在打开src目录中的package.json文件并更改其中的以下设置:

{
 "scripts": {
…
 
 "start": "ng serve --proxy-config proxy.config.json",
"build": "ng build --prod --output-path ../AngularOnlineDesignerFRCore/wwwroot",
 …
 }

因此,我们为代理指定了配置文件,并为ClientApp程序集设置了wwwroot文件夹。

现在您可以运行应用程序并评估已完成的工作。我们期待一个几乎空的页面,只有这些控件:

FastReport教程:如何在Angular单页面应用程序中使用Online Designer

让我们选择两个报表中的一个,然后单击ShowOnlineDesigner按钮:

FastReport教程:如何在Angular单页面应用程序中使用Online Designer

设计器显示加载的报表。单击“报表”选项卡并单击“保存”按钮:

FastReport教程:如何在Angular单页面应用程序中使用Online Designer

如果正确配置了代理,您将在右侧的绿色框中看到消息保存。报告文件保存在服务器上。

在这一点上,我们将假设示范项目的工作已经完成。让我们总结一下。后端开发几乎与常规ASP.Net Core应用程序相同。考虑到我们在一个命令中生成了几乎所有文件,改进前端也不是那么困难。


相关链接:

关于产品的任何问题,欢迎咨询在线客服>>