Altbilgi içeriğine atla
IRONPDF KULLANARAK

IronPDF kullanan bir Blazor PDF Görüntüleyici nasıl oluşturulur

Dağıtılmış PDF Üretiminin Sorunu

IronPDF ana sayfası 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

Internal Pdf Reporting Service 2 related to Ö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)
$vbLabelText   $csharpLabel

Çıkış PDF Belgesi

IronPDF örnek üretilen PDF

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
$vbLabelText   $csharpLabel

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

Üretilen PDF belgesi

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.

Curtis Chau
Teknik Yazar

Curtis Chau, Bilgisayar Bilimleri alanında Lisans Derecesine (Carleton Üniversitesi) sahip ve Node.js, TypeScript, JavaScript ve React konularında uzmanlaşmış ön uç geliştirmeyle ilgileniyor. Sezgisel ve estetik açıdan hoş kullanıcı arayüzleri oluşturma tutkunu, Curtis modern çerçevelerle çalışmayı ve iyi yapı...

Daha Fazla Oku

Iron Destek Ekibi

Haftada 5 gün, 24 saat çevrimiçiyiz.
Sohbet
E-posta
Beni Ara