Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

サーバーサイドでExcelファイルを読み書きするWebアプリケーションを作る

ASP.NET MVCやMicrosoft Azure Functions上でExcel処理を記述しよう

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
2017/05/26 14:00

 本記事で紹介するExcelコンポーネントは、サーバーサイドでExcelファイルを読み書きできる.NET Frameworkのライブラリです。これを利用してExcelファイルの作成・読み取りを行うASP.NETなWebアプリケーションを作成します。このアプリケーションは、クラウド上、例えばMicrosoftのPaaSや、サーバーレスアーキテクチャのサービスであるMicrosoft Azure Functionでも動作します。

はじめに

 Excelコンポーネントは、Excelファイルの読み書きを行う.NET Framework上で動作するライブラリ、つまりdllファイルです。グレープシティ社の製品である「ComponentOne Studio」の中に含まれています。このライブラリを使用することにより、Excelファイルを活用したアプリケーションを開発できます。

 Excelファイルの読み書きでは、さまざまなタスクを実行できます。例えば、セルの値や数式の読み書き/レイアウトの設定/セルの結合/小計を作成するためのアウトラインレベルの設定/シートの作成/画像の挿入/コメントの挿入 等を行うことができます。

 今回は、このExcelコンポーネントを使って2種類の環境で動くサンプルを用意しました。前半は、 (1)Excelファイルから値を読み取りデータを登録する機能、(2)データの一覧が出力されたExcelファイルをダウンロードできる機能、の2つの機能をASP.NET MVC 5のWebアプリケーションで実装します。後半では、別のサンプルとして、簡単なExcelファイルの処理をクラウド上のMicrosoft Azure Functions上で動かします。

作成するWebアプリケーションの概要図
作成するWebアプリケーションの概要図
Azure Functions上での動作を表す概要図
Azure Functions上での動作を表す概要図

特徴・必要システム

 このライブラリの特徴は、サーバーにExcelをインストールする必要がないことと、メソッド一つでシート・セル・行・列等を扱う操作性の良さです。また、.NET Framework上で動作するため、ASP.NET WebForms/ASP.NET MVC 5/ASP.NET Core MVC(.NET Framework版)といったWebフレームワークだけでなく、WPFやWindows Forms上に組み込むことができます。.NET Frameworkが動作する環境であれば、クラウド上での稼働も可能です。また、グレープシティ社によるテクニカルサポートを受けられます。対応するExcelファイルの種類と必要システムは以下の通りです。

対応するExcelファイルの種類

  • Excel 97~Excel2003のバイナリファイル形式(.xls)
  • Excel 2010およびExcel 2007のXMLベースファイル形式(.xlsx)
  • Excel 2010およびExcel 2007のExcelテンプレート用のファイル形式(.xltx)
  • VBAマクロが有効なExcel 2007/2016のファイル形式(.xlsm)
  • (単純なカンマ区切り値CSV形式)

必要システム

  • OS:Windows 7~Windows Server 2016
  • Webサーバー:Internet Information Services
  • .NET Frameworkのバージョン:.NET Framework 4.5.2以上

 詳細は、ComponentOne Studioリリースノート/必要システムをご参照ください。

対象読者

  • Excelファイルを使ったWebアプリケーションの開発に興味のある方
  • ASP.NET開発者

必要な環境

  • ASP.NET MVC 5アプリケーションの開発ができる環境。今回作成するサンプルでは、筆者はVisual Studio 2017で動作確認しています。
  • Excel 2016(アプリケーションを使用するユーザーとしてExcelファイルの作成や閲覧に使用します。)

ComponentOne Studio for ASP.NET MVCとは

 Excelコンポーネントは、グレープシティ社が提供する有償製品「ComponentOne Studio for ASP.NET MVC」に含まれるコンポーネントの1つです。他に、データグリッド・チャート・帳票・ナビゲーション等のリッチなUIを提供するコンポーネントが含まれています。Excelの活用だけでなく、これらのコンポーネントを組み合わせることにより、開発生産性を向上させることができます。「ComponentOne Studio for ASP.NET MVC」は、ASP.NET Coreにも対応しています。ASP.NET Coreでは、先ほど挙げたUIを実現するためのTag Helperが含まれており、NuGetパッケージによりライブラリを参照できます。

