DioDocsをBlazor WebAssemblyで使ってみる

DioDocsとBlazorに関する記事としては、「Blazor Server」のリリースに合わせてDioDocsを使用する手順を紹介しました。

2020年5月に「Blazor WebAssembly」がリリースされていますので、今回は「DioDocs(ディオドック)」を利用したExcelファイルとPDFファイルの生成を、このBlazor WebAssemblyアプリケーションで実行する手順を紹介します。

Blazor

ちょっとだけふりかえります。BlazorはC#(.NET Core)とHTMLを使ってWebアプリケーション(シングルページアプリケーション、SPA)を作成できるASP.NET Coreのフレームワークです。

フロントエンド(クライアントサイド)のUIをHTMLとCSSで、実行する処理をJavaScriptではなくC#で作成できます。大きなメリットとしてはバックエンド(サーバーサイド)もフロントエンド(クライアントサイド)もC#で開発ができるということで、ここ最近C#(.NET)開発者には非常に注目されている機能となっています。

Blazor WebAssemblyとBlazor Server

Blazorには2種類の実装方法があり、「Blazor WebAssembly」と「Blazor Server」があります。

Blazor WebAssemblyは「クライアントサイド Blazor」とも呼ばれているモノで、WebAssemblyを利用してブラウザでC#で記載した処理を実行します。

Blazor Serverは「サーバーサイド Blazor」とも呼ばれているモノで、バックエンド(サーバーサイド。ASP.NET Core)でC#で記載した処理を実行します。

アプリケーションで実装する内容

実装する内容は非常にシンプルなモノです。まず、DioDocsを使用してExcelファイルとPDFファイルを作成します。その後、作成したExcelファイルとPDFファイルをAzure Storage EmulatorのBLOBに保存します。BLOBへの保存にはAzure Storage Blobs client library for .NETを使用します。

アプリケーションの作成

作成するにはVisual Studio 2019が必要ですので、事前にインストールしておきます。

Visual Studioを起動して「新しいプロジェクト」-「Blazor アプリ」を選択して「次へ」をクリックします。

アプリケーションの作成

プロジェクト名を「DioDocsBlazorWasmApp1」として「作成」をクリックします。

アプリケーションの作成

「Blazor WebAssembly App」を選択して「作成」をクリックします。

Blazor WebAssembly App

これでBlazor WebAssemblyアプリケーションが作成できました。

NuGetパッケージの追加

NuGet パッケージ マネージャーから以下のパッケージを追加します。

  • GrapeCity.DioDocs.Excel.ja:DioDocs for Excel
  • GrapeCity.DioDocs.Pdf.ja:DioDocs for PDF
  • Azure.Storage.Blobs:Azure Storage Blobs client library for .NET

NuGetパッケージ

BLOB Storageの準備

Visual Studioから「Cloud Explorer」を開いてAzure Storage EmulatorのBLOBにdiodocsという名前のBLOBコンテナーを作成します。こちらにアプリケーションで作成したExcelファイルとPDFファイルを保存します。

Cloud Explorer

appsettings.jsonの準備

プロジェクトにappsettings.jsonを追加します。Blazor WebAssemblyではこのような構成ファイルを追加した場合、デフォルトの状態ですとクライアントサイドにそのままダウンロードできてしまうので内容が丸見えです。

そこで以下のように「ビルドアクション」と「出力ディレクトリにコピー」の設定を変更しておきます。

appsettings.json

Azure Storage Emulatorの接続文字列とDioDocsのライセンスキーを記載します。

{
"ConnectionStrings": {
"dev": "Azure Storage Emulatorの接続文字列",
"product": "本番環境用の接続文字列"
},
"LicenseStrings": {
"DioDocsExcel": "DioDocs for Excelのライセンスキー",
"DioDocsPdf": "DioDocs for PDFのライセンスキー"
}
}

Azure Storage Emulatorの接続文字列はVisual Studioの「Cloud Explorer」で参照できます。

Cloud Explorer

オプションを扱うクラスを追加

