本記事では、AWS Lambdaで「DioDocs(ディオドック)」を使用したC#( .NET Core 3.1)のLambda関数アプリケーションを作成し、ExcelやPDFファイルを出力する方法について紹介します。
目次
AWS Lambdaとは
AWS LambdaはAmazon Web Servicesで提供されている、各種イベントをトリガーに処理を実行するサーバーレスなアプリケーションを作成できるクラウドサービスです。
AWS Lambdaは.NET Core 3.1をサポートしており、C#で .NET CoreベースのLambda関数を作成できます。今回はAWS Toolkit for Visual Studioを使用してVisual Studio 2019でLambda関数を作成し、AWSへデプロイして確認してみます。
実装する内容
今回実装する内容は非常にシンプルです。AWS LambdaアプリケーションでAmazon API GatewayからHTTPリクエストを受け取るLambda関数を作成します。この関数の実行時にDioDocsを使用してExcelとPDFファイルを作成し、HTTPリクエストのクエリパラメータで受け取った文字列を追加します。その後、作成したExcelとPDFファイルを関数からAmazon API Gatewayに渡してHTTPレスポンスで直接ローカルへ出力する、といった内容です。
AWS Toolkit for Visual Studioのセットアップ
Visual Studio 2019へのAWS Toolkit for Visual StudioのインストールとAWSの認証情報の設定は以下を参考にして準備しておきます。
AWS Toolkit for Visual Studio をセットアップする – AWS Toolkit for Visual Studio
AWS 認証情報を提供する – AWS Toolkit for Visual Studio
AWS Lambdaアプリケーションを作成
以下のドキュメントを参考にAWS Lambdaアプリケーションを作成していきます。
チュートリアル: AWS Toolkit for Visual Studio の AWS Lambda プロジェクトを使用する – AWS Toolkit for Visual Studio
Visual Studio 2019でプロジェクトテンプレート「AWS Lambda Project (.NET Core – C#)」を選択して[次へ]をクリックします。
プロジェクト名に「ExcelExportAWSLambda1」を入力して[作成]をクリックします。
AWS Lambda Projectのテンプレートを選択します。「Empty Function」を選択して[Finish]をクリックします。
「ExcelExportAWSLambda1」プロジェクトが作成されます。
NuGetパッケージを追加
Visual Studioの「NuGet パッケージ マネージャー」からAmazon API Gatewayのイベントを処理するためのパッケージ「Amazon.Lambda.APIGatewayEvents」とDioDocs for Excelのパッケージ「GrapeCity.DioDocs.Excel.ja」をインストールします。
Amazon API Gatewayを使うコードを追加
Lambda関数がAmazon API GatewayからHTTPリクエストを受け取り、Lambda関数からAPI GatewayへHTTPレスポンスを返すために、以下のようにFunctionHandler
の引数と戻り値にAPIGatewayProxyRequest
とAPIGatewayProxyResponse
を設定します。
public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest input, ILambdaContext context)
DioDocs for Excelを使うコードを追加
DioDocs for ExcelでExcelファイルを作成するコードを追加してFunctionHandler
を以下のように更新します。
public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest input, ILambdaContext context)
{
APIGatewayProxyResponse response;
string queryString;
input.QueryStringParameters.TryGetValue("name", out queryString);
string Message = string.IsNullOrEmpty(queryString)
? "Hello, World!!"
: $"Hello, {queryString}!!";
//Workbook.SetLicenseKey("");
Workbook workbook = new Workbook();
workbook.Worksheets[0].Range["A1"].Value = Message;
var base64String = "";
using (var ms = new MemoryStream())
{
workbook.Save(ms, SaveFileFormat.Xlsx);
base64String = Convert.ToBase64String(ms.ToArray());
}
response = new APIGatewayProxyResponse
{
StatusCode = (int)HttpStatusCode.OK,
Body = base64String,
IsBase64Encoded = true,
Headers = new Dictionary<string, string> {
{ "Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
{ "Content-Disposition", "attachment; filename=Result.xlsx"},
}
};
return response;
}
DioDocs for Excelで作成したExcelファイルをMemoryStream
に保存し、これを一旦base64エンコードしています。これを文字列base64String
としてAPIGatewayProxyResponse
のBody
に設定してAmazon API Gatewayに渡すようにしています。
作成したExcelファイルをbase64にエンコードする理由ですが、Lambda関数とAmazon API Gatewayを連携させる「AWS Lambdaプロキシ統合」を利用する際の決まり事になっています。
AWS Lambda プロキシ統合からバイナリメディアを返すには、Lambda 関数からのレスポンスを base64 でエンコードします。また、API のバイナリメディアタイプを設定する必要があります。
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/lambda-proxy-binary-media.html
デバッグ実行で確認
作成したLambda関数アプリケーションをローカルでデバッグ実行して確認します。F5キーをクリックするとMock Lambda Test Toolが起動します。
Example Requestsに「API Gateway AWS Proxy」を設定して[Exceute Function]をクリックします。
Responseのbodyにbase64にエンコードされた文字列が格納されていればOKです。
AWSへデプロイ
作成したLambda関数アプリケーションをAWSへデプロイして確認します。ソリューションエクスプローラーから「ExcelExportAWSLambda1」プロジェクトを右クリックして「Publish to AWS Lambda」を選択します。
「Function Name」にDioDocsExcelExport
を入力して[Next]をクリックします。
「Role Name」にNew role based on AWS managed policy: AWSLambda_FullAccess
を設定して[Upload]をクリックします。
成功すると以下の画面が表示されます。
AWSのコンソールでAWS Lambdaの「関数」を選択するとデプロイしたLambda関数「DioDocsExcelExport」が表示されます。
トリガーの追加
デプロイしたLambda関数「DioDocsExcelExport」をクリックして以下の画面から[トリガーを追加]をクリックします。
「API Gateway」を選択し、さらに「APIを作成する」を選択します。作成するAPIタイプは「REST API」を選択して、セキュリティは「オープン」を選択します。この状態で[追加]をクリックします。
以下のようにトリガーにAPI Gatewayが追加されます。
API Gatewayのバイナリメディアタイプを設定
AWSのコンソールで作成したAPI「DioDocsExcelExport-API」の「設定」からバイナリメディアタイプを「*/*」で追加します。追加後に[変更の保存]をクリックします。
「*/*」を設定する理由ですが、 Lambda関数とAmazon API Gatewayを連携させる「AWS Lambdaプロキシ統合」を利用する際の決まり事になっています。
この統合例でウェブブラウザを使用して API を呼び出すには、API のバイナリメディアタイプを
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/lambda-proxy-binary-media.html*/*
に設定します 。API Gateway は、クライアントからの最初のAccept
ヘッダーを使用して、レスポンスがバイナリメディアを返すかどうかを判断します。ブラウザからのリクエストなど、Accept
ヘッダー値の順序を制御できない場合に、バイナリメディアを返すには、API のバイナリメディアタイプを*/*
(すべてのコンテンツタイプ) に設定します。
この設定ですが、気を利かせたつもりでapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet
など、固有のバイナリメディアタイプを設定してしまうとbase64エンコードされたただの文字列が出力されてしまうので注意が必要です。
デプロイしたアプリケーションを確認
AWSのコンソールで作成したAPI「DioDocsExcelExport-API」の「リソース」から[アクション]をクリックし、「APIのデプロイ」を選択します。
デプロイされるステージは「default」を選択して[デプロイ]をクリックします。
API「DioDocsExcelExport-API」の「ステージ」から「default – GET – /DioDocsExcelExport」を選択します。
「URLの呼び出し」に表示されているAPIのURLをコピーしてブラウザに張り付けて、さらにクエリパラメータと文字列「?name=DioDocsForExcel」を追加します。
このAPIを実行するとクエリパラメータで渡した文字列「DioDocsForExcel」が追加されたExcelファイル「Result.xlsx」がローカルに出力されます。
PDFを出力するには?
Visual Studioの「NuGet パッケージ マネージャー」から DioDocs for PDFのパッケージ「GrapeCity.DioDocs.Pdf.ja」をインストールします。 DioDocs for PDFでPDFファイルを作成するコードを追加してFunctionHandler
を以下のように更新します。PDFファイルを出力するのでそれに合わせてAPIGatewayProxyResponse
のHeader
の内容も変更しています。
public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest input, ILambdaContext context)
{
APIGatewayProxyResponse response;
string queryString;
input.QueryStringParameters.TryGetValue("name", out queryString);
string Message = string.IsNullOrEmpty(queryString)
? "Hello, World!!"
: $"Hello, {queryString}!!";
//GcPdfDocument.SetLicenseKey("");
GcPdfDocument doc = new GcPdfDocument();
GcPdfGraphics g = doc.NewPage().Graphics;
g.DrawString(Message,
new TextFormat() { Font = StandardFonts.Helvetica, FontSize = 12 },
new PointF(72, 72));
var base64String = "";
using (var ms = new MemoryStream())
{
doc.Save(ms, false);
base64String = Convert.ToBase64String(ms.ToArray());
}
response = new APIGatewayProxyResponse
{
StatusCode = (int)HttpStatusCode.OK,
Body = base64String,
IsBase64Encoded = true,
Headers = new Dictionary<string, string> {
{ "Content-Type", "application/pdf" },
{ "Content-Disposition", "attachment; filename=Result.pdf"},
}
};
return response;
}
さいごに
動作を確認できるAWS Lambdaアプリケーションのサンプルはこちらです。
https://github.com/GrapeCityJP/ExcelExportAWSLambda1
https://github.com/GrapeCityJP/PDFExportAWSLambda1
本記事ではAWS LambdaとAmazon API Gatewayで作成したAPIを使用して直接ローカルへExcelとPDFファイルを出力する方法を紹介しましたが、ファイルの保存先としてAmazon S3を使うより実践的な方法もあります。こちらは次回の記事で紹介しています。
弊社Webサイトでは、製品の機能を気軽に試せるデモアプリケーションやトライアル版も公開していますので、こちらもご確認いただければと思います。
また、ご導入前の製品に関するご相談やご導入後の各種サービスに関するご質問など、お気軽にお問合せください。