注意:Excelコンポーネントは、.NET Core版には対応していないため、ASP.NET Core MVCフレームワークで使用するには.NET Frameworkを対象にする必要があります。「ComponentOne Studio for ASP.NET MVC」の他のコンポーネントは .NET Core版に対応しています。

ASP.NET MVC 5でWebアプリケーションを作成する

 初めに、Visual Studioが提供するスキャフォールディング機能(scaffolding:足場。ここでは、基礎的なコードをツールで生成するという意味あい)により、あるエンティティのCRUD操作を行うWebアプリケーションを手早く作成します。その後、次の2つのExcelの機能を実装します。

  1. エンティティの情報を記述したExcelファイルをアップロードすることで、エンティティを一括登録できる
  2. エンティティ一覧を出力したExcelファイルをダウンロードできる

 エンティティは例としてトレーニングのログとし、以下の図のように、日々の腹筋回数や体重を確認できるWebアプリケーションを作成します。

 このサンプルでは、スキャフォールディングで生成されるコードを元に、Entity Frameworkのコードファーストでデータべースのスキーマを定義し、SQL Serverデータベースファイルにデータを登録します。ちなみに、今回はEntity FrameworkやSQL Serverを使っていますが、Excelコンポーネントを使用する上では必須条件ではありませんので、別のデータベースやO/R Mapperを選択することもできます。

 以下の手順は、ASP.NET Core MVC(.NET Framework版)においてもほぼ同じ手順で行うことができますが、その場合Entity FrameworkやASP.NET Core MVCフレームワークのAPIが若干違いますのでご注意ください。

Excel コンポーネントのインストールとライセンス認証

 Excelコンポーネントを使用するには、「ComponentOne Studio」をインストールする必要があります。今回は、ASP.NET MVC上で使用するので、「ComponentOne Studio for ASP.NET MVC」をインストールします。はじめは、プロダクトキーを入力せずにインストールすることで、トライアル版として使用できます。

 インストール後、Visual Studio 2017を起動し、ASP.NET MVC 5アプリケーションのプロジェクトを作成します。[ファイル][新規作成][プロジェクト]から、テンプレート「ASP.NET Web アプリケーション(.NET Framework)」を選択し、プロジェクトを作成します。次のダイアログにて、「MVC」テンプレートを選択し、[OK]をクリックします。

 作成したプロジェクトにて、「C1.C1Excel.4.dll」の参照を追加します。dllファイルの場所は、ComponentOne Studioのインストール先の場所にあります(例:C:\Program Files (x86)\ComponentOne\Studio for ASP.NET MVC\Bin\v4)。

 次に、ライセンス認証を行います。「ComponentOne Studio for ASP.NET MVC」についてのライセンス認証は、以下のサイトを参照します。

 このライセンス認証は、トライアル版を使用する場合でも必要です。ここでは、サンプルの実行のために最低限の範囲で操作説明をします。

 プロジェクトの「Properties」を右クリックし、[追加][新しい項目]を選択します。項目の種類は「テキストファイル」を選択し、「Licenses.licx」という名前を入力し、[追加]をクリックします。作成したファイルに、「C1.C1Excel.C1XLBook, C1.C1Excel.4」と記述します。

 ライセンス認証が行われたマシンでこのプロジェクトをビルドすると、ビルドの出力結果にライセンス情報が含まれます。これは、.NET Frameworkのライセンス認証の仕組みによるものです。

 また、トライアル版の場合は、実行時に次のようなダイアログが表示されるので、随時「OK」をクリックしてデバッグを続行します。

 以上により、Excelコンポーネントを使用する準備が完了します。

