在 App Service 透過 Html 產生 PDF (.NET Core 版)

  • 85
  • 0

過去曾經針對 .NET Framework 寫了一版在 App Service 要轉換 HTML 成 PDF 檔案的可行方案,這次改成 .NET Core 版,一樣是透過 wkhtmltopdf 這個工具,然後配合找到的套件來產生 PDF,後面就是實做和測試的結果。

前言

過去曾經針對 .NET Framework 寫了一版在 App Service 要轉換 HTML 成 PDF 檔案的可行方案,這次改成 .NET Core 版,一樣是透過 wkhtmltopdf 這個工具,然後配合找到的套件來產生 PDF,後面就是實做和測試的結果。

實做

新增 Wkhtmltopdf.NetCore NuGet 套件

新增 wkhtmltopdf 檔案,需要按照底下目錄將 wkhtmltopdf 放入,檔案可以在此處找到

在 Startup.cs 新增 service

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddWkhtmltopdf(); // 新增 Wkhtmltopdf Service
}

注入服務

readonly IGeneratePdf _generatePdf;

public HomeController(IGeneratePdf generatePdf)
{
   _generatePdf = generatePdf;
}

新增 Action 方法

public async Task<IActionResult> Pdf()
{
   return await _generatePdf.GetPdf("Views/Home/Pdf.cshtml");
}

新增 View

@{
    Layout = null;
}
<!DOCTYPE html>

<html lang="zh-tw" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>PDF 轉換測試</title>
    <style>
        body {
            margin: 0 auto;
            width: 21cm;
        }

        .text {
            font-size: x-large;
        }

        .text-pmingliu {
            font-family: "Microsoft PMingLiU";
        }

        .text-dfkai {
            font-family: DFKai-SB;
        }

        .text-jhenghei {
            font-family: "Microsoft JhengHei";
        }
    </style>
</head>
<body>
    <div>
        <!-- 中文測試 -->
        <h1>中文測試</h1>
        <p class="text text-pmingliu">新細明體</p>
        <p class="text text-dfkai">標楷體</p>
        <p class="text text-jhenghei">微軟正黑體</p>

        <!-- 圖片測試 -->
        <h1>圖片測試</h1>
        <img src="https://fakeimg.pl/250x100/" />完整網址<br>
        <img src="data:image/png;base64,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" />Base64<br>
        <img src="~/images/250x100.png" />實體路徑<br>
        <!-- SVG 不支援 -->
        <svg id="svg-app-service" viewBox="0 0 50 50" width="100%" height="100%"> <path fill="#A0A1A2" d="M20.1,46.5H3.5V30h3.4c-0.4-1-0.6-2.1-0.6-3.3c0,0,0-0.1,0-0.2H0V50h23.6V36h-3.5V46.5z"></path> <path fill="#A0A1A2" d="M43.5,30h3v16.6H29.9V36.1h-3.5V50H50V26.5h-7.4c0.5,1,0.9,2,0.9,3.3C43.5,29.8,43.5,29.9,43.5,30z"></path> <path fill="#A0A1A2" d="M3.5,20V3.5h16.6v9.6c1-0.8,2.3-1.3,3.5-1.6V0H0v23.5h6.8C7.3,22.3,8,21,9,20.1L3.5,20L3.5,20z"></path> <path fill="#A0A1A2" d="M29.9,11.1V3.5h16.6v16.6h-7.3c0.3,1,0.5,2.2,0.5,3.4c0,0,0,0.1,0,0.1H50V0H26.4v10.9c0.3,0,0.5-0.1,0.8-0.1 C28.1,10.9,29,10.9,29.9,11.1z"></path> <path fill="#59B4D9" d="M40.8,29.7c0-2.1-1.7-3.7-3.7-3.7c-0.2,0-0.3,0-0.5,0c0.2-0.8,0.4-1.7,0.4-2.6c0-5.5-4.4-9.9-9.9-9.9 c-4.3,0-8,2.8-9.3,6.8c-0.7-0.2-1.4-0.4-2.2-0.4c-3.7,0-6.7,3-6.7,6.8c0,3.8,3,6.8,6.7,6.8c0,0,0,0,0,0v0h21.8l0,0 C39.3,33.3,40.8,31.7,40.8,29.7"></path> <path opacity="0.2" fill="#FFFFFF" d="M19.2,33.5c-0.9-0.9-1.5-2-1.8-3.3c-0.8-3.7,1.4-7.3,5.1-8.1c0.8-0.2,1.5-0.2,2.2-0.1 c0.3-3.4,2.4-6.5,5.5-8c-0.9-0.3-1.9-0.5-3-0.5c-4.3,0-8,2.8-9.3,6.8c-0.7-0.2-1.4-0.4-2.2-0.4c-3.7,0-6.7,3-6.7,6.8 c0,3.8,3,6.8,6.7,6.8c0,0,0,0,0,0v0H19.2z"></path> </svg>SVG

        <!-- JavaScript 測試 -->
        <p id="js-test"></p>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script>
        $(function () {
            $("#js-test").html("<b>JavaScript 測試</b>");
        });
    </script>
</body>
</html>

發佈到 App Service 測試,因為這次是 .NET Core 版本,所以我分別測試了 Windows 和 Linux 的 App Service,可惜的是 Linux 版的針對中文會無法正確顯示中文字體,這邊可能需要再試看看是否有解決辦法。

結論

這次使用的套件還包含了很多的方法,也可以直接產生成 PDF 的串流檔案,需要更多範例可以參考 GitHub,這次主要測試是確認套件一樣可以在 App Service 執行,因為 App Service 不一定可以正確執行,測試結果針對實體路徑部分一直無法正確抓到檔案,在 Linux 版底下也沒有辦法正確顯示中文字型,這部分就可能要再尋找看看是否有解覺得方案,原始範例也有包含 Docker 版,大家可以自行測試看看了。

GitHub

參考資料

  1. Wkhtmltopdf.NetCore
  2. Wkhtmltopdf.NetCore.Example