Jak wyświetlać pliki PDF w Blazorze za pomocą IronPDF
Problem z ogolnym i recznym dokumentem zabezpieczeniowym
Oferta znizkowa, ktora trafia do kazdego klienta w bazie danych, niezaleznie od tego, co kupil lub przegladal, jest bardziej wydarzeniem szumu niz oferta. Klient, ktory wlasnie wydal 800 USD na bagaz, nie potrzebuje kuponu 10% na bagaz. Uzytkownik wersji probnej, ktory otwieral tylko funkcje raportowania, nie chce otrzymywac e-maili o narzedziach wspolpracy. Personalizacja nie jest luksusem marketingowym, to punkt wyjsciowy dla kolateralu, ktory rzeczywiscie przeksztalca.
Luka miedzy rzadaniem spersonalizowanego kolateralu a jego produkcja na skale masowa jest miejscem, gdzie wszystko sie psuje. Firma turystyczna z dziesiecioma segmentami docelowymi, trzema poziomami klientow i dwiema odmianami regionalnymi nie posiada 60 plikow InDesign, ma trzy pliki, ktore ktos zamierzyl zaktualizowac, a reszta znajduje sie w folderze na dysku wspoldzielonym, do ktorego nikt nie zaglada. Firma zajmujaca sie uslugami finansowymi, produkujaca dopasowane podsumowania inwestycji dla roznych profilow ryzyka, nie moze poprosic projektanta o reczne wykonanie kazdego z nich. Platforma e-commerce z kampaniami odzyskiwania klientow, ktore stracily waznosc, potrzebuje ofert generowanych na podstawie kazdego odbiorcy, a nie na segment.
Dział inżynierii zostaje wciągnięty w lukę za każdym razem, gdy marketing potrzebuje "jeszcze jednej wersji". Eksport PDF jest odbudowywany, szablon jest duplikowany, przepływ danych jest rozszerzany, a do czasu wysyłki okno kampanii się zawęża. Następna kampania rozpoczyna ten sam cykl.
Zewnętrzne platformy personalizacyjne abstrahują część tego, ale dodają ceny za dokument lub odbiorcę, które skalują się bezpośrednio w stosunku do wielkości kampanii, co sprawia, że kampanie o najszerszym zasięgu są najdroższe do realizacji.
Rozwiązanie: Personalizacja w czasie rzeczywistym od danych klienta do dokumentu PDF
IronPDF pozwala aplikacjom .NET generować spersonalizowane oferty PDF i broszury poprzez łączenie danych klientów i logiki segmentacji z zawartością HTML i szablonami marketingowymi CSS w czasie rzeczywistym. System kampanii identyfikuje odbiorcę i jego atrybuty, wybiera odpowiednią wersję szablonu, wypełnia go treściami specyficznymi dla klienta, a ChromePdfRenderer produkuje PDF.
Marketing posiada i aktualizuje szablony HTML. Dział inżynierii posiada przepływ danych i logikę segmentacji. Żaden z nich nie blokuje drugiego, projektant może zmienić układ szablonu, zaktualizować obrazy lub przepisać tekst bez dotykania ani jednej linii C#, a następne renderowanie automatycznie odbiera zmiany. Brak eksportów narzędzi do projektowania, brak opłat za dokumenty dla dostawcy, brak ręcznych wariacji dla kampanii. Renderowanie odbywa się wewnątrz istniejącej aplikacji .NET jako pojedyncza paczka NuGet.
Jak to działa w praktyce
1. Uruchomienie kampanii identyfikuje odbiorcę i jego profil
Generowanie odbywa się, gdy zaplanowane zadanie kampanii jest uruchamiane dla docelowego segmentu, użytkownik osiąga punkt zwrotny w cyklu życia (trzydzieści dni od ostatniego zakupu, 14 dzień próbny, pierwsze logowanie po przerwie) lub przedstawiciel handlowy generuje ofertę dla określonego potencjalnego klienta w CRM. Wszystkie trzy ścieżki generują ten sam wynik: identyfikator klienta i kontekst, który wywołał kampanię.
Aplikacja pobiera profil odbiorcy z bazy danych klientów, imię, etykietę segmentu, historię zakupów, powiązania z produktami, poziom lojalności oraz wszelkie sygnały behawioralne związane z ofertą. Przeglądane destynacje klienta podróżniczego, najnowsza kategoria zakupiona przez klienta e-commerce, najczęściej używane funkcje użytkownika próbnego SaaS. To właśnie te dane sprawiają, że dokument wydaje się specyficzny, a nie ogólny.
2. Logika segmentacji wybiera szablon i zawartość
Wybieracz szablonów mapuje segment i atrybuty klienta na wariant szablonu. Klient lojalnościowy z wysokimi wydatkami otrzymuje szablon premium z najwyższym poziomem rabatu i tonem "cenionego członka". Segment wrażliwy na cenę otrzymuje wariant przyjazny dla budżetu z innym nagłówkiem i propozycją wartości. Nieaktywny klient otrzymuje ramkę odzyskania.
Rekomendacje produktów, procenty ofert, daty wygaśnięcia i kody realizacji są obliczane na tym etapie, wynikające z modelu powiązań klienta, poziomu lojalności i konfiguracji kampanii. Unikalny kod realizacji lub śledzony URL łączy konkretny dokument z odbiorcą dla atrybucji, gdy oferta zostanie zrealizowana.
Na przykład:
Przykładowy szablon oferty budżetowej