スキャフォールディング機能によりCRUDを実装する

 まず、データを表すエンティティのクラスを定義します。体重や腹筋回数などのプロパティを持つ「TrainingLog」クラスを定義します。プロジェクト内の「Models」フォルダ内に「TrainingLog.cs」ファイルを作成し、以下のようにコードを記述します。

using System;
using System.ComponentModel.DataAnnotations;

namespace Miso.C1ExcelSample.Models
{
	public class TrainingLog
	{
		public int Id { get; set; }
		public DateTime Date { get; set; }
		[Required]
		public string Name { get; set; }
		/// <summary>
		/// 体重
		/// </summary>
		[Display(Name = "体重")]
		public double BodyWeight { get; set; }
		/// <summary>
		/// スクワット
		/// </summary
		[Display(Name = "スクワット")]
		public int SquatCount { get; set; }
		/// <summary>
		/// 腕立て伏せ
		/// </summary>
		[Display(Name = "腕立て伏せ")]
		public int PushupCount { get; set; }
		/// <summary>
		/// 腹筋
		/// </summary>
		[Display(Name = "腹筋")]
		public int SitupCount { get; set; }
	}
}

 次に、「Controllers」フォルダを右クリックし、[追加][コントローラー]を選択します。表示されるダイアログにて、「Entity Frameworkを使用した、ビューがあるMVC 5コントローラー」を選択し「追加」をクリックします。

 そして表示されるダイアログにて、モデルクラスに先ほど定義したクラス「TrainingLog」を指定します。次に、右側の「+」ボタンをクリックし、データコンテキストクラスを選択し、[OK]をクリックします。

 スキャフォールディングの処理が終了すると、TrainingLogエンティティの追加・編集・詳細・削除を実装するTrainingLogsControllerクラスと、ビューであるcshtmlのファイルの一式が生成されていることが確認できます。デバッグを実行し、URL「/TrainingLogs」にアクセスして一覧ページを表示してください。このページからデータの追加等を行うことができます。

機能(1) Excelファイルから値を読み取りデータを登録する

 それでは、Excelコンポーネントを使用した機能を実装します。はじめに、以下の図のようなExcel2016のファイルをWebアプリケーションにアップロードすると、記載した内容のデータを一括で登録する機能を実装します。

一行につき1つのデータの内容を記述したExcelファイル)
一行につき1つのデータの内容を記述したExcelファイル)

手順

 Webアプリケーションにファイルをアップロードするためのフォームを作成します。「Models」フォルダに「UploadModel.cs」クラスを、「Views」の下の「TrainingLogs」フォルダ(※)に「Upload.cshtml」を作成し、次のように記述します。これらの記述はASP.NET MVCにてファイルをアップロードする機能の一般的な実装になりますので、説明を省きます。

※ 「Views」の下の「TrainingLogs」フォルダは、前述の「スキャフォールディング」の手順により生成されたフォルダです。

UploadModel.cs
using System.Web;

namespace Miso.C1ExcelSample.Models
{
	public class UploadModel
	{
		public HttpPostedFileWrapper PostedFile { get; set; }
	}
}
Upload.cshtml
@{ ViewBag.Title = "Upload"; }
@model Miso.C1ExcelSample.Models.UploadModel
<h2>Upload</h2>

<form action="/TrainingLogs/Upload" enctype="multipart/form-data" method="post">
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(excludePropertyErrors: false, message: "", htmlAttributes: new { @class = "text-danger" })
    <input type="file" name="@Html.NameFor(m => m.PostedFile)" />
    <input type="submit" value="Upload"/>
</form>
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

 次に、「TrainingLogsController.cs」のクラスの中に、次のようにメソッドを2つ追記します。