プロジェクトにDataフォルダを追加して、その配下にSettingAccessor.csを追加します。こちらにLicenseStringsAzStorageStringsを追加します。このクラスはAzure Storage Emulatorの接続文字列とDioDocsのライセンスキーを読み込んで利用するためのクラスです。

public class LicenseStrings
{
public string DioDocsExcel { get; set; }
public string DioDocsPdf { get; set; }
}
public class AzStorageStrings
{
public string Dev { get; set; }
public string Product { get; set; }
}

Azure BLOB Storageを使うクラスを追加

Dataフォルダ配下にAzStorage.csを追加します。このクラスはUploadExcelAsyncUploadPdfAsyncで、次で作成するDDExcelServiceDDPdfServiceで呼び出され、DioDocsで作成したExcelファイルとPDFファイルをAzure BLOB Storageへ保存(アップロード)します。

public class AzStorage
{
private readonly string storageConnectionString;
public AzStorage(string connectionstring)
{
storageConnectionString = connectionstring;
}
public async void UploadExcelAsync(MemoryStream uploadstream)
{
BlobContainerClient container = new BlobContainerClient(storageConnectionString, "diodocs");
BlobClient blob = container.GetBlobClient("Result.xlsx");
await blob.UploadAsync(uploadstream);
}
public async void UploadPdfAsync(MemoryStream uploadstream)
{
BlobContainerClient container = new BlobContainerClient(storageConnectionString, "diodocs");
BlobClient blob = container.GetBlobClient("Result.pdf");
await blob.UploadAsync(uploadstream);
}
}

DioDocsを使うクラスを追加

Dataフォルダ配下にDDExcelService.csDDPdfService.csを追加します。それぞれのクラスでDioDocsを使用してExcelファイルとPDFファイルを作成します。

public class DDExcelService
{
public void Create(string platformname, string key, string connectionstring)
{
// ライセンスキー設定
//Workbook.SetLicenseKey(key);
// ワークブックの作成
Workbook workbook = new Workbook();
// ワークシートの取得
IWorksheet worksheet = workbook.Worksheets[0];
// セル範囲を指定して文字列を設定
worksheet.Range["B2"].Value = "Hello DioDocs!";
worksheet.Range["B3"].Value = "from " + platformname;
// メモリストリームに保存
MemoryStream ms = new MemoryStream();
workbook.Save(ms, SaveFileFormat.Xlsx);
ms.Seek(0, SeekOrigin.Begin);
// BLOBストレージにアップロード
AzStorage storage = new AzStorage(connectionstring);
storage.UploadExcelAsync(ms);
}
}
public class DDPdfService
{
public void Create(string platformname, string key, string connectionstring)
{
// ライセンスキー設定
//GcPdfDocument.SetLicenseKey(key);
// PDFドキュメントを作成します。
GcPdfDocument doc = new GcPdfDocument();
// ページを追加し、そのグラフィックスを取得します。
GcPdfGraphics g = doc.NewPage().Graphics;
// ページに文字列を描画します。
g.DrawString("Hello, DioDocs!" + Environment.NewLine + "from " + platformname,
new TextFormat() { Font = StandardFonts.Helvetica, FontSize = 12 },
new PointF(72, 72));
// メモリストリームに保存
MemoryStream ms = new MemoryStream();
doc.Save(ms, false);
ms.Seek(0, SeekOrigin.Begin);
// BLOBストレージにアップロード
AzStorage storage = new AzStorage(connectionstring);
storage.UploadPdfAsync(ms);
}
}

なお、ライセンスキーを設定する部分だけコメントアウトしていますが、DioDocsはライセンスキーを設定しなくても機能制限がありますが動作を試すことができます。機能制限なしで確認したい場合はトライアル版を利用してライセンスキーを設定してください。

DioDocsを使うページを追加

Pagesフォルダ配下にDioDocs.razorを追加します。このページではボタンクリック時にDioDocsRunを呼び出しています。

DioDocsを使うページを追加

