C# Formu PDF'ye Yazdırma -- Tam Geliştirici Rehberi
Paralel PDF Şablonlarıyla Sorun
Razor görünümleri zaten oluşturulmuştur. Fatura detay sayfası satırları oluşturur, toplamları hesaplar ve şirketin stil dosyasını uygular. Proje durumu sayfası, yalnızca mil taşları geciktiğinde görünen koşullu bölümlerle görev dağılımını gösterir. Maaş bordrosu görünümü, kazançlar, kesintiler ve YTD rakamlarını iki hafta boyunca doğru hale getiren İK ekibinin bir tablo haline getirir. Tüm bu işler tamamlandı ve sonra bir paydaş bir "PDF olarak İndir" butonu talep eder.
Standart yanıt, ikinci bir şablon oluşturmaktır: PDF yolu için aynı düzeni yeniden üreten bir HTML dizisi veya rapor tanımlaması. O ikinci şablon öncelikle ilk nüsha olarak başlatılır, sonra hemen farklılaşmaya başlar. UI tasarımcısı, Sprint 14'te fatura görünümünün tablo stilini günceller. Kimse PDF şablonunu, bir kullanıcı indirilmiş faturanın ekranla farklı göründüğünü rapor edene kadar güncellemez. Artık iki doğru kaynak var ve biri her zaman biraz yanlıştır.
İstemci tarafı JavaScript PDF kütüphaneleri çoğaltmayı önler ancak sunucuya sunulan veriyi, kimliği doğrulanmış veriyi, sunucuya hesaplanan toplamları ve ViewModel tarafından yönlendirilen koşullu bölümleri, tarayıcı tarafı renderenara aktaramaz. Sunucu tarafında başsız tarayıcı otomasyonu kırılgandır, altyapı yükü ekler ve konteynerlaştırılmış ortamlarda öngörülemez bir şekilde başarısız olur. Tarayıcıdan PDF'ye yazdırma, bir kullanıcının manuel yazdırması için çalışır; üretim uygulamasında bir "PDF'yi İndir" butonu değildir.
Gerçek senaryolar gerçek maliyeti ortaya çıkarır: bir sipariş detay sayfasını yerine getirmek için indirilen bir e-ticaret yöneticisi, proje yönetim aracından proje durumu sayfası ihraç eden bir müşteri, maaş bordrosunu indiren bir çalışan, yol özetini yazdıran bir sevk görevlisi. Hepsi PDF'nin ekranda gördükleri gibi görünmesini bekler.
Çözüm: Mevcut Görünümü Render Et, Bir Kopyasını Değil
IronPDF ASP.NET Core uygulamalarının, tarayıcıya hizmet eden aynı Razor görünümünü doğrudan PDF'ye render etmesine olanak tanır. PDF denetleyici eylemi Razor görünümünü bir HTML dizisi olarak standart görünüm motorunu kullanarak oluşturarak ChromePdfRenderer.RenderHtmlAsPdf()'ye geçirir ve sonucu dosya indirimi olarak döndürür.
Bir görünüm, iki çıktı. Razor görünümü değiştiğinde, PDF çıktısı onunla birlikte değişir, otomatik olarak, herhangi bir koordinasyona gerek kalmadan. Sürdürülmesi gereken paralel şablonlar, hataları gidermek için istemci tarafında çözümler ve başsız tarayıcı sürecini canlı tutmak yoktur. Render, tek bir NuGet paketi olarak mevcut .NET uygulamasının içinde çalışır.
Pratikte Nasıl Çalışır?
1. Görünüm Zaten Var: Yenilik PDF Eylemindedir
/invoices/{id} üzerindeki fatura detay sayfası, ister bir tarayıcıya hizmet ediyor olsun ister PDF üretiyor olsun, aynı veri modelini işliyor. Model satır ögelerini, toplamları, müşteri detaylarını ve şirket marka kimliğini içerir, görünümün ihtiyaç duyduğu tüm veriler. Mevcut InvoicesController, o modeli dolduran bir Detaylar eylemine sahiptir. PDF eylemi onunla aynı konumda, bir yedek değil.
Kullanıcı "PDF'yi İndir" butonuna tıklayındığında, istek /invoices/{id}/pdf'ye ulaşıyor. PDF eylemi aynı ViewModel'i aynı servis çağrısını kullanarak alır, model aynıdır. Farklı olan bir sonraki olan biten şeydir.
2. Razor Görünümü HTML Dizisi Olarak Render Edildi
PDF eylemi bir ViewResult döndürmek yerine, konum servisi kullanarak Razor motorunu, görünüm dosyasına ve ViewModel'e karşı çalıştırır ve çıktıyı bir string olarak yakalar. ASP.NET Core'da yaygın olan bir model, denetleyiciye enjekte edilen IViewRenderService'dir; bu, ICompositeViewEngine'i çağırır, görünümü sahte bir ActionContext'te yürütür ve render edilmiş HTML'yi döndürür.
Render edilmiş HTML dizisi tamam: Tüm veriler doldurulur, tüm koşullu bölümler çözülür, tüm CSS sınıf adları mevcuttur. Bu, tarayıcının alacağı aynı HTML'nin sunucu tarafında yakalanmış şeklidir.
3. ChromePdfRenderer, HTML Dizisini PDF Formatına Dönüştürür
using IronPdf;
[HttpGet("{id}/pdf")]
public async Task<IActionResult> DownloadInvoicePdf(int id)
{
var model = await _invoiceService.GetInvoiceViewModelAsync(id);
// Render the existing Razor view to an HTML string
string html = await _viewRenderer.RenderToStringAsync("Invoices/Details", model);
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
renderer.RenderingOptions.MarginTop = 15;
renderer.RenderingOptions.MarginBottom = 15;
PdfDocument pdf = renderer.RenderHtmlAsPdf(html);
return File(pdf.BinaryData, "application/pdf"
$"Invoice-{model.InvoiceNumber}.pdf");
}
using IronPdf;
[HttpGet("{id}/pdf")]
public async Task<IActionResult> DownloadInvoicePdf(int id)
{
var model = await _invoiceService.GetInvoiceViewModelAsync(id);
// Render the existing Razor view to an HTML string
string html = await _viewRenderer.RenderToStringAsync("Invoices/Details", model);
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
renderer.RenderingOptions.MarginTop = 15;
renderer.RenderingOptions.MarginBottom = 15;
PdfDocument pdf = renderer.RenderHtmlAsPdf(html);
return File(pdf.BinaryData, "application/pdf"
$"Invoice-{model.InvoiceNumber}.pdf");
}
Imports IronPdf
Imports Microsoft.AspNetCore.Mvc
<HttpGet("{id}/pdf")>
Public Async Function DownloadInvoicePdf(id As Integer) As Task(Of IActionResult)
Dim model = Await _invoiceService.GetInvoiceViewModelAsync(id)
' Render the existing Razor view to an HTML string
Dim html As String = Await _viewRenderer.RenderToStringAsync("Invoices/Details", model)
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
renderer.RenderingOptions.MarginTop = 15
renderer.RenderingOptions.MarginBottom = 15
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(html)
Return File(pdf.BinaryData, "application/pdf", $"Invoice-{model.InvoiceNumber}.pdf")
End Function
Oluşturulan PDF Belgesi
CssMediaType.Print, zaten görünümün stil dosyasındaki tüm @media print kurallarını uygular: gezinme çubuğunu gizler, işlem butonları bastırır ve baskıya özel aralığı uygular, Razor görünümünde herhangi bir değişiklik yapmayı gerektirmeden.
4. Görünümü Dokunmadan PDF Çıktısını İnce Ayarlama
PDF'ye özgü düzenlemeler (sayfa numaraları, özel kenar boşlukları, belge başlığı ile üstbilgiler) render üzerinde, Razor görünümde değil, yapılandırılır. Bu, baskı mantığını şablondan uzak tutar:
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = @"
<div style='font-size:9px; color:#888; text-align:center; width:100%;'>
Invoice — Page {page} of {total-pages}
</div>",
DrawDividerLine = true
};
PdfDocument pdf = renderer.RenderHtmlAsPdf(html);
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = @"
<div style='font-size:9px; color:#888; text-align:center; width:100%;'>
Invoice — Page {page} of {total-pages}
</div>",
DrawDividerLine = true
};
PdfDocument pdf = renderer.RenderHtmlAsPdf(html);
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "
<div style='font-size:9px; color:#888; text-align:center; width:100%;'>
Invoice — Page {page} of {total-pages}
</div>",
.DrawDividerLine = True
}
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(html)
Çıktı PDF Dosyası
Razor görünümünün, bir tarayıcıya mı yoksa PDF'ye mi render ettiğini bilmesine gerek yoktur. Denetleyici eylemi, PDF'ye özgü konfigürasyonu yönetir ve görünüm saf bir ekran görüntüsü şablonu olarak kalır.
Gerçek Dünya Faydaları
Sıfır şablon çoğaltma. Razor görünümü, belgenin düzen ve içeriği için tek doğruluk kaynağıdır. Tarayıcı ve PDF, aynı dosyadan render edilir, sürdürülecek ikinci bir şablon yoktur ve düzeltilmesi gereken bir sürüklenme yoktur.
Anında benimseme. Görüntü zaten varsa, PDF ihracı bir denetleyici eylem kadar uzaktadır. Düzeni yeniden tasarlama, şablonları yeniden inşa etme veya koşullu mantığı başka bir render sistemine taşıma yoktur.
Piksel hassasiyetinde çıktı. Krom tabanlı render, CSS grid, flexbox, web yazı tipi ve medya sorularının tümü PDF'de çalışır. Çıktı, tarayıcının ürettiği şeyle eşleşir, daha düşük kaliteli bir tahmin değil.
Baskıya özel stil. @media print kuralları zaten görünümün stil dosyasında PDF'de neyin görüneceğini yönetir: gezinme çubuğunu gizleme, kağıda sığacak şekilde sütun genişliklerini ayarlama veya içeriği yeniden akıtma. Ayrı bir şablon yoktur, ayrı olarak yönetilecek satır içi baskı stilleri yoktur.
Sürdürülebilirlik. Razor görünümünü güncelleyin ve hem tarayıcı çıktısı hem de PDF çıktısı değişikliği yansıtır. Güncellemelerin koordine edileceği ikinci bir sistem yoktur, bir tasarımcının değişikliğinin tarayıcıya ulaşıp PDF'ye ulaşmama riski yoktur.
[Belge başına maliyet yok. İşleme, web uygulamasının içinde işlemiçi olarak gerçekleşir.] Dış API çağrıları, kullanım ölçümü yoktur ve indirme hacmine karşı ölçeklenen bir maliyet modeli yoktur.
Kapanış
Razor görünümü zaten oluşturulmuşsa, PDF ihracı yeni bir özellik değil, mevcut çalışmanın yeni bir teslimat yoludur. Aynı model, aynı görünüm, aynı stil: Tek ekleme, görünümün HTML çıktısını yakalayan ve onu bir renderan üzerinden geçirip dosya olarak geri döndüren bir denetleyici eylemdir.
Bu mimari, kod tabanını temiz tutar ve PDF çıktısını tarayıcı ile kalıcı bir şekilde senkronize tutar. IronPDF, HTML'yi oluşturmaktan belge kaydetmeye, akışına ve manipülasyonuna kadar PDF oluşturmasının tüm yaşam döngüsünü ironpdf.com adresinde C#'da ele alır. Mevcut Razor görünümlerinize PDF ihracı eklemeye hazırsanız, ücretsiz 30 günlük denemenizi başlatın ve özelliği göndermeden önce mevcut tarayıcı render'ına karşı çıktıyı doğrulayın.




