日本語版
最新ニュース
企業

Syncfusion .Net PDF Fram を使用した PDF 作成用の Azure Function App

社内および社外のユーザーがコンテンツを PDF 形式で印刷する必要があるユース ケースがいくつかあります。この機能は、DXP Web アプリから Docker コンテナーで実行されている Azure Function App にオフロードされています。Syncfusion .Net PDF Framework (注: サブスクリプションが必要) を使用します。最初のユース ケースでは、印刷用のエンドポイントに URL を提供できます。2 番目のユース ケースでは、XHTML コンテンツの配列をエンドポイントに POST します。 Azure Function App を作成する Visual Studio で新しいプロジェクトを作成し、Azure Functions を選択します。 プロジェクトに名前を付ける ここではデフォルトを使用します: .Net…

Syncfusion .Net PDF Fram を使用した PDF 作成用の Azure Function App

1723173439
2024-08-08 16:21:38

社内および社外のユーザーがコンテンツを PDF 形式で印刷する必要があるユース ケースがいくつかあります。この機能は、DXP Web アプリから Docker コンテナーで実行されている Azure Function App にオフロードされています。Syncfusion .Net PDF Framework (注: サブスクリプションが必要) を使用します。最初のユース ケースでは、印刷用のエンドポイントに URL を提供できます。2 番目のユース ケースでは、XHTML コンテンツの配列をエンドポイントに POST します。

Azure Function App を作成する

Visual Studio で新しいプロジェクトを作成し、Azure Functions を選択します。

プロジェクトに名前を付ける

ここではデフォルトを使用します:

  • .Net 8 分離 バージョン
  • HTTP トリガー 関数ではGETとPOSTを使用するため
  • コンテナサポートを有効にする Dockerを活用するため
  • 関数 承認レベルを設定すると、ファンクション キーが必要になります。(この承認レベルで Azure にホストされている場合、エンドポイントにアクセスするためにファンクション キーが必要になります。)

「作成」をクリックします。

これにより、基本的な足場が得られます。

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace TestPdfEndpoint
{
    public class Function1
    {
        private readonly ILogger _logger;

        public Function1(ILogger logger)
        {
            _logger = logger;
        }

        [Function("Function1")]
        public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
        {
            _logger.LogInformation("C# HTTP trigger function processed a request.");
            return new OkObjectResult("Welcome to Azure Functions!");
        }
    }
}

ConvertUrlToPdf関数を追加する

Function1 の名前を ConvertUrlToPdf に変更します。

    public class ConvertUrlToPdf
    {
        private readonly ILogger _logger;

        public ConvertUrlToPdf(ILogger logger)
        {
            _logger = logger;
        }

        [Function("ConvertUrlToPdf")]
        public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
        {
            _logger.LogInformation("C# HTTP trigger function processed a request.");
            return new OkObjectResult("Welcome to Azure Functions!");
        }
    }

IActionResult を非同期タスクに変更し、FunctionContext パラメータを追加します。

public async Task Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req, FunctionContext functionContext)

Syncfusion.HtmlToPdfConverter.Net.Linux nuget パッケージを追加します。関数アプリは Linux でホストされます。このパッケージは、URL を PDF ファイルに変換するという面倒な作業を実行します。nuget には、Blink ヘッドレス Chrome ブラウザが含まれています。

クエリ文字列パラメータとして関数に URL を渡すので、リクエストに「URL」パラメータがあるかどうかを確認します。見つからない場合は EmptyResult を返します。

string urlString = req.Query["url"];

 //return if no url
 if (string.IsNullOrEmpty(urlString))
{
     return new EmptyResult();
 }

Blink バイナリへのパスを取得します。これは、後で設定オブジェクトで必要になります。

var directory = Directory.GetCurrentDirectory();
var blinkBinariesPath = Path.Combine(directory, "runtimes/linux/native");

HTML から PDF へのコンバーターを初期化します。

//Initialize the HTML to PDF converter with the Blink rendering engine.
var htmlConverter = new HtmlToPdfConverter(HtmlRenderingEngine.Blink)
 {
       ConverterSettings = null,
       ReuseBrowserProcess = false
};