@page "/diodocs"
@using DioDocsBlazorWasmApp1.Data
@inject DDExcelService ddexcelservice
@inject DDPdfService ddpdfservice
@inject LicenseStrings licensestrings
@inject AzStorageStrings azstoragestrings
<h1>DioDocs</h1>
<p>Current platform: @platformname</p>
<button class="btn btn-primary" @onclick="DioDocsRun">Create</button>
<p></p>
<p>Status: @status</p>
@code {
string platformname = "Blazor Wasm App (Client-Side Blazor)";
string status = "Ready";
void DioDocsRun()
{
ddexcelservice.Create(platformname, licensestrings.DioDocsExcel, azstoragestrings.Dev);
ddpdfservice.Create(platformname, licensestrings.DioDocsExcel, azstoragestrings.Dev);
status = "Finished!";
}
}

Program.csを更新

ProgramクラスのMainを以下のように更新します。LicenseStringsAzStorageStringsappsettings.jsonで設定したAzure Storage Emulatorの接続文字列とDioDocsのライセンスキーをAddSingletonでインジェクションします。さらにAddSingletonDDExcelServiceDDPdfServiceをインジェクションします。

public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
var configuration = new ConfigurationBuilder()
.AddJsonStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("DioDocsBlazorWasmApp1.appsettings.json"))
.Build();
builder.Services.AddSingleton(p => configuration.GetSection("LicenseStrings").Get<LicenseStrings>());
builder.Services.AddSingleton(p => configuration.GetSection("ConnectionStrings").Get<AzStorageStrings>());
builder.Services.AddSingleton<DDExcelService>();
builder.Services.AddSingleton<DDPdfService>();
await builder.Build().RunAsync();
}
}

NavMenuを更新

NavMenu.razorDioDocs.razorにナビゲーションするための要素を追加します。

<div class="top-row pl-4 navbar navbar-dark">
<a class="navbar-brand" href="">DioDocsBlazorWasmApp1</a>
<button class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="diodocs">
<span class="oi oi-document" aria-hidden="true"></span> DioDocs
</NavLink>
</li>
</ul>
</div>
@code {
private bool collapseNavMenu = true;
private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}

確認してみる(エラー)

Visual Studioでデバッグ実行してみます。

デバッグ実行

左側のメニューから「DioDocs」をクリックするとDioDocsページが表示されます。

DioDocsページ

ページにある[Create]ボタンをクリックするとDioDocsでExcelファイルとPDFファイルが作成され、Azure Storage EmulatorのBLOBコンテナdiodocsへ保存されるハズ…がエラーになってしまいます。

DioDocsページ

これはAzure Storage EmulatorのBLOBでCORSの設定がないためです。エラー内容はブラウザの開発者ツールから参照できます。

開発者ツール

Blazor WebAssemblyアプリケーションの情報を予め利用するクラウドサービス側でCORSの設定をしておく必要があります。

Azure Storage EmulatorでCORSの設定をする

設定する情報はプロジェクトのPropertiesフォルダにあるlaunchSettings.jsonに記載されています。

launchSettings.json

アプリケーションをホストする際のURLhttp://localhost:6415https://localhost:44332をAzure Storage Emulatorに設定します。設定は残念ながらVisual SutidoのCloud Explorerでは出来ないので、「Microsoft Azure Storage Explorer」を使用します。

「Blob Container」を右クリックしてメニューから「CORS の設定の構成」をクリックします。

CORSの設定の構成

「追加」をクリックします。

CORSの設定の構成

「許可されたオリジン」にhttp://localhost:6415https://localhost:44332を、「許可されたヘッダー」と「公開ヘッダー」に*を設定します。

CORSの設定の構成

確認してみる(成功)

以上で準備は完了です。先程と同じようにデバッグ実行してDioDocsページで「Create」ボタンをクリックすると、DioDocsでExcelファイルとPDFファイルが作成され、Azure Storage EmulatorのBLOBコンテナdiodocsへ保存されるのが確認できます。

DioDocsページ

出力結果

構成ファイルappsettings.jsonの利用方法に若干の違いはありましたが、Blazor Serverと同じようにBlazor WebAssemblyでもDioDocsを利用することができました。

実際に動作を確認できるサンプルはこちらです。