Przejdź do treści stopki
KORZYSTANIE Z IRONPDF

Generowanie miesięcznych wyciągów z konta w formacie PDF

Problem ze statycznym i ręcznym dostarczaniem dokumentów

Strona glowna IronPDF Gdy ubezpieczony dzwoni, aby poprosić o aktualną stronę swoich deklaracji, lub klient banku otwiera zgłoszenie wsparcia, aby poprosić o trzymiesięczne zestawienie, prośba trafia na biurko pracownika. Taka osoba odpytuje system, formatuje dokument i przesyła go e-mailem z powrotem, czasami tego samego dnia, czasami po 48 godzinach. Na przestrzeni tysięcy klientów ten workflow się nie skaluje, a każde obsłużone zapytanie to takie, które powinno być niepotrzebne dzięki portalowi samoobsługowemu.

Alternatywy, do których sięgają organizacje, zwykle wymieniają jeden problem na inny. Generowanie PDFów dla każdego klienta co noc tworzy górę dokumentów, których nigdy nie pobierają, a wszystkie zaczynają tracić ważność w momencie, gdy zmieniają się dane podstawowe. Klient, który aktualizuje swoją metodę płatności lub zmienia poziom ubezpieczenia, może pobrać PDF, który już nie odzwierciedla jego konta, i nadal zadzwonić na wsparcie.

Zewnętrzne API do generowania dokumentów oferują renderowanie na żądanie, ale dodają koszty na żądanie, które rosną bezpośrednio za ruchem portalu, oraz zależność od sieci, która jest na krytycznej ścieżce działań użytkowników. Portal bankowy, który wysyła 200 000 pobrań wyciągów miesięcznie, nie chce tego na zliczonym API.

Oczekiwanie użytkownika jest proste: przycisk "Pobierz PDF", który zapewnia odpowiedni dokument, teraz. Użytkownik polisy ubezpieczeniowej pobierający swoją stronę deklaracyjną, klient usługi komunalnej pobierający swoją najnowszą fakturę, administrator SaaS eksportujący bieżący raport subskrypcji, klient telekomunikacyjny pobierający szczegóły rozmowy, wszyscy oczekują natychmiastowego wyniku, a nie zapytania w kolejce.

Rozwiązanie: Renderowanie na żądanie w środku punktu końcowego API

IronPDF pozwala aplikacjom webowym .NET generować pliki PDF na żądanie wewnątrz akcji kontrolera lub minimalnego punktu końcowego API. Gdy użytkownik kliknie "Pobierz PDF", serwer pobiera jego aktualne dane z bazy danych, wypełnia szablon HTML, a ChromePdfRenderer renderuje zawartość PDF w pamięci. Odpowiedź przesyła plik bezpośrednio do przeglądarki jako pobieranie, bez wstępnej generacji, bez przestarzałych plików, bez kolejki wsparcia.

Dokument odzwierciedla dane konta użytkownika w dokładnym momencie zapytania. Renderowanie odbywa się wewnątrz istniejącej aplikacji .NET jako pojedynczy pakiet NuGet, bez zewnętrznych procesów, bez wywołań do API dokumentu, bez usług pomocniczych do utrzymania przy życiu i bez kosztów śledzenia na pobranie.

Jako że jest to biblioteka NuGet C# do przepływów pracy z PDFami, można łatwo zainstalować IronPDF przez Menedżera pakietów NuGet. Z kluczowymi funkcjami, takimi jak generacja PDF, narzędzia do modyfikacji nowych i istniejących plików PDF, zastosowanie zabezpieczeń, takich jak podpisy cyfrowe i hasła oraz więcej, IronPDF to doskonałe narzędzie do dodania do twoich projektów.

Jak to działa w praktyce

1. Użytkownik klika "Pobierz dokument PDF" na portalu

Przycisk uruchamia żądanie HTTP GET do punktu końcowego API, przekazując typ dokumentu i dowolne parametry wybrane przez użytkownika, okres wyciągu, numer polisy, zakres dat. Punkt końcowy uwierzytelnia i autoryzuje żądanie przed wykonaniem czegokolwiek innego, weryfikując tożsamość i prawo do dostępu do konkretnego dokumentu.

Autoryzacja jest tutaj niezbędna. Klient proszący o swój własny wyciąg nie wystarczy; klient proszący o wyciąg innego klienta nie jest. Punkt końcowy musi sprawdzić, czy uwierzytelniony użytkownik ma prawo do dokumentu lub parametrów, które żądają, przed zapytaniem jakichkolwiek danych.

Przykładowy widok portalu

Przyklad przycisku do generowania naszego PDF

2. Dane na żywo wypełniają szablon, który zawiera treść HTML

Metoda akcji odpytuje bazę danych o aktualne dane użytkownika, takie jak szczegóły konta, pozycje zamówień, salda, warunki polisy, wybory pokrycia lub metryki użytkowania, i wypełnia szablon HTML specyficzny dla typu dokumentu. Szablon zawiera nazwę klienta i numer konta, datę dokumentu, wszystkie odpowiednie pozycje, brandowanie firmy, oraz wszelkie wymagane teksty zastrzeżeń prawnych w stopce.

