IronPDF kullanan bir Blazor PDF Görüntüleyici nasıl oluşturulur
Dağıtılmış PDF Üretiminin Sorunu
PDF dışa aktarma ihtiyacı olan her ekip kendi uygulamasını oluşturduğunda, kod tabanı, her biri biraz farklı, her biri farklı önceliklerle farklı bir ekip tarafından sürdürülen, aynı render mantığının altı sürümü ile tamamlanır. BI kontrol panelinin kendi dışa aktarma denetleyicisi vardır. Yönetim panelinin başka bir denetleyicisi vardır. Finans sistemi, üç yıl öncesinden farklı bir kütüphane etrafında inşa edilmiş üçüncü bir denetleyiciye sahiptir. Hiçbiri aynı şirkete aitmiş gibi belgeler üretmez.
Bağlayıcı sorun, çoğaltma kadar maliyetlidir. Bir PDF şablonunun değişmesi gerektiğinde, bir yasal uyarı güncellendiğinde, bir logo yenilendiğinde, standart bir rapora bir sütun eklendiğinde, bu değişiklik, kendi render mantığını içeren her uygulamada dağıtılmalıdır. Güncellenmesi bir öğleden sonrayı alması gereken bir şablon, çok ekipli, çok sprint'li bir koordinasyon çabasına dönüşür.
Alternatifler, genellikle farklı sorunlar sağlar. Bir CLI aracılığıyla JSON borulamak, çalışana kadar çalışır ve üretimde sessizce başarısız olan bir kabuk betiği hatası ayıklamak, sıkıntılı bir deneyimdir. Harici belge oluşturma API'leri, ayrıştırma sorununu çözer ancak her çağrı için ücretler ekler ve içsel bir yetenek olması gereken bir ağ yolculuğu oluşturur. Ad-hoc rapor isteyen çalışma ekipleri hala bir geliştiricinin özel bir dışa aktarım yazmasını bekler, çünkü çağrılacak genel bir amaçlı uç nokta yoktur.
Gerçek senaryolar: her çizelge veya tablo için PDF dışa aktarımı sunmak zorunda olan bir BI arka ucu, her gösterge panosunun kendi render'ına sahip olmadan, dağıtım öncesi özetleri render etmek için bir iç hizmeti çağıran bir finans sistemi, bir QA platformu kişisel raporları CI hattı JSON çıktısından oluşturmak, bir çalışma ekibi her yapılandırılmış yükü biçimlendirilmiş bir rapor haline getirmek için tek bir uç nokta isteği.
Çözüm: Özel bir HTML'den PDF'ye Rendering Mikroservisi
IronPDF, JSON'u HTTP POST yoluyla kabul eden, verileri bir HTML ve CSS şablonuna uyarlayan ve yanıt gövdesinde bitmiş bir PDF döndüren hafif .NET mikroservisinin içinde render motoru olarak işlev görür. Herhangi bir dahili sistem, bir gösterge panosu arka ucu, bir zamanlayıcı, bir CLI aracı veya başka bir mikro hizmet, bir şablon adı ve JSON yükü içeren bir istek gönderir ve bir PDF ikilisi alır.
Şablon değişiklikleri, raporlama hizmetine bir kez dağıtılır ve her tüketici için anında etkili olur, ekipler arasında koordineli yeniden dağıtımlar yoktur. Çağrı başına SaaS ücretleri, uygulamalar arasında dağılmış render mantığı çoğaltması, ekipler arasında kitaplık sürüm uyumsuzlukları yoktur. Hizmet, bir konteynerize edilmiş .NET uygulaması olarak çalışır, bir NuGet paketi, harici süreç yok.
Pratikte Nasıl Çalışır?
1. TEK BİR POST Ağ Hattı Şablon İsmi ve Verileri Kabul Eder
Hizmet, bir uç nokta açığa çıkarır: POST /api/reports/generate. İstek gövdesi bir şablon tanımlayıcı ve bir JSON veri yükü taşır. Şablon tanımlayıcısı, rapor tasarımına sahip olan ekip tarafından korunan ve kaynak kontrolü üzerindeki servisle birlikte sürümlenen bir HTML dosyasına eşler.
{
"template": "aylık-özet",
"data": {
"period": "Mart 2025",
"totalRevenue": 482300.00,
"newAccounts": 143,
"lineItems": [...]
}
}
Servis, organizasyonun ürettiği her PDF formatı için tek doğruluk kaynağıdır. Yeni bir rapor türü eklemek, yeni bir HTML şablonu ve yeni bir şablon tanımlayıcısı eklemek anlamına gelir, hiçbir tüketici sistemde değişiklik gerektirmez.
Örnek: Endpoint'imizi Postman ile JSON Veri ile Test Etme

