AWS LambdaとDioDocsでExcelやPDFファイルを出力する(2)

前回に引き続き、本記事でも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レスポンスで直接ローカルへ出力していましたが、今回は作成したExcelとPDFファイルをAmazon S3へ出力します。Amazon S3への保存にはAWS SDK for .NETを使用します。

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#)」を選択して[次へ]をクリックします。

AWS Lambdaアプリケーションを作成

プロジェクト名に「ExcelExportAWSLambda2」を入力して[作成]をクリックします。

AWS Lambdaアプリケーションを作成

AWS Lambda Projectのテンプレートを選択します。「Empty Function」を選択して[Finish]をクリックします。

AWS Lambdaアプリケーションを作成

「ExcelExportAWSLambda2」プロジェクトが作成されます。

AWS Lambdaアプリケーションを作成

NuGetパッケージを追加

Visual Studioの「NuGet パッケージ マネージャー」からAmazon API Gatewayのイベントを処理するためのパッケージ「Amazon.Lambda.APIGatewayEvents」とAmazon S3を使うためのパッケージ「AWSSDK.S3」、そしてDioDocs for Excelのパッケージ「GrapeCity.DioDocs.Excel.ja」をインストールします。

AWS Lambdaアプリケーションを作成

Amazon S3にバケットを作成

Amazon S3にDioDocs for Excelで作成したExcelファイルの保存先になるバケット「diodocs-export」を、Visual Studioの「AWS Explorer」から作成します。

Amazon S3にバケットを作成

Amazon API Gatewayを使うコードを追加

Lambda関数がAmazon API GatewayからHTTPリクエストを受け取り、Lambda関数からAmazon API GatewayへHTTPレスポンスを返すために、以下のようにFunctionHandlerの引数と戻り値にAPIGatewayProxyRequestAPIGatewayProxyResponseを設定します。

public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest input, ILambdaContext context)

DioDocs for Excelを使うコードを追加

DioDocs for ExcelでExcelファイルを作成するコードを追加してFunctionHandlerを以下のように更新します。

public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest input, ILambdaContext context)
{
    APIGatewayProxyResponse response;

    try
    {
        // クエリ文字列を取得
        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;

        using (var ms = new MemoryStream())
        {
            workbook.Save(ms, SaveFileFormat.Xlsx);

            // S3にアップロード
            AmazonS3Client client = new AmazonS3Client(RegionEndpoint.APNortheast1);
            var request = new PutObjectRequest
            {
                BucketName = "diodocs-export",
                Key = "Result.xlsx",
                InputStream = ms
            };

            await client.PutObjectAsync(request);
        }

        response = new APIGatewayProxyResponse
        {
            StatusCode = (int)HttpStatusCode.OK,
            Body = "ファイルが保存されました。",
            Headers = new Dictionary<string, string> {
                { "Content-Type", "text/plain; charset=utf-8" }
            }
        };
    }
    catch (Exception e)
    {
        response = new APIGatewayProxyResponse
        {
            StatusCode = (int)HttpStatusCode.InternalServerError,
            Body = e.Message,
            Headers = new Dictionary<string, string> {
                { "Content-Type", "text/plain" }
            }
        };
    }

    return response;
}

DioDocs for Excelで作成したExcelファイルをMemoryStreamに保存し、これをAmazonS3ClientクラスのPutObjectAsyncメソッドを使用してAmazon S3へアップロードしています。

デバッグ実行で確認

作成したLambda関数アプリケーションをローカルでデバッグ実行して確認します。F5キーをクリックするとMock Lambda Test Toolが起動します。

デバッグ実行で確認

Example Requestsに「API Gateway AWS Proxy」を設定して[Exceute Function]をクリックします。

デバッグ実行で確認

Responseで以下のようにbodyに「ファイルが保存されました。」が表示されていればOKです。

デバッグ実行で確認

AWS Explorerから「diodocs-export」をクリックして、DioDocs for Excelで作成したExcelファイル「Result.xlsx」がアップロードされているか確認できます。なお、AWSへデプロイした後にも確認するのでアップロードしたExcelファイルはここで一旦削除しておきます。