Przykładowy szablon oferty standardowej

Przykładowy szablon oferty premium

3. Szablon wypełniony i renderowany w konwersji HTML na PDF
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter;
renderer.RenderingOptions.MarginTop = 0;
renderer.RenderingOptions.MarginBottom = 0;
string templateFile = customer.Segment switch
{
"HighValue" => "Templates/offer-premium.html",
"PriceSensitive"=> "Templates/offer-budget.html",
_ => "Templates/offer-standard.html"
};
string productRows = string.Concat(customer.Recommendations.Take(3).Select(p =>
$"<div class='product'><img src='{p.ImageUrl}'><p><strong>{p.Name}</strong></p><p>{p.Price:C}</p></div>"));
string html = (await File.ReadAllTextAsync(templateFile))
.Replace("{{CustomerName}}", customer.FirstName)
.Replace("{{DiscountPct}}", customer.LoyaltyDiscount.ToString())
.Replace("{{OfferCode}}", customer.UniqueOfferCode)
.Replace("{{Expiry}}", campaign.ExpiryDate.ToString("MMMM d, yyyy"))
.Replace("{{ProductRecommendations}}", productRows);
PdfDocument offer = renderer.RenderHtmlAsPdf(html);
offer.SaveAs($"offers/{campaign.Id}/{customer.Id}.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter;
renderer.RenderingOptions.MarginTop = 0;
renderer.RenderingOptions.MarginBottom = 0;
string templateFile = customer.Segment switch
{
"HighValue" => "Templates/offer-premium.html",
"PriceSensitive"=> "Templates/offer-budget.html",
_ => "Templates/offer-standard.html"
};
string productRows = string.Concat(customer.Recommendations.Take(3).Select(p =>
$"<div class='product'><img src='{p.ImageUrl}'><p><strong>{p.Name}</strong></p><p>{p.Price:C}</p></div>"));
string html = (await File.ReadAllTextAsync(templateFile))
.Replace("{{CustomerName}}", customer.FirstName)
.Replace("{{DiscountPct}}", customer.LoyaltyDiscount.ToString())
.Replace("{{OfferCode}}", customer.UniqueOfferCode)
.Replace("{{Expiry}}", campaign.ExpiryDate.ToString("MMMM d, yyyy"))
.Replace("{{ProductRecommendations}}", productRows);
PdfDocument offer = renderer.RenderHtmlAsPdf(html);
offer.SaveAs($"offers/{campaign.Id}/{customer.Id}.pdf");
Imports IronPdf
Imports System.IO
Imports System.Linq
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter
renderer.RenderingOptions.MarginTop = 0
renderer.RenderingOptions.MarginBottom = 0
Dim templateFile As String = If(customer.Segment = "HighValue", "Templates/offer-premium.html", If(customer.Segment = "PriceSensitive", "Templates/offer-budget.html", "Templates/offer-standard.html"))
Dim productRows As String = String.Concat(customer.Recommendations.Take(3).Select(Function(p) $"<div class='product'><img src='{p.ImageUrl}'><p><strong>{p.Name}</strong></p><p>{p.Price:C}</p></div>"))
Dim html As String = (Await File.ReadAllTextAsync(templateFile)).
Replace("{{CustomerName}}", customer.FirstName).
Replace("{{DiscountPct}}", customer.LoyaltyDiscount.ToString()).
Replace("{{OfferCode}}", customer.UniqueOfferCode).
Replace("{{Expiry}}", campaign.ExpiryDate.ToString("MMMM d, yyyy")).
Replace("{{ProductRecommendations}}", productRows)
Dim offer As PdfDocument = renderer.RenderHtmlAsPdf(html)
offer.SaveAs($"offers/{campaign.Id}/{customer.Id}.pdf")
Przykładowy wygenerowany PDF
ChromePdfRenderer odpowiada za pełną wierność wizualną szablonu, obrazów produktów, niestandardowych czcionek marketingowych ładowanych przez @font-face, układów wielokolumnowych i stylizowanych przycisków wezwania do działania, renderując dokładnie tak, jak zaprojektował zespół marketingowy. Wynik nie jest zubożoną wersją szablonu; to jest szablon.
4. Generowanie w partiach dla segmentów kampanii
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter;
await Parallel.ForEachAsync(campaignRecipients,
new ParallelOptions { MaxDegreeOfParallelism = 4 },
async (customer, _) =>
{
string html = await BuildPersonalizedHtmlAsync(customer, campaign);
PdfDocument pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs($"offers/{campaign.Id}/{customer.Id}.pdf");
});
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter;
await Parallel.ForEachAsync(campaignRecipients,
new ParallelOptions { MaxDegreeOfParallelism = 4 },
async (customer, _) =>
{
string html = await BuildPersonalizedHtmlAsync(customer, campaign);
PdfDocument pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs($"offers/{campaign.Id}/{customer.Id}.pdf");
});
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter
Await Parallel.ForEachAsync(campaignRecipients,
New ParallelOptions With {.MaxDegreeOfParallelism = 4},
Async Function(customer, _)
Dim html As String = Await BuildPersonalizedHtmlAsync(customer, campaign)
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs($"offers/{campaign.Id}/{customer.Id}.pdf")
End Function)
Dwie oferty PDF wygenerowane za pomocą biblioteki IronPDF
Każde renderowane PDF jest przechowywane z kluczem klienta w katalogu kampanii, gotowe do załączenia do wysyłanej wiadomości e-mail, służenia jako link do pobrania na spersonalizowanej stronie docelowej lub podarowania przedstawicielowi handlowemu jako drukowany materiał do pozostawienia. Analityka kampanii śledzi, które kody są realizowane, zamykając atrybucję w stosunku do konkretnego dokumentu oferty, który otrzymał każdy odbiorca.
Korzyści w praktyce
Personalizacja w skali. Każdy odbiorca otrzymuje dokument zbudowany na podstawie swoich danych, segmentu, zachowania, historii zakupów, poziomu lojalności. Ten sam przepływ obsługuje listę dziesięciu potencjalnych klientów lub segment kampanii obejmujący pięćdziesiąt tysięcy.
Namacalny format. PDF jest zapisywany w folderze pobierania, przesłany koledze lub wydrukowany i przypięty. Utrzymuje się dłużej niż tekst body e-maila, przedłużając trwałość oferty bez dodatkowego wysiłku.
Zwinność marketingowa. Szablon HTML i CSS jest bezpośrednio edytowany przez zespół marketingowy lub projektowy, zaktualizowane obrazy, zrewidowany tekst, nowy układ. Zmiany wchodzą w życie w następnym renderowaniu bez potrzeby wprowadzania wdrożenia inżynieryjnego.
Atrybucja. Unikalny kod realizacji lub śledzony URL wbudowany dla każdego odbiorcy łączy konwersje z konkretnym dokumentem, który otrzymał klient. Wydajność kampanii nie jest wnioskowana z ogólnych wskaźników kliknięć, jest śledzona na poziomie indywidualnych ofert.
Elastyczność segmentu. Dodanie nowego segmentu oznacza dodanie nowego wariantu szablonu lub dostosowanie logiki selektora. Przepływ generacji się nie zmienia. Dział inżynierii nie musi odbudowywać niczego, aby wspierać nowy poziom klienta lub motyw kampanii.
Brak kosztów za dokument. Renderowanie odbywa się w trakcie procesu. Nie ma zewnętrznego API personalizacji, brak opłat za odbiorcę i brak modelu cenowego, który karze za realizację dużych kampanii.
Zakończenie
Spersonalizowany materiał PDF to miejsce, gdzie przecinają się rzeczy, na które klienci faktycznie reagują — coś, co wydaje się dla nich szczególnie istotne — oraz format, który podróżuje dalej niż e-mail. Luka między statycznym wybuchem a dokumentem dostosowanym do każdego odbiorcy to przepływ danych i szablon, nie odrębna platforma.
Budowanie tego przepływu wewnątrz istniejącego systemu kampanii .NET wymaga pliku szablonu, kroku wypełniania danych i wywołania renderowania. IronPDF obsługuje pełen cykl życia generacji PDF w C# na stronie ironpdf.com, od renderowania zawartości HTML po zapisywanie, generowanie raportów, strumieniowanie i manipulowanie dokumentami. Jeśli jesteś gotów przetestować generację spersonalizowanego materiału przeciwko własnym segmentom klientów i danym kampanii, rozpocznij bezpłatny 30-dniowy okres próbny i miej działający przepływ przed otwarciem kolejnego okna kampanii.




