DioDocsをBlazor Serverで使ってみる

2019年9月23日に「.NET Core 3.0」がリリースされました。

この.NET Core 3.0では、「Blazor Server」が正式リリースとして含まれています。
そこで今回は「DioDocs(ディオドック)」を利用したExcelファイルとPDFファイルの生成を、このBlazor Serverで動作するアプリケーションで実行してみます。

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#で記載した処理を実行します。こちらは2020年に正式リリースを予定しており、現在はプレビュー版で試すことができます。

Blazor Serverは「サーバーサイド Blazor」とも呼ばれているモノで、バックエンド(サーバーサイド。ASP.NET Core)でC#で記載した処理を実行します。こちらは前述のとおり正式リリース済みです。

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

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

アプリケーションの作成

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

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

アプリケーションの作成

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

アプリケーションの作成

「Blazor サーバー アプリ」が選択されています。そのまま「作成」をクリックします。

Blazor サーバー アプリ

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

NuGetパッケージの追加

以下のパッケージを追加します。

  • GrapeCity.DioDocs.Excel.ja:DioDocs for Excel
  • GrapeCity.DioDocs.Pdf.ja:DioDocs for PDF
  • Microsoft.Azure.Storage.Blob:Microsoft Azure Storage Blob SDK for .NET

※2020年10月時点ではMicrosoft.Azure.Storage.Blobは古いライブラリになっています。代わりにAzure.Storage.Blobsを使用してください。

NuGetパッケージ

BLOB Storageの準備

Visual Studioから「Cloud Explorer」を開いてdiodocsという名前のBLOBコンテナーを作成します。こちらにExcelファイルとPDFファイルを保存します。

Cloud Explorer

appsettings.jsonの準備

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

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"dev": "Azure Storage Emulatorの接続文字列",
"product": "本番環境用の接続文字列"
},
"LicenseStrings": {
"DioDocsExcel": "DioDocs for Excelのライセンスキー",
"DioDocsPdf": "DioDocs for PDFのライセンスキー"
},
"AllowedHosts": "*"
}

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

Cloud Explorer

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

Dataフォルダ配下にOptionsAccessor.csを追加します。こちらにはLicenseStringsAzStorageStringsを追加します。このクラスはAzure BLOB Storageの接続文字列とDioDocsのライセンスキーを、ASP.NET Coreのオプション機能で読み込んで利用するためのクラスです。

Cloud Explorer

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へ保存(アップロード)します。

Cloud Explorer

public class AzStorage
{
private readonly string storageConnectionString;
public AzStorage(string connectionstring)
{
storageConnectionString = connectionstring;
}
public async void UploadExcelAsync(MemoryStream uploadstream)
{
CloudStorageAccount storageAccount;
CloudStorageAccount.TryParse(storageConnectionString, out storageAccount);
CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("diodocs");
CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference("Result.xlsx");
await cloudBlockBlob.UploadFromStreamAsync(uploadstream);
}
public async void UploadPdfAsync(MemoryStream uploadstream)
{
CloudStorageAccount storageAccount;
CloudStorageAccount.TryParse(storageConnectionString, out storageAccount);
CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("diodocs");
CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference("Result.pdf");
await cloudBlockBlob.UploadFromStreamAsync(uploadstream);
}
}

※2020年10月時点ではMicrosoft.Azure.Storage.Blobは古いライブラリになっています。代わりにAzure.Storage.Blobsを使用して、以下のコードに変更してください。

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ファイルを作成します。

Cloud Explorer

public class DDExcelService
{
private readonly string key;
private readonly string connectionstring;
public DDExcelService(IOptions<LicenseStrings> licensestrings, IOptions<AzStorageStrings> azstoragestrings)
{
key = licensestrings.Value.DioDocsExcel;
connectionstring = azstoragestrings.Value.Dev;
}
public void Create(string platformname)
{
// ライセンスキー設定
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
{
private readonly string key;
private readonly string connectionstring;
public DDPdfService(IOptions<LicenseStrings> licensestrings, IOptions<AzStorageStrings> azstoragestrings)
{
key = licensestrings.Value.DioDocsPdf;
connectionstring = azstoragestrings.Value.Dev;
}
public void Create(string platformname)
{
// ライセンスキー設定
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を使うページを追加

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

Cloud Explorer

@page "/diodocs"
@using DioDocsBlazorApp1.Data
@inject DDExcelService ddexcelservice
@inject DDPdfService ddpdfservice
<h1>DioDocs</h1>
<p>Current platform: @platformname</p>
<button class="btn btn-primary" @onclick="DioDocsRun">Create</button>
<p></p>
<p>Status: @status</p>
@functions {
string platformname = "Blazor Server App (Server-Side Blazor)";
string status = "Ready";
void DioDocsRun()
{
ddexcelservice.Create(platformname);
ddpdfservice.Create(platformname);
status = "Finished!";
}
}

ConfigureServicesを更新

StartupクラスのConfigureServicesを以下のように更新します。LicenseStringsAzStorageStringsappsettings.jsonで設定したAzure BLOB Storageの接続文字列とDioDocsのライセンスキーを割り当てるようにします。また、AddSingletonDDExcelServiceDDPdfServiceをインジェクションします。

public void ConfigureServices(IServiceCollection services)
{
IConfigurationSection licensestring = Configuration.GetSection("LicenseStrings");
services.Configure<LicenseStrings>(licensestring);
IConfigurationSection azstroragestring = Configuration.GetSection("ConnectionStrings");
services.Configure<AzStorageStrings>(azstroragestring);
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
services.AddSingleton<DDExcelService>();
services.AddSingleton<DDPdfService>();
}

NavMenuを更新

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

<div class="top-row pl-4 navbar navbar-dark">
<a class="navbar-brand" href="">DioDocsBlazorApp1</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 {
bool collapseNavMenu = true;
string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}

確認してみる

以上で準備は完了です。Visual Studioでデバッグ実行してみます。

デバッグ実行

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

DioDocsページ

ページにある「Create」ボタンをクリックするとDioDocsでExcelファイルとPDFファイルが作成され、Azure Storage EmulatorのBLOBコンテナdiodocsへ保存されます。

Createボタンをクリック

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

以上です。Blazor WebAssemblyの正式リリースも控えており、今後ますます注目のBlazorですね!