設定オブジェクトを作成し、値を設定します。これらのコマンド ライン引数設定は、Syncfusion のドキュメントから取得されます。

var settings = new BlinkConverterSettings();

 //Set command line arguments to run without sandbox.
settings.CommandLineArguments.Add("--no-sandbox");
settings.CommandLineArguments.Add("--disable-setuid-sandbox");

settings.BlinkPath = blinkBinariesPath;

設定オブジェクトを割り当てます。

//Assign WebKit settings to the HTML converter 
htmlConverter.ConverterSettings = settings;

URL をコンバーターに渡します。出力ストリームに保存します。

var newDocument = htmlConverter.Convert(urlString);

var ms = new MemoryStream();

newDocument.Save(ms);
newDocument.Close();

ms.Position = 0;

MemoryStream から FileStreamResult を返します。コンテンツ タイプとファイル名を指定します。

return new FileStreamResult(ms, "application/pdf")
{
      FileDownloadName = "Test.pdf"
};

この時点で、関数は次のようになります。

    public class ConvertUrlToPdf
    {
        private readonly ILogger _logger;

        public ConvertUrlToPdf(ILogger logger)
        {
            _logger = logger;
        }

        [Function("ConvertUrlToPdf")]
        public async Task Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req, FunctionContext functionContext)
        {
            string urlString = req.Query["url"];

            //return if no url
            if (string.IsNullOrEmpty(urlString))
            {
                return new EmptyResult();
            }

            var directory = Directory.GetCurrentDirectory();

            var blinkBinariesPath = Path.Combine(directory, "runtimes/linux/native");

            //Initialize the HTML to PDF converter with the Blink rendering engine.
            var htmlConverter = new HtmlToPdfConverter(HtmlRenderingEngine.Blink)
            {
                ConverterSettings = null,
                ReuseBrowserProcess = false
            };

            var settings = new BlinkConverterSettings();

            //Set command line arguments to run without sandbox.
            settings.CommandLineArguments.Add("--no-sandbox");
            settings.CommandLineArguments.Add("--disable-setuid-sandbox");

            settings.BlinkPath = blinkBinariesPath;

            //Assign WebKit settings to the HTML converter 
            htmlConverter.ConverterSettings = settings;

            var newDocument = htmlConverter.Convert(urlString);

            var ms = new MemoryStream();

            newDocument.Save(ms);
            newDocument.Close();

            ms.Position = 0;

            return new FileStreamResult(ms, "application/pdf")
            {
                FileDownloadName = "Test.pdf"
            };

        }
    }

追加のクエリ文字列パラメータを追加して、方向、高さ、幅、出力ファイル名など、PDF 出力のあらゆる側面を制御できます。

string orientation = req.Query["orientation"];
string widthString = req.Query["width"];
string heightString = req.Query["height"];
string fileName = req.Query["filename"]; 

int.TryParse(widthString, out int width);
int.TryParse(heightString, out var height);

if (width == 0)
{
      width = 817;
}

if (!string.IsNullOrEmpty(orientation) && orientation.ToLower().Equals("landscape"))
       settings.Orientation = PdfPageOrientation.Landscape;

settings.BlinkPath = blinkBinariesPath;
settings.Margin.All = 0;
settings.ViewPortSize = new Size(width, height);

Dockerfileの更新

Syncfusion にはいくつかの基本的な要件があるため、Dockerfile に以下を追加する必要があります (Syncfusion のドキュメントを参照)。

RUN apt-get update && 
apt-get install -yq --no-install-recommends  
libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3  
libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4  
libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1  
libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6  
libnss3 libgbm1

完全な Dockerfile は次のようになります。

#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/azure-functions/dotnet-isolated:4-dotnet-isolated8.0 AS base
RUN apt-get update && 
apt-get install -yq --no-install-recommends  
libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3  
libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4  
libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1  
libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6  
libnss3 libgbm1
WORKDIR /home/site/wwwroot
EXPOSE 8080

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["TestPdfEndpoint.csproj", "."]
RUN dotnet restore "./TestPdfEndpoint.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "./TestPdfEndpoint.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./TestPdfEndpoint.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /home/site/wwwroot
COPY --from=publish /app/publish .
ENV AzureWebJobsScriptRoot=/home/site/wwwroot 
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true