デバッグ実行で確認

AWSへデプロイ

作成した Lambda関数 アプリケーションをAWSへデプロイして確認します。ソリューションエクスプローラーから「ExcelExportAWSLambda2」プロジェクトを右クリックして「Publish to AWS Lambda」を選択します。

AWSへデプロイ

「Function Name」にDioDocsExcelExportToS3を入力して[Next]をクリックします。

AWSへデプロイ

「Role Name」にNew role based on AWS managed policy: AWSLambdaExecuteを設定して[Upload]をクリックします。

AWSへデプロイ

成功すると以下の画面が表示されます。

AWSへデプロイ

AWSのコンソールでAWS Lambdaの「関数」を選択するとデプロイしたLambda関数「DioDocsExcelExportToS3」が表示されます。

AWSへデプロイ

トリガーの追加

デプロイしたLambda関数「DioDocsExcelExportToS3」をクリックして以下の画面から[トリガーを追加]をクリックします。

トリガーの追加

「API Gateway」を選択し、さらに「APIを作成する」を選択します。作成するAPIタイプは「REST API」を選択して、セキュリティは「オープン」を選択します。この状態で[追加]をクリックします。

トリガーの追加

以下のようにトリガーにAPI Gatewayが追加されます。

トリガーの追加

デプロイしたアプリケーションを確認

AWSのコンソールで作成したAPI「DioDocsExcelExportToS3-API」の「リソース」から[アクション]をクリックし、「APIのデプロイ」を選択します。

デプロイしたアプリケーションを確認

デプロイされるステージは「default」を選択して[デプロイ]をクリックします。

デプロイしたアプリケーションを確認

API「DioDocsExcelExportToS3-API」の「ステージ」から「default – GET – /DioDocsExcelExportToS3」 を選択します。

デプロイしたアプリケーションを確認

「URLの呼び出し」に表示されているAPIのURLをコピーしてブラウザに張り付けて、さらにクエリパラメータと文字列「?name=DioDocsForExcel」を追加します。

デプロイしたアプリケーションを確認

このAPIを実行するとクエリパラメータで渡した文字列「DioDocsForExcel」が追加されたExcelファイル「Result.xlsx」がAmazon S3のバケット「diodocs-export」に出力されます。

デプロイしたアプリケーションを確認
デプロイしたアプリケーションを確認
デプロイしたアプリケーションを確認

PDFを出力するには?

Visual Studioの「NuGet パッケージ マネージャー」からDioDocs for PDFのパッケージ「GrapeCity.DioDocs.Pdf.ja」をインストールします。次にDioDocs for PDFでPDFファイルを作成するコードを追加してFunctionHandlerを以下のように更新します。

public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest input, ILambdaContext context)
{
    APIGatewayProxyResponse response;

    try
    {
        // クエリ文字列を取得
        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));

        using (var ms = new MemoryStream())
        {
            doc.Save(ms, false);

            // S3にアップロード
            AmazonS3Client client = new AmazonS3Client(RegionEndpoint.APNortheast1);
            var request = new PutObjectRequest
            {
                BucketName = "diodocs-export",
                Key = "Result.pdf",
                InputStream = ms
            };

            await client.PutObjectAsync(request);
        }

        response = new APIGatewayProxyResponse
        {
            StatusCode = (int)HttpStatusCode.OK,
            Body = "ファイルが保存されました。",
            Headers = new Dictionary<string, string> {
                { "Content-Type", "text/plain; charset=utf-8" }
            }
        };
    }
    catch (Exception e)
    {
        response = new APIGatewayProxyResponse
        {
            StatusCode = (int)HttpStatusCode.InternalServerError,
            Body = e.Message,
            Headers = new Dictionary<string, string> {
                { "Content-Type", "text/plain" }
            }
        };
    }

    return response;
}

さいごに

動作を確認できるAWS Lambdaアプリケーションのサンプルはこちらです。

https://github.com/GrapeCityJP/ExcelExportAWSLambda2

https://github.com/GrapeCityJP/PDFExportAWSLambda2