Różny szablon HTML obsługuje każdy typ dokumentu: podsumowanie polisy, wyciąg z konta, pokwitowanie zapłaty, wszystkie renderowane przez ten sam kontroler i potok generacji.

3. ChromePdfRenderer konwertuje HTML na PDF i zwraca plik

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

Przykładowy wyjściowy plik PDF

Przykladowe wyjscie IronPDF File() z nazwą pliku automatycznie ustawia Content-Disposition: attachment, zachęcając przeglądarkę do zapisania pliku zamiast próby jego renderowania inline. PDF nigdy nie jest zapisywany na dysku, generowany jest w pamięci i przesyłany bezpośrednio do odpowiedzi.

4. Opcjonalne cache'owanie dla powtórzonych pobrań

Dla typów dokumentów, gdzie podstawowe dane zmieniają się rzadko, na przykład przy stronie deklaracji polisy, która aktualizuje się tylko podczas odnowień, warstwa cache'owania unika ponownego renderowania tego samego PDFu wiele razy:

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

Klucz cache'a zawiera hash danych podstawowych, a nie tylko ID użytkownika i okres. Jeśli dane się zmienią, opóźniona płatność zostanie zaksięgowana, kredyt zostanie zastosowany, hash się zmieni, cache nie zostanie zapisane, a kolejne pobranie ponownie zrenderuje z bieżących danych. Klient nigdy nie pobierze przestarzałego dokumentu.

Korzyści w praktyce

Zawsze aktualne. Dokumenty generowane są z bieżących danych w momencie zapytania. Nie ma luki synchronizacyjnej między zmianami danych a treścią dokumentu, klient, który aktualizuje swoje dane konta, pobiera PDF, który to odzwierciedla natychmiast.

Zerowe obciążenie wsparcia. Klienci, którzy mogą pobierać swoje własne polisy, wyciągi lub listy, nie otwierają zgłoszeń prosząc o nie. Przycisk pobierania zastępuje workflow wsparcia, który kosztował czas na każde zapytanie.

Brak nadmiarowej pamięci. PDFy generowane są na żądanie i przesyłane do przeglądarki. Nie ma potrzeby wcześniejszego generowania i magazynowania dokumentów dla każdego klienta w każdym cyklu rozliczeniowym, koszty magazynowania nie skalują się z bazą klientów.

Szybkie czasy odpowiedzi. ChromePdfRenderer produkuje typowy dokument portalowy: jednokartkowy wyciąg, podsumowanie polisy, pokwitowanie płatności, w milisekundach. Użytkownik doświadcza niemal natychmiastowego pobrania zamiast indykatora postępu.

Spójność marki. Każdy typ dokumentu ma zatwierdzony HTML i szablon CSS. Każdy pobrany PDF zawiera to samo logo, typografię, układ i zastrzeżenia prawne, niezależnie od tego, który punkt końcowy zajmował się żądaniem lub kiedy został wygenerowany.

Bez kosztów na dokument. Renderowanie odbywa się wewnątrz aplikacji webowej. Nie ma miarowania przez zewnętrzne API, brak wyceny opartej na użytkowaniu i brak pozycji na rachunku infrastruktury, która rośnie przez ruch portalu.

Zakończenie

Pobranie PDF na żądanie to mała funkcja o nieproporcjonalnym wpływie. Usuwa całą klasę zgłoszeń wsparcia, eliminuje ryzyko działania klientów na przestarzałych dokumentach i zastępuje workflow ręcznego dostarczania czymś, co zajmuje kilkaset milisekund.

Implementacja mieści się w jednej akcji kontrolera, zapytaniu bazy danych, szablonie HTML, wywołaniu renderowania i odpowiedzi plikowej. IronPDF obsługuje pełny cykl życia generowania PDF w C# na stronie ironpdf.com, od renderowania szablonów HTML po zapisywanie, strumieniowanie i manipulowanie dokumentami. Bezpłatny 30-dniowy okres próbny daje wystarczająco czasu, aby zbudować i przetestować punkt końcowy pobrania na żądanie względem własnego portalu i danych.

Curtis Chau
Autor tekstów technicznych

Curtis Chau posiada tytuł licencjata z informatyki (Uniwersytet Carleton) i specjalizuje się w front-endowym rozwoju, z ekspertką w Node.js, TypeScript, JavaScript i React. Pasjonuje się tworzeniem intuicyjnych i estetycznie przyjemnych interfejsów użytkownika, Curtis cieszy się pracą z nowoczesnymi frameworkami i tworzeniem dobrze zorganizowanych, atrakcyjnych wizualnie podrę...

Czytaj więcej

Zespół wsparcia Iron

Jesteśmy online 24 godziny, 5 dni w tygodniu.
Czat
E-mail
Zadzwoń do mnie