跳至頁尾內容
使用IRONPDF

產生每月帳戶報表(PDF 文件)

靜態和手動文件傳遞的問題

IronPDF首頁 當保單持有人致電索取其當前的聲明頁面,或者銀行客戶提交支援請求要求三個月的報表時,請求最終會到達工作人員的桌上。 那個人查詢系統,格式化文件,然後通過電子郵件將其發回,有時是同一天,有時是48小時後。 對於數以千計的客戶來說,此工作流程無法擴展,而且它處理的每個請求都是自助服務入口網站應使其不必要的一個。

組織所追求的替代方案往往是用一個問題換取另一個問題。 每晚為每位客戶預生成PDF會產生一堆可能從未被下載的文件,而每一個在底層資料發生變化的那一刻起就開始變得陳舊。 更新支付方式或更改保險範疇的客戶可以下載已不再反映其賬戶的PDF文件,但仍會致電支援。

第三方文件生成API提供按需呈現,但會增加與入口網站流量直接相關的每次請求成本,此外還存在使用者操作的關鍵鏈路中的網路依賴。 每月發送20萬份報表下載的銀行入口網站不想在計量的API上承受這種負擔。

使用者的期望很簡單:一個能立即產生正確文件的"下載PDF"按鈕。 下載自己聲明頁面的保險持有人、拉取最新賬單的公用事業客戶、匯出的當前訂閱報告的SaaS管理員、下載通話詳情記錄的電信客戶,所有這些都期望即時結果,而不是排隊請求。

解決方案:API端點內的按需呈現

IronPDF允許 .NET Web應用在控制器動作或最小API端點內按需生成PDF文件。 當使用者單擊"下載PDF"時,伺服器從資料庫中提取即時資料,填充HTML模板,並由ChromePdfRenderer在記憶體中渲染PDF內容。 響應將文件直接流傳輸到瀏覽器作為下載,無需預生成,無陳舊文件,無支援隊列。

文件反映了請求時使用者賬戶資料的準確瞬間。呈現在現有的.NET應用中作為一個單一的NuGet包運行,無外部進程,無需調用文件API,無需維護輔助服務,無需按需下載的成本計算。

作為一個用於PDF工作流程的C# NuGet庫,您可以輕鬆地通過NuGet包管理器安裝IronPDF。 具有關鍵功能,包括PDF生成、工具來修改新的及現有的PDF文件、應用數位簽名和密碼等安全性,IronPDF是增強您的專案的好工具。

實際運作方式

1. 使用者在入口網站上點擊"下載PDF文件"

按鈕觸發HTTP GET到API端點,傳遞文件型別以及使用者選擇的任何參數,如報表周期、保單號、日期範圍。 端點在執行任何其他操作之前先驗證和授權請求,確認特定文件的身份和權限。

授權在這裡不是可選的。 客戶申請自己的報表是可以的;客戶申請其他客戶的則不行。 端點必須驗證已驗證的使用者有權獲取他們所請求的文件ID或參數,然後才能查詢資料。

範例入口網站視圖

生成我們PDF的範例按鈕

2. 即時資料填充包含HTML內容的模板

動作方法查詢資料庫以獲取使用者當前資料,例如賬戶詳情、項目明細、餘額、保單條款、承保選擇或使用指標,並填充特定於文件型別的HTML模板。 模板包括客戶姓名和帳號、文件日期、所有相關明細、公司品牌以及頁腳中的任何所需法律聲明文字。

不同的HTML模板處理每種文件型別:保單摘要、賬戶聲明、支付收據,均由相同的控制器和生成管道渲染。

3. ChromePdfRenderer將HTML轉換為PDF並返回文件

using IronPdf;

[HttpGet("portal/documents/statement")]
[Authorize]
public IActionResult DownloadStatement([FromQuery] string period)
{
    var userId = User.GetUserId();
    var data = _accountService.GetStatementData(userId, period);

    string html = $@"
        <h1>Account Statement — {data.Period}</h1>
        <p><strong>Account:</strong> {data.AccountNumber}</p>
        <p><strong>Name:</strong> {data.CustomerName}</p>
        {data.LineItemsHtml}
        <p><strong>Closing Balance:</strong> {data.ClosingBalance:C}</p>";

    var renderer = new ChromePdfRenderer();

    renderer.RenderingOptions.MarginTop = 20;

    renderer.RenderingOptions.MarginBottom = 20;

    PdfDocument pdf = renderer.RenderHtmlAsPdf(html);

    return File(pdf.BinaryData, "application/pdf",
        $"Statement-{data.Period}-{data.AccountNumber}.pdf");

}
using IronPdf;

[HttpGet("portal/documents/statement")]
[Authorize]
public IActionResult DownloadStatement([FromQuery] string period)
{
    var userId = User.GetUserId();
    var data = _accountService.GetStatementData(userId, period);

    string html = $@"
        <h1>Account Statement — {data.Period}</h1>
        <p><strong>Account:</strong> {data.AccountNumber}</p>
        <p><strong>Name:</strong> {data.CustomerName}</p>
        {data.LineItemsHtml}
        <p><strong>Closing Balance:</strong> {data.ClosingBalance:C}</p>";

    var renderer = new ChromePdfRenderer();

    renderer.RenderingOptions.MarginTop = 20;

    renderer.RenderingOptions.MarginBottom = 20;

    PdfDocument pdf = renderer.RenderHtmlAsPdf(html);

    return File(pdf.BinaryData, "application/pdf",
        $"Statement-{data.Period}-{data.AccountNumber}.pdf");

}
Imports IronPdf
Imports Microsoft.AspNetCore.Mvc