[HttpGet]
public ActionResult Upload()
{
  return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Upload(UploadModel model)
{
  //ファイルが送信されているか検証します
  if ((model?.PostedFile?.ContentLength ?? 0) == 0)
  {
  ModelState.AddModelError(nameof(model.PostedFile), "ファイルを送信して下さい。");
  return View();
  }
  Stream stream = model.PostedFile.InputStream;
  //C1XLBookオブジェクトを作成し、送信されたExcelファイルを読み込みます。
  var excelBook = new C1XLBook();
  excelBook.Load(stream, FileFormat.OpenXml);

  var logList = new List<TrainingLog>();
  //Excelに入力のある行数を取得します
  int inputMaxRowCount = excelBook.Sheets[0].Rows.Count;
  for(int rowIndex = 0; rowIndex < (inputMaxRowCount - 1); rowIndex += 1)
  {
  if (rowIndex == 0) continue; //最初の行はヘッダー行なので処理しない
  //日付のセルの値を取得します
  var dateValue = excelBook.Sheets[0].GetCell(rowIndex, colIndex:0)?.Text;
  if (!DateTime.TryParse(dateValue, out DateTime date))
  {
    //日付でない場合は処理をしない
    continue;
  }
  string name = excelBook.Sheets[0].GetCell(rowIndex, 1)?.Value as string;
  double.TryParse(excelBook.Sheets[0].GetCell(rowIndex, 2)?.Text, out double bodyWeight);
  int.TryParse(excelBook.Sheets[0].GetCell(rowIndex, 3)?.Text, out int squatCount);
  int.TryParse(excelBook.Sheets[0].GetCell(rowIndex, 4)?.Text, out int pushupCount);
  int.TryParse(excelBook.Sheets[0].GetCell(rowIndex, 5)?.Text, out int situpCount);
  var log = new TrainingLog
  {
    Date = date, Name = name, BodyWeight = bodyWeight,
    SquatCount = squatCount, PushupCount  = pushupCount, SitupCount = situpCount,
  };
    logList.Add(log);
  }

  //データを保存します
  db.TrainingLogs.AddRange(logList);
  await db.SaveChangesAsync();

  return RedirectToAction("Index");
}

実行例

 ここで、Webアプリケーションをデバッグ実行し、URL「/TrainingLogs/Upload」にアクセスして先ほどのExcelファイルをアップロードします。

補足

 ここでC# 7の文法に関するコンパイルエラーが発生する場合は、NuGetパッケージ「Microsoft.Net.Compilers」をバージョンアップしてください。執筆時はバージョン2.1にアップデートできます。

「/TrainingLogs/Upload」にアクセスしたときの画面
「/TrainingLogs/Upload」にアクセスしたときの画面

 Excelファイルをアップロードした後、「TrainingLogs/」でアクセスする一覧画面にて、複数のデータが登録できたことを確認します。

解説

 これで機能(1)の実装は完了です。「TrainingLogsController.cs」に追記したUploadメソッドについて補足します。ファイルを送信された時に実行するUploadメソッドが、Excelファイルを読み取り、データを登録する処理を行っている部分です。

 このUploadメソッドではまず、C1XLBookオブジェクト(C1.C1Excel名前空間)を生成し、C1XLBook クラスのLoadメソッドにて、送信されたExcelのファイルの内容をロードしています。このLoadメソッドでは、Streamオブジェクト(System.IO名前空間)やファイルパスの指定によりExcelファイルを読み取ることができます。第二引数では、Excelファイルのバージョンを指定しています。

Stream stream = model.PostedFile.InputStream;
//C1XLBookオブジェクトを作成し、送信されたExcelファイルを読み込みます。
var excelBook = new C1XLBook();
excelBook.Load(stream, FileFormat.OpenXml);

 次に、Excelファイルに入力されている行数の最大値を「excelBook.Sheets[0].Rows.Count」で取得し、入力された行数分ループし、その行に記述されたセルの値を読み取ります。

//Excelに入力のある行数を取得します
int inputMaxRowCount = excelBook.Sheets[0].Rows.Count;
for(int rowIndex = 0; rowIndex < (inputMaxRowCount - 1); rowIndex += 1)
{
	if (rowIndex == 0) continue; //最初の行はヘッダー行なので処理しない
	//日付のセルの値を取得します
	var dateValue = excelBook.Sheets[0].GetCell(rowIndex, colIndex:0)?.Text;
//省略

 セルの値は、「excelBook.Sheets[0].GetCell(rowIndex, colIndex:0)?.Text」といったように、行インデックスと列のインデックスを指定して、テキストの値を読み取ります。

機能(2) データの一覧が出力されたExcelファイルを生成する

 次は、Excelファイルをダウンロードできる機能を実装します。このExcelファイルには、登録されているデータの一覧が記載されているものとします。Excelコンポーネントではゼロからファイルを作成することもできますが、ここでは、あらかじめ用意されたExcelファイルをテンプレートとして利用します。

手順

 下の図のようなExcelファイルを用意し、プロジェクトの「App_Data」フォルダ配下に「フィットネスtemplate.xlsx」として配置します。このExcelファイルの「H3」のセルには、「Name」という値で名前を定義します。後に、このセルに名前を書き込みます。Excelの名前定義については、「数式で名前を定義し使用する - Excel」を参照してください。

用意したExcelファイル。H3のセルに「Name」の値で名前定義を設定済み。7行目から値を書き込みます。
用意したExcelファイル。H3のセルに「Name」の値で名前定義を設定済み。7行目から値を書き込みます。
プロジェクトにExcelファイルを追加したときのソリューションエクスプローラー。
プロジェクトにExcelファイルを追加したときのソリューションエクスプローラー。

 「TrainingLogsController.cs」に、次のように「Download」メソッドを追記します。

/// <summary>
/// 一覧をExcelファイルとして取得します
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<ActionResult> Download()
{
  string templateFilePath = @"~\App_Data\フィットネスtemplate.xlsx";
  var excelBook = new C1XLBook();
  excelBook.Load(Server.MapPath(templateFilePath));
  var sheet = excelBook.Sheets[0];

  var list = await db.TrainingLogs.OrderBy(log => log.Date).ToListAsync();

  //名前を出力する
  string name = list.FirstOrDefault()?.Name;
  foreach(XLNamedRange range in excelBook.NamedRanges)
  {
    //名前の定義がNameのみ後述の処理を行う
    if (range.Name != "Name") continue;
    //名前が定義されているセルの位置を特定します
    int colIndex = range.CellRange.ColumnFrom;
    int rowIndex = range.CellRange.RowFrom;
    //セルに名前を出力します
    sheet[rowIndex, colIndex].Value = name;
  }

  //セルのスタイルを参照する行インデックスを定義
  int styleRowIndex = 6;
  //データの1行目の各セルのスタイルを取得します。あとでこのスタイルをデータ行に適用します。
  //key: 列インデックス、value: XLStyleクラス
  Dictionary<int, XLStyle> styleDictionary = Enumerable.Range(1, 5)
  .ToDictionary(col => col, col => sheet[styleRowIndex, colIndex: col].Style);

  int dataRowIndex = 6;
  foreach (var log in list)
  {
//列インデックス1には、日付、列インデックス2には、体重…といったように各値を書き込みます
    sheet[dataRowIndex, colIndex: 1].SetValue(log.Date, styleDictionary[1]);
    sheet[dataRowIndex, colIndex: 2].SetValue(log.BodyWeight, styleDictionary[2]);
    sheet[dataRowIndex, colIndex: 3].SetValue(log.SquatCount, styleDictionary[3]);
    sheet[dataRowIndex, colIndex: 4].SetValue(log.PushupCount, styleDictionary[4]);
    sheet[dataRowIndex, colIndex: 5].SetValue(log.SitupCount, styleDictionary[5]);
    dataRowIndex += 1;
  }

  var stream = new MemoryStream();
  excelBook.Save(stream, FileFormat.OpenXml);
  stream.Position = 0;
  return File(stream, contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileDownloadName: "list.xlsx");
}

実行例

 ここで、デバッグ実行をし、URL「TrainingLogs/Download」にアクセスすると、Excelファイルがブラウザによってダウンロードされることを確認します。作成されたExcelファイルは次の図のようになります。

解説

 こちらも、Downloadメソッドの内容について説明します。まず、次のように、あらかじめ用意されたExcelファイルを読み込みます。

string templateFilePath = @"~\App_Data\フィットネスtemplate.xlsx";
var excelBook = new C1XLBook();
excelBook.Load(Server.MapPath(templateFilePath));

 次に、「Name」名前で定義されたセルを特定し、名前を書き込みます。行・列インデックスではなく名前の定義によりセルを特定することで、デザインの変更に柔軟に対応できます。

foreach(XLNamedRange range in excelBook.NamedRanges)
{
	//名前の定義がNameのみ後述の処理を行う
	if (range.Name != "Name") continue;
	//名前が定義されているセルの位置を特定します
	int colIndex = range.CellRange.ColumnFrom;
	int rowIndex = range.CellRange.RowFrom;
	//セルに名前を出力します
	sheet[rowIndex, colIndex].Value = name;
}

 データの行には、文字色や書式設定などのスタイルが設定されています。次の処理では、データの個数が可変であってもすべての行にスタイルを適用するために、データ1行目に設定されたスタイルを保存しておき、行を書き込むときに適用しています。SetValueメソッド(C1.C1Excel名前空間のXLCellクラス)で、セルに値を書き込むと同時にスタイルの設定を行います。

  //セルのスタイルを参照する行インデックスを定義
  int styleRowIndex = 6;
  //データの1行目の各セルのスタイルを取得します。あとでこのスタイルをデータ行に適用します。
  //key: 列インデックス、value: XLStyleクラス
  Dictionary<int, XLStyle> styleDictionary = Enumerable.Range(1, 5)
  .ToDictionary(col => col, col => sheet[styleRowIndex, colIndex: col].Style);

  int dataRowIndex = 6;
  foreach (var log in list)
  {
    //列インデックス1には、日付、列インデックス2には、体重…といったように各値を書き込みます
    sheet[dataRowIndex, colIndex: 1].SetValue(log.Date, styleDictionary[1]);
    sheet[dataRowIndex, colIndex: 2].SetValue(log.BodyWeight, styleDictionary[2]);
    sheet[dataRowIndex, colIndex: 3].SetValue(log.SquatCount, styleDictionary[3]);
    sheet[dataRowIndex, colIndex: 4].SetValue(log.PushupCount, styleDictionary[4]);
    sheet[dataRowIndex, colIndex: 5].SetValue(log.SitupCount, styleDictionary[5]);
    dataRowIndex += 1;
  }

 また、本筋から離れますが、「ComponentOne Studio for ASP.NET MVC」の他のコンポーネントを使用すると、次のような表やグラフの描画を行うことができます。

Azure FunctionsでExcelファイルを読み書きする

 Excelコンポーネントは、.NET Framework向けのライブラリなので、サーバー以外のクライアントアプリであるWPF等でも動作し、ASP.NET MVCが動作する環境と同じであればクラウド上でも動作します。Microsoft Azureの場合は、IaaSの仮想マシンやPaaSのApp Service・WebJob、さらにサーバーレスアーキテクチャのサービスのAzure Functionsの選択肢があります。ただし、ComponentOne Studioはライセンス製品なので、認証されたマシンで予めビルドが必要になるなど、ライセンスの考慮は必要になります。

 Excelファイルの処理を、例えばAzure Functionsに切り出すことにより、Excelファイルの処理にのみリソース(マシンのリソースや、料金等)を集中できます。例えば、1日1回のバッチとして動かしたり、HTTPをトリガーとして起動して結果をメールで送信したりする、といった構成を素早く立ち上げることができます。

 ここでは、Azure FunctionsにてExcelファイルを読み書きする処理を動かす方法を簡単に紹介します。Azure BLOBストレージ上にExcelファイルが配置されたときをトリガーとし、生成したExcelファイルは同じくAzure BLOBストレージ上に配置するよう設定します。

 Azure Functionsでは、JavaScript・C#・F#など、さまざまな言語で関数を作成でき、直接Azureポータルのサイトからコードを記述できます。また、関数をC#で記述したファイル(.cs)を事前にコンパイルし、dllファイルをアップロードすることもできます。今回はライセンス認証のために事前にビルドが必要なので、後者の方法を選択します。以下のサイトから、ベースとなるプロジェクトをダウンロードします(または、本記事に添付しているサンプルファイル内のPreCompiledFunctionSampleを利用します)。

 Azure Functionsにおけるプリコンパイルのサポートについてはこちらを参照します。

 先述のように、ライセンスファイル「License.licx」を追加し、「C1.C1Excel.4.dll」を参照します。

 プロジェクト内の「MyFuncrions.cs」クラスには、次のように記述します。ここでは、Azure BLOBストレージにアップロードされたExcelファイルを読み取り、一番左上のセルに「よくできました!」と書き込む処理を記述しています。MyFunctionクラスのRunメソッドの引数には、Azure Functionsにより、それぞれ次のように内容がバインドされます。myBlob変数にはトリガーとなったBLOBファイルが、name変数には、トリガーとなったBLOBファイルの名前が、outputBlob変数には出力先となるBLOBファイルの参照がバインドされます。

MyFuncrions.cs
using C1.C1Excel;
using System.IO;
using System.Threading.Tasks;

namespace PreCompiledFunctionSample
{
  public class MyFunction
  {
  public static async Task Run(Stream myBlob, string name, Stream outputBlob)
    {
      using (var input = new MemoryStream())
      using (var output = new MemoryStream())
      {
        myBlob.CopyTo(input);
        var excelBook = new C1XLBook();
        excelBook.Load(input, FileFormat.OpenXml);

        XLSheet sheet = excelBook.Sheets[0];
        sheet[rowIndex: 0, colIndex: 0].Value = "よくできました!";

        excelBook.Save(output, FileFormat.OpenXml);

        var byteArray = output.ToArray();
        await outputBlob.WriteAsync(byteArray, 0, byteArray.Length);
      }
    }
//省略

 プロジェクトをビルドした後、生成された「PreCompiledFunctionSample.dll」と「C1.C1Excel.4.dll」と「function.json」の3つのファイルを、Azure Functions上にアップロードします。次の図は、Azureポータルサイトでアップロードした後の画面です。

 トリガーと出力の設定は、Azure ポータルサイト上から行うか、または「function.json」でコードベースで設定します。次の図は、Azureポータルサイトから行った時の図です。

function.json
{
  "bindings": [
    {
      "type": "blobTrigger",
      "name": "myBlob",
      "path": "mycontainer/{name}",
      "connection": "c1func8159_STORAGE",
      "direction": "in"
    },
    {
      "type": "blob",
      "name": "outputBlob",
      "path": "outcontainer/{name}",
      "connection": "c1func8159_STORAGE",
      "direction": "out"
    }
  ],
  "scriptFile": "PreCompiledFunctionSample.dll",
  "entryPoint": "PreCompiledFunctionSample.MyFunction.Run",
  "disabled": false
}

 Azure Functionsを起動後、Azure BLOBストレージの「mycontainer」コンテナーに「Book1.xlsx」ファイルをアップロードすると、処理が開始され、「outcontainer」コンテナーに「Book1.xlsx」ファイルが生成されることが確認できます。

まとめ

 Excelコンポーネントを使用すると、Excelファイルの読み書きを行うプログラムを記述できます。.NET Framework上で動作するので、ASP.NET MVC等で作成したWebアプリケーションにExcelファイルを活用した機能を搭載できます。また、Azure Functionsなどのクラウド上でも動作するので、Excelファイルの処理に合わせた構成が可能です。

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 矢後 比呂加(ヤゴ ヒロカ)

     Microsoft MVP for Visual Studio and Development Technologies(https://mvp.microsoft.com/ja-jp/PublicProfile/5000246)  シグマコンサルティング株式会社にて、Microsoft Azu...

All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5