2. Şablon, C# PDF İçinde Doldurulur ve Render Edilir
Talebi alırken, servis HTML şablonunu yükler, JSON yükünü türüne bağlı veya dinamik bir modele indirger ve verilerle şablonu doldurur. Tutarlı şemaları olan yapılandırılmış raporlar için, derleme süresi emniyeti sağlayan bir türlendirilmiş deserialize aşamasını yapar. Şablona göre değişen şemanın bulunduğu ad-hoc yükler için, string ara değerleme veya Scriban gibi hafif bir kütüphane ile çalışan bir JsonDocument veya dinamik bağlama yapılır.
using IronPdf;
using System.Text.Json;
app.MapPost("/api/reports/generate", async (HttpContext ctx) =>
{
using var doc = await JsonDocument.ParseAsync(ctx.Request.Body);
string templateId = doc.RootElement.GetProperty("template").GetString();
var data = doc.RootElement.GetProperty("data");
string templateHtml = await File.ReadAllTextAsync($"Templates/{templateId}.html");
// Populate template with data values via string replacement or templating engine
string html = templateHtml
.Replace("{{period}}", data.GetProperty("period").GetString())
.Replace("{{totalRevenue}}", data.GetProperty("totalRevenue").GetDecimal().ToString("C"))
.Replace("{{newAccounts}}", data.GetProperty("newAccounts").GetInt32().ToString());
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
PdfDocument pdf = renderer.RenderHtmlAsPdf(html);
ctx.Response.ContentType = "application/pdf";
ctx.Response.Headers["Content-Disposition"] = $"attachment; filename=\"{templateId}-report.pdf\"";
await ctx.Response.Body.WriteAsync(pdf.BinaryData);
});
using IronPdf;
using System.Text.Json;
app.MapPost("/api/reports/generate", async (HttpContext ctx) =>
{
using var doc = await JsonDocument.ParseAsync(ctx.Request.Body);
string templateId = doc.RootElement.GetProperty("template").GetString();
var data = doc.RootElement.GetProperty("data");
string templateHtml = await File.ReadAllTextAsync($"Templates/{templateId}.html");
// Populate template with data values via string replacement or templating engine
string html = templateHtml
.Replace("{{period}}", data.GetProperty("period").GetString())
.Replace("{{totalRevenue}}", data.GetProperty("totalRevenue").GetDecimal().ToString("C"))
.Replace("{{newAccounts}}", data.GetProperty("newAccounts").GetInt32().ToString());
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
PdfDocument pdf = renderer.RenderHtmlAsPdf(html);
ctx.Response.ContentType = "application/pdf";
ctx.Response.Headers["Content-Disposition"] = $"attachment; filename=\"{templateId}-report.pdf\"";
await ctx.Response.Body.WriteAsync(pdf.BinaryData);
});
Imports IronPdf
Imports System.Text.Json
app.MapPost("/api/reports/generate", Async Function(ctx As HttpContext) As Task
Using doc = Await JsonDocument.ParseAsync(ctx.Request.Body)
Dim templateId As String = doc.RootElement.GetProperty("template").GetString()
Dim data = doc.RootElement.GetProperty("data")
Dim templateHtml As String = Await File.ReadAllTextAsync($"Templates/{templateId}.html")
' Populate template with data values via string replacement or templating engine
Dim html As String = templateHtml _
.Replace("{{period}}", data.GetProperty("period").GetString()) _
.Replace("{{totalRevenue}}", data.GetProperty("totalRevenue").GetDecimal().ToString("C")) _
.Replace("{{newAccounts}}", data.GetProperty("newAccounts").GetInt32().ToString())
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(html)
ctx.Response.ContentType = "application/pdf"
ctx.Response.Headers("Content-Disposition") = $"attachment; filename=""{templateId}-report.pdf"""
Await ctx.Response.Body.WriteAsync(pdf.BinaryData)
End Using
End Function)
Çıkış PDF Belgesi

3. Tüketici Sistemleri Servisi HTTP Üzerinden Çağırır
HTTP POST yapabilen herhangi bir dahili sistem, herhangi bir render mantığını gömmeden veya herhangi bir kütüphane bağımlılığı yönetmeden PDF oluşturabilir:
using System.Net.Http;
using System.Text;
using System.Text.Json;
var payload = new
{
template = "monthly-summary",
data = new { period = "March 2025", totalRevenue = 482300.00, newAccounts = 143 }
};
using var client = new HttpClient { BaseAddress = new Uri("http://pdf-service.internal") };
var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
using var response = await client.PostAsync("/api/reports/generate", content);
response.EnsureSuccessStatusCode();
byte[] pdfBytes = await response.Content.ReadAsByteArrayAsync();
// Stream to browser, save to storage, attach to email, etc.
using System.Net.Http;
using System.Text;
using System.Text.Json;
var payload = new
{
template = "monthly-summary",
data = new { period = "March 2025", totalRevenue = 482300.00, newAccounts = 143 }
};
using var client = new HttpClient { BaseAddress = new Uri("http://pdf-service.internal") };
var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
using var response = await client.PostAsync("/api/reports/generate", content);
response.EnsureSuccessStatusCode();
byte[] pdfBytes = await response.Content.ReadAsByteArrayAsync();
// Stream to browser, save to storage, attach to email, etc.
Imports System.Net.Http
Imports System.Text
Imports System.Text.Json
Dim payload = New With {
.template = "monthly-summary",
.data = New With {.period = "March 2025", .totalRevenue = 482300.0, .newAccounts = 143}
}
Using client As New HttpClient With {.BaseAddress = New Uri("http://pdf-service.internal")}
Dim content As New StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json")
Using response As HttpResponseMessage = Await client.PostAsync("/api/reports/generate", content)
response.EnsureSuccessStatusCode()
Dim pdfBytes As Byte() = Await response.Content.ReadAsByteArrayAsync()
' Stream to browser, save to storage, attach to email, etc.
End Using
End Using
Bu kod, tüketici sisteminde (konsol uygulaması, arka uç servisi veya mikro servis), PDF servisi içinde değil, çalışır. Çağrı yapan sistem, bir kullanıcının tarayıcısına akış yapabileceği, blob depolamaya yazabileceği veya bir dış e-postaya ekleyebileceği ham PDF baytlarını alır, ne gerekiyorsa. PDF'nin nasıl üretildiğine dair hiçbir bilgisi yoktur.
Çıktı: Konsol uygulaması + API'niz ile oluşturulan Rapor