PrintUrlToPdf エンドポイントのテスト

Docker Desktop を使用してコンテナーを起動します。ブラウザーまたは Postman を使用して PDF 生成をテストできます。クエリ文字列に、印刷するサイトの URL を追加します。

ConvertToPdf関数を追加する

2 番目の関数は、主に最初の関数をコピーして貼り付け、いくつかの調整を加えたものです。

この関数では、POST された Xhtmlstring の配列を検索します。

req.Form.TryGetValue("html", out var strings);

次に、それぞれにストリームを作成します。

var streams = new Stream[strings.Count];

for (var i = 0; i 

GetMemoryStream は次のようになります。

private static MemoryStream GetMemoryStream(string url, HtmlToPdfConverter htmlConverter)
{
    try
    {
        PdfDocument newDocument = htmlConverter.Convert(url, string.Empty);

        var ms = new MemoryStream();

        newDocument.Save(ms);
        newDocument.Close();

        ms.Position = 0;

        return ms;
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw;
    }
}

結合されたコンテンツを保持する新しい PdfDocument を作成します。

var mergedDocument = new PdfDocument
{
    EnableMemoryOptimization = true
};

ストリームを PdfDocument に追加します。

PdfDocumentBase.Merge(mergedDocument, streams);

//Save the document into stream.
var stream = new MemoryStream();
mergedDocument.Save(stream);

//Close the document.
mergedDocument.Close(true);

//Disposes the streams.
foreach (var memStream in streams)
{
    await memStream.DisposeAsync();
}

stream.Position = 0;

最後に、FileStreamResult を返します。

return new FileStreamResult(stream, "application/pdf")
{
    FileDownloadName = "TestMergedPdf.pdf"
};

ConvertToPdf の最終バージョンは次のとおりです。

    public class ConvertToPdf
    {
        private readonly ILogger _logger;

        public ConvertToPdf(ILogger logger)
        {
            _logger = logger;
        }

        [Function("ConvertToPdf")]
        public async Task Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
        {
            req.Form.TryGetValue("html", out var strings);
            
            var directory = Directory.GetCurrentDirectory();

            var blinkBinariesPath = Path.Combine(directory, "runtimes/linux/native");

            //Initialize the HTML to PDF converter with the Blink rendering engine.
            var htmlConverter = new HtmlToPdfConverter(HtmlRenderingEngine.Blink)
            {
                ConverterSettings = null,
                ReuseBrowserProcess = false
            };

            var settings = new BlinkConverterSettings();

            //Set command line arguments to run without sandbox.
            settings.CommandLineArguments.Add("--no-sandbox");
            settings.CommandLineArguments.Add("--disable-setuid-sandbox");

            settings.BlinkPath = blinkBinariesPath;

            //Assign WebKit settings to the HTML converter 
            htmlConverter.ConverterSettings = settings;

            var streams = new Stream[strings.Count];

            for (var i = 0; i 

ConvertToPdf エンドポイントのテスト

Docker Desktop を使用してコンテナを起動します。Postman を使用してテストします。エンドポイントに POST して、複数の「HTML」キーと値のペアを提供します。PDF のページごとに 1 つずつです。

Optimizely Webアプリに結び付ける

エンドポイントができたので、特定の URL または POST コンテンツを印刷するためのリンクを提供できます。

注記

実稼働環境で使用する場合は、ライセンスを購入してアプリに提供する必要があります。

Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("XXX...");

Azure での Function の設定はこの記事の範囲外ですが、今後の記事で取り上げる予定です。

2024年8月8日

#Syncfusion #.Net #PDF #Fram #を使用した #PDF #作成用の #Azure #Function #App

執筆者について: nipponese

Nipponese News編集部は、国内外のニュースを日本語で分かりやすくお届けします。