共有データソースには、複数のレポートに同じデータをバインドできる接続プロパティが含まれます。共有データソースは、単体のデザイナまたはVisual Studioに統合されたデザイナでのみ作成および編集できます。Webデザイナでは、既存のデータソースのみを参照できます。
以下は、様々なシナリオでWebデザイナに共有データソースを使用する方法について説明します。
この問題は、共有データソースによって解決されます。レポート定義にはデータソース定義への参照のみが含まれており、レポートのプレビュー時にサーバー側で解決されます。
共有データソース(*.rdsx)は、単体のデザイナまたはVisual Studioに統合されたデザイナでのみ作成される必要があります。詳細については、「共有データソースの操作」を参照してください。
以下の手順では、共有データソースを使用する方法について説明します。まず、ASP.NET MVC CoreアプリケーションでWebデザイナを作成する必要があります。詳細については、次のトピックを参照してください。
以下の手順では、WebDesigner_MVC_Coreサンプルに共有データソースを追加する方法について説明します。
script.js |
コードのコピー
|
---|---|
import { arWebDesigner } from './web-designer.js'; import { createViewer } from './jsViewer.min.js'; let viewer = null; let serverUrl = getServerUrl(); function getServerUrl() { let baseUrl = 'api'; let virtualDirName = document.getElementById('virtualDir'); if (virtualDirName && virtualDirName.href != window.location.origin + '/') { return virtualDirName.href + baseUrl; } return baseUrl; } arWebDesigner.create('#ar-web-designer', { server: { url: serverUrl }, appBar: { openButton: { visible: true } }, data: { dataSets: { canModify: true }, dataSources: { canModify: true, shared: { enabled: true } } }, preview: { openViewer: (options) => { if (viewer) { viewer.theme = options.theme; viewer.openReport(options.documentInfo.id); return; } viewer = createViewer({ element: '#' + options.element, reportService: { url: 'api/reporting', }, reportID: options.documentInfo.id, settings: { zoomType: 'FitPage', }, theme: options.theme }); } } }); |
Implementationフォルダを作成します。
Implementationフォルダに、IReportStoreの実装を含むReportStore.csクラスを追加します。
ReportStore.cs |
コードのコピー
|
---|---|
using System; using System.Collections.Generic; using System.IO; using System.Linq; using GrapeCity.ActiveReports.Rendering.Tools; using GrapeCity.ActiveReports.Web.Designer; using GrapeCity.ActiveReports.Web.Viewer; namespace WebDesigner_MVC_Core.Implementation { public class ReportStore : IReportStore { private static readonly string[] ReportExtensions = { ".rdl", ".rdlx", ".rdlx-master", ".rpx" }; private readonly Dictionary<string, byte[]> _tempStorage = new Dictionary<string, byte[]>(); private readonly DirectoryInfo _rootDirectory; public ReportStore(DirectoryInfo rootDirectory) { _rootDirectory = rootDirectory; } public ReportDescriptor GetReportDescriptor(string reportId) { if (_tempStorage.ContainsKey(reportId)) return new ReportDescriptor(GetReportTypeByExtension(Path.GetExtension(reportId))); var fileInfo = new FileInfo(Path.Combine(_rootDirectory.FullName, reportId)); return new ReportDescriptor(GetReportTypeByExtension(fileInfo.Extension)); } public Stream LoadReport(string reportId) { if (_tempStorage.TryGetValue(reportId, out var tempReport)) return new MemoryStream(tempReport); var file = new FileInfo(Path.Combine(_rootDirectory.FullName, reportId)); return file.OpenRead(); } public string SaveReport(ReportType reportType, string reportId, Stream reportData, SaveSettings settings = SaveSettings.None) { if ((settings & SaveSettings.IsTemporary) != 0) { var tempName = Guid.NewGuid() + GetReportExtension(reportType); _tempStorage.Add(tempName, reportData.ToArray()); return tempName; } var reportFullPath = Path.Combine(_rootDirectory.FullName, reportId); using var fileStream = new FileStream(reportFullPath, FileMode.Create, FileAccess.Write); reportData.CopyTo(fileStream); return reportId; } public string UpdateReport(ReportType reportType, string reportId, Stream reportData) { return SaveReport(reportType, reportId, reportData); } public ReportInfo[] ListReports() { var reports = _rootDirectory .EnumerateFiles("*.*") .Where(fileInfo => ReportExtensions.Any(ext => fileInfo.Extension.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase))) .Select(fileInfo => new ReportInfo() { Id = fileInfo.Name, Name = fileInfo.Name, ReportType = GetReportTypeByExtension(fileInfo.Extension), }).ToArray(); return reports; } private static ReportType GetReportTypeByExtension(string extension) { switch (extension) { case ".rdl": case ".rdlx": return ReportType.RdlXml; case ".rdlx-master": return ReportType.RdlMasterXml; case ".rpx": return ReportType.RpxXml; default: throw new ArgumentOutOfRangeException(nameof(extension), extension, null); } } private static string GetReportExtension(ReportType type) { return type switch { ReportType.RdlXml => ".rdlx", ReportType.RdlMasterXml => ".rdlx-master", ReportType.RpxXml => ".rpx", _ => throw new ArgumentOutOfRangeException(nameof(type), type, null) }; } public void DeleteReport(string reportId) { if (_tempStorage.ContainsKey(reportId)) { _tempStorage.Remove(reportId); return; } var file = new FileInfo(Path.Combine(_rootDirectory.FullName, reportId)); if (file.Exists) file.Delete(); ; } } } |
IResourcesServiceの実装を追加するには、ImplementationフォルダにResourceService.csを追加します。
ResourceService.cs |
コードのコピー
|
---|---|
using System.IO; using System.Linq; using GrapeCity.ActiveReports; using GrapeCity.ActiveReports.Rendering.Tools; using GrapeCity.ActiveReports.Web.Designer; namespace WebDesigner_MVC_Core.Implementation { public class ResourceProvider : IResourceRepositoryProvider { private const string SharedDataSourceExtension = ".rdsx"; private readonly DirectoryInfo _rootDirectory; public ResourceProvider(DirectoryInfo rootDirectory) { _rootDirectory = rootDirectory; } public Stream GetResource(ResourceInfo resource) { string absolutePath = Path.Combine(_rootDirectory.FullName, resource.Name); var file = new FileInfo(absolutePath); if (!file.Exists) return null; return file.OpenRead(); } public ResourceDescriptor[] ListResources(ResourceType resourceType) { if (resourceType == ResourceType.SharedDataSource) { var sharedDataSources = _rootDirectory .EnumerateFiles("*" + SharedDataSourceExtension).Select(fileInfo => { using var stream = fileInfo.OpenRead(); var dataSource = DataSourceTools.LoadSharedDataSource(stream); return new SharedDataSourceResourceDescriptor() { Id = fileInfo.Name, Name = fileInfo.Name, Type = dataSource.ConnectionProperties.DataProvider }; }).ToArray(); return sharedDataSources; } return Enumerable.Empty<ResourceDescriptor>().ToArray(); } public ResourceDescriptor[] DescribeResources(ResourceInfo[] resources) { return Enumerable.Empty<ResourceDescriptor>().ToArray(); } } } |
Startup.csを開き、次のようにファイルを更新します。Startup.csファイルは次のような処理を行います。
Startup.cs |
コードのコピー
|
---|---|
using System.IO; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using GrapeCity.ActiveReports.Aspnetcore.Viewer; using GrapeCity.ActiveReports.Aspnetcore.Designer; using System.Text; using GrapeCity.ActiveReports.Web.Designer; using WebDesigner_MVC_Core.Implementation; using System; namespace WebDesignerMvcCore { public class Startup { private static readonly DirectoryInfo ResourcesRootDirectory = new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "resources" + Path.DirectorySeparatorChar)); public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // このメソッドはランタイムによって呼び出されます。このメソッドを使用して、コンテナにサービスを追加します。 public void ConfigureServices(IServiceCollection services) { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); services .AddReportViewer() .AddReportDesigner() .AddSingleton<IReportStore>(new ReportStore(ResourcesRootDirectory)) .AddSingleton<IResourceRepositoryProvider>(new ResourceProvider(ResourcesRootDirectory)) .AddMvc(options => options.EnableEndpointRouting = false) .AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null); } // このメソッドはランタイムによって呼び出されます。このメソッドを使用して、HTTP要求パイプラインを構成します。 public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IReportStore reportStore, IResourceRepositoryProvider resourceProvider ) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } var pathToConfig = Path.Combine(Environment.CurrentDirectory, "ActiveReports.config"); app.UseReportDesigner(config => { config.UseReportsProvider(reportStore); config.UseResourcesProvider(resourceProvider); config.UseConfig(pathToConfig); }); app.UseFileServer(); app.UseMvc(); } } } |
以下の内容でActiveReports.configファイルを追加します。
ActiveReports.config |
コードのコピー
|
---|---|
<?xml version="1.0" encoding="utf-8" ?> <Configuration> <Extensions> <Data> <Extension Name="SQLITE" Type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" DisplayName="Sqlite Provider" /> </Data> </Extensions> </Configuration> |
[データ]タブに移動し、データソースを追加します。
[データソースエディタ]ダイアログでは、種類で[共有参照]を選択し、参照で「.rdsx」ファイルを選択します。