4. Servis Durumsuz ve Gözlemlenebilir
Servis talepler arasında hiçbir veri tutmaz. Her bir render bağımsızdır, bu da hizmetin bir yük dengeleyicinin arkasında veya bir Kubernetes dağıtımında ortak çalışmadan yatay olarak ölçeklenebileceği anlamına gelir. Aylık sonu çalışmaları gibi rapor talebi artışları veya zamanlanmış bir işlemle tetiklenen toplu dışa aktarmalar, uygulama mantığını değiştirmeden kopyalar eklenerek yönetilir.
Yapılandırılmış günlükleme, her istekte render süresi, şablon tanımlayıcısı, yük boyutu ve başarı veya başarısızlığı kaydeder. Merkezileştirilmiş metrikler, render gecikmesi eğilimlerini, şablonlara göre hata oranlarını ve hacim kalıplarını tek bir yerde sergiler, her bir tüketici uygulamasının günlükleri arasında dağılmayan.
Gerçek Dünya Faydaları
Merkezileştirilmiş render. Bir hizmet tüm organizasyon için PDF üretiminin sahibidir. Şablon güncellemeleri bir kez dağıtılır ve her bir tüketici değişikliği kendi kod tabanlarına dokunmadan veya bir sürüm koordine etmeden alır.
Durumsuz ölçeklenebilirlik. Talepler arasında paylaşılmış bir durum olmadığı için, hizmet talebi karşılamak için yatay olarak ölçeklenir, yük azaldığında kopyaları ekler, kaldırır. Yapışkan oturumlar yok, dağıtılmış önbellek gerekli değil.
Tutarlı çıktı. Servis tarafından üretilen her PDF aynı render motorunu, aynı şablonları ve aynı yapılandırmayı kullanır. Finans sisteminin ürettiği ve gösterge tablosunun dışa aktardığı arasında bir farklılık yoktur.
Hızlı entegrasyon. HTTP POST yapabilen herhangi bir sistem PDF dosyası oluşturabilir. Tüketici tarafında yerleştirilmiş bir SDK yok, yönetilecek kütüphane sürümü yok ve eklenecek ithalat yok. Sözleşme JSON içindeki PDF çıktısıdır.
Gözlemlenebilirlik. Her bir render tek bir yerde günlüğe kaydedilir ve ölçülür. Yanıt süresi yüzdeleri, şablonlara göre hata oranları ve günlük hacmi bir tabloda görünür, birden fazla uygulama arasında dağılmayan.
Çağrı başına maliyet yok. Servis, bir konteyner içinde süreç içi çalışır. Üçüncü taraf API ölçümleme yoktur ve rapor hacmiyle ölçeklenen bir maliyet modeli yoktur, 100 veya 100.000 rapor oluşturmak altyapı açısından aynı maliyeti taşır.
Kapanış
PDF üretiminin merkezileştirilmesi özel bir mikro hizmete, dağıtık bir bakım sorununu basit bir hale getirir: bir hizmet, bir render motoru, şablonları güncellemek için bir yer. PDF dosyaları üreten her iç sistem, kendileri bir iş yapmadan değişiklikten yararlanır.
Hizmetin kendisi, en az bir .NET uygulaması, bir endpoint, bir şablon yükleyici ve bir render çağrısıdır. IronPDF, PDF oluşturmanın tüm yaşam döngüsünü C#'da ironpdf.com adresinde ele alır, HTML şablonlarını render etmekten belgeleri kaydetmeye, akışını sağlamaya ve belgeleri manipüle etmeye kadar. Kendi dahili API'lerinize karşı hizmeti inşa etmeye ve doğrulamaya hazırsanız, ücretsiz 30 günlük denemenizi başlatın, bu süre hizmeti kurmaya, veri kaynaklarınıza bağlamaya ve onu ekibinize çıkmadan önce çıktıyı doğrulamak için yeterlidir.