<HttpGet("portal/documents/statement")>
<Authorize>
Public Function DownloadStatement(<FromQuery> period As String) As IActionResult
    Dim userId = User.GetUserId()
    Dim data = _accountService.GetStatementData(userId, period)

    Dim html As String = $"
        <h1>Account Statement — {data.Period}</h1>
        <p><strong>Account:</strong> {data.AccountNumber}</p>
        <p><strong>Name:</strong> {data.CustomerName}</p>
        {data.LineItemsHtml}
        <p><strong>Closing Balance:</strong> {data.ClosingBalance:C}</p>"

    Dim renderer As New ChromePdfRenderer()

    renderer.RenderingOptions.MarginTop = 20

    renderer.RenderingOptions.MarginBottom = 20

    Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(html)

    Return File(pdf.BinaryData, "application/pdf", $"Statement-{data.Period}-{data.AccountNumber}.pdf")
End Function
$vbLabelText   $csharpLabel

範例輸出PDF文件

IronPDF範例輸出 File()與文件名一起設置自動內容配置:附件,提示瀏覽器保存文件而不是嘗試內嵌渲染。PDF文件從不寫入磁盤,它是在記憶體中生成並直接流傳輸到響應中。

4. 針對重複下載的可選快取

對於底層資料變化不頻繁的文件型別,例如僅在續訂時更新的保單聲明頁,快取層可避免多次重新渲染相同的PDF:

var dataHash = _accountService.GetStatementDataHash(userId, period);

string cacheKey = $"statement/{userId}/{period}/{dataHash}";

byte[] pdfBytes = await _cache.GetAsync(cacheKey);

if (pdfBytes == null)
{
    var renderer = new ChromePdfRenderer();
    PdfDocument pdf = renderer.RenderHtmlAsPdf(html);

    pdfBytes = pdf.BinaryData;

    await _cache.SetAsync(cacheKey, pdfBytes,
        new DistributedCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(24)
        });
}

return File(pdfBytes, "application/pdf", $"Statement-{period}.pdf");
var dataHash = _accountService.GetStatementDataHash(userId, period);

string cacheKey = $"statement/{userId}/{period}/{dataHash}";

byte[] pdfBytes = await _cache.GetAsync(cacheKey);

if (pdfBytes == null)
{
    var renderer = new ChromePdfRenderer();
    PdfDocument pdf = renderer.RenderHtmlAsPdf(html);

    pdfBytes = pdf.BinaryData;

    await _cache.SetAsync(cacheKey, pdfBytes,
        new DistributedCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(24)
        });
}

return File(pdfBytes, "application/pdf", $"Statement-{period}.pdf");
Imports System
Imports System.Threading.Tasks
Imports IronPdf

Dim dataHash = _accountService.GetStatementDataHash(userId, period)

Dim cacheKey As String = $"statement/{userId}/{period}/{dataHash}"

Dim pdfBytes As Byte() = Await _cache.GetAsync(cacheKey)

If pdfBytes Is Nothing Then
    Dim renderer As New ChromePdfRenderer()
    Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(html)

    pdfBytes = pdf.BinaryData

    Await _cache.SetAsync(cacheKey, pdfBytes, New DistributedCacheEntryOptions With {
        .AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(24)
    })
End If

Return File(pdfBytes, "application/pdf", $"Statement-{period}.pdf")
$vbLabelText   $csharpLabel

快取鍵合併了底層資料的哈希,不僅僅是使用者ID和周期。 如果資料更改、延遲付款被發佈或信用被應用,則哈希改變,快取未命中,下一次下載會根據當前資料重新渲染。 客戶從不下載陳舊的文件。

現實世界的好處

永遠保持最新。文件是根據請求時的即時資料生成的。資料變化與文件內容之間沒有同步延遲,更新賬戶資訊的客戶立即下載反映其變更的PDF。

零支援開銷。可以下載自己保單、聲明或信函的客戶不會開出要求它們的工單。 下載按鈕取代了每次請求耗費時間的支援工作流程。

無儲存膨脹。PDF是按需生成並流傳輸到瀏覽器的。 無需預生成並儲存每個客戶在每個帳單周期的文件,儲存成本不隨客戶群增加而擴大。

快速響應時間。 ChromePdfRenderer在毫秒內生成典型的入口網站文件:單頁聲明、保單摘要、支付收據。 使用者體驗幾乎是即時下載,而不是進度指標。

品牌一致性。每種文件型別都有經批准的HTMLCSS模板。 每個下載的PDF文件都帶有相同的標誌、排版、佈局和法律聲明,無論哪個端點處理了請求或何時生成的。

無每文件成本。渲染在Web應用程式中的進程中運行。 沒有第三方API計量,沒有基於使用的定價,也沒有基礎設施賬單中隨著入口網站流量增加而成長的細項。

結語

按需PDF下載是一個小功能但影響卻不成比例。 它完全消除了類別支援請求的需要,消除了客戶因陳舊文件而採取行動的風險,並用只需幾百毫秒就能完成的東西取代了手動交付工作流程。

實施適合於單個控制器操作、一個資料庫查詢、一個HTML模板、一個渲染調用和一個文件響應。 IronPDF在ironpdf.com上用C#處理PDF生成的全生命周期,從渲染HTML模板到保存、流播到文件操作。 免費30天試用讓您有足夠的時間在您自己的入口網站和資料上構建和測試按需下載端點。

Curtis Chau
技術作家

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

除了開發,Curtis對物聯網(IoT)有濃厚的興趣,探索創新的方法來整合硬體和軟體。在空閒時間,他喜歡玩遊戲和建立Discord機器人,結合他對技術的熱愛與創造力。

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話