IRONSOFTWAREHOME

Generate Reports in C# Like Raporty Crystal Reports (.NET 10)

Curtis Chau
Curtis Chau
Updated: 4 czerwca 2026

Generowanie raportu HTML-do-PDF w C# .NET z IronPDF zastępuje zastrzeżonego projektanta .rpt Raporty Crystal Reports za pomocą standardowych szablonów HTML, CSS i Razor, umożliwiając deweloperom .NET tworzenie biznesowych raportów opartych na danych, korzystając z umiejętności tworzenia stron internetowych, które już posiadają. Obejmuje to pełne wsparcie dla dynamicznych tabel, wykresów opartych na JavaScript, formatowania warunkowego, przetwarzania wsadowego wielu dokumentów oraz wdrażania między platformami w dowolnym środowisku uruchamiającym .NET.

TL;DR: Przewodnik Quickstart

Ten samouczek obejmuje zastępowanie Raporty Crystal Reports generowaniem raportów z HTML do PDF w C# .NET, od podstawowych szablonów po przetwarzanie wsadowe i generowanie zaplanowane.

  • Dla kogo jest to przeznaczone: Programiści .NET zastępujący Raporty Crystal Reports lub budujący nowe systemy raportowania od podstaw.
  • Co zbudujesz: Trzy kompletne implementacje raportów (faktura sprzedaży, katalog pracowników, raport inwentaryzacyjny), plus wizualizacje Chart.js, markowane nagłówki/stopki, generowanie spisu treści, scałanie podraportów i równoległe przetwarzanie wsadowe.
  • Gdzie działa: .NET 10, .NET 8 LTS, .NET Framework 4.6.2+ oraz .NET Standard 2.0. Brak zależności od składników COM tylko dla Windows.
  • Kiedy używać tego podejścia: Kiedy brak wsparcia Raporty Crystal Reports dla .NET Core, uzależnienie od Windows lub złożone licencjonowanie stają się wąskim gardłem.
  • Dlaczego to istotne technicznie: HTML/CSS renderuje się identycznie na wszystkich platformach, integruje się z CI/CD i wykonuje JavaScript dla wykresów, wszystko bez zastrzeżonego projektanta czy opłat za dokument.

Aby kontynuować z przykładami kodu, zainstaluj IronPdf przez NuGet (Install-Package IronPdf). Wygeneruj swój pierwszy raport kilkoma linijkami kodu:

  1. 1Install IronPDF with NuGet Package Manager

    PM > Install-Package IronPdf

  2. 2Skopiuj i uruchom ten fragment kodu.

    // Install-Package IronPdf
    var pdf = new IronPdf.ChromePdfRenderer()
        .RenderHtmlAsPdf("<h1>Sales Report</h1><table><tr><td>Q1</td><td>$50,000</td></tr></table>")
        .SaveAs("sales-report.pdf");
    C#
  3. 3Wdrożenie do testowania w środowisku produkcyjnym

    Rozpocznij używanie IronPDF w swoim projekcie już dziś z darmową wersją próbną
    arrow pointer

Po zakupie lub zapisaniu się na 30-dniowy okres próbny IronPDF, dodaj swój klucz licencyjny na początku aplikacji.

IronPdf.License.LicenseKey = "KEY";

Start using IronPDF in your project today with a free trial.

Pierwszy krok:
arrow pointer
NuGetZainstaluj za pomocą NuGet

PM > Install-Package IronPdf

Install IronPDF by running the command above in the NuGet Package Manager Console, or search for the package in the NuGet Package Manager.
Spis treści

C# Report Generator: HTML Templates to PDF

Generowanie z HTML do PDF opiera się na liniowym łańcuchu architektonicznym. Zamiast zastrzeżonego formatu plików, aplikacja używa standardowych modeli danych do wypełnienia widoków Razor lub szablonów HTML. Uzyskany ciąg HTML jest następnie przekazywany do silnika renderowania jak IronPdf, który rejestruje wizualny wynik jako dokument PDF. To podejście oddziela projektowanie raportu od środowiska hostingowego, pozwalając na uruchamianie dokładnie tego samego kodu na dowolnej platformie wspierającej .NET.

Ten przepływ pracy odzwierciedla standardowy rozwój webowy. Programiści frontendowi tworzą układ za pomocą CSS i natychmiast go podglądają w dowolnej przeglądarce. Następnie programiści backendowi wiążą dane z użyciem C#. To rozdzielenie pozwala zespołom na korzystanie z istniejącej kontroli wersji, przeglądu kodu i procesów ciągłej wdrożenia dla raportów tak samo jak dla reszty aplikacji.

HTML umożliwia funkcje niedostępne w Raporty Crystal Reports: interaktywne wykresy, responsywne tabele i wspólne style dla jednolitego brandingu.

Dlaczego zastąpić Raporty Crystal Reports w aplikacjach .NET

Migracja z Raporty Crystal Reports nie jest wynikiem pojedynczego katastroficznego problemu czy nagłego porzucenia przez SAP. Zamiast tego, to kumulacja punktów tarcia, które razem sprawiają, że platforma staje się coraz trudniejsza do uzasadnienia dla nowych projektów i bardziej wymagająca do utrzymania w istniejących rozwiązaniach. Zidentyfikowanie tych punktów bólu wyjaśnia, dlaczego wiele zespołów poszukuje alternatyw i jakie kryteria są najważniejsze przy ocenie opcji zamienników.

Brak wsparcia dla .NET 8 lub .NET Core

Raporty Crystal Reports nie wspiera .NET Core ani .NET 5-10. SAP stwierdziło na forach, że nie planują dodania wsparcia. SDK używa komponentów COM, które są niekompatybilne z międzyplatformowym .NET. Wsparcie dla nowoczesnego .NET wymagałoby całkowitego przepisania, czego SAP odmówiło.

W rezultacie zespoły budujące nowe aplikacje na bieżących wersjach .NET nie mogą używać Raporty Crystal Reports. Organizacje znormalizowane na .NET 8 lub .NET 10 nie są w stanie go zintegrować. W przypadku istniejących aplikacji, aktualizacja do nowoczesnego środowiska .NET wymaga najpierw zastąpienia systemu raportowania.

Złożone Licencjonowanie i Ukryte Koszty

Licencjonowanie Raporty Crystal Reports odróżnia licencje projektanta, licencje runtime, wdrożenia serwera i użycie osadzone. Zasady różnią się dla usług desktop, web i terminal. Zgodność w jednej konfiguracji może wymagać dodatkowych licencji w innej. Jeśli pojawią się luki po wdrożeniu, nieoczekiwane koszty pojawiają się. Wiele organizacji decyduje, że niepewność jest gorsza niż migracja do rozwiązania z jaśniejszym licencjonowaniem.

Uzależnienie od Platformy Windows

Raporty Crystal Reports działa tylko na Windows z dziedzictwem .NET Framework. Nie można wdrażać tych aplikacji do kontenerów Linux, Azure App Service na Linuxie, AWS Lambda ani Google Cloud Run. Gdy organizacje używają systemów kontenerowych, neutralnych platformowo i serverless, te ograniczenia stają się istotniejsze.

Zespoły programistyczne budujące mikroserwisowe systemy napotykają dodatkowe wyzwania. Jeśli dziewięć usług działa w lekkich kontenerach Linux, a jedna potrzebuje Windows dla Raporty Crystal Reports, wdrożenie jest bardziej skomplikowane. Potrzebujesz obrazów kontenerowych Windows, kompatybilnego z Windows hostingu i oddzielnych ustawień wdrożenia. Usługa raportowania staje się wyjątkiem, blokującym standaryzację.

Set Up a C# Report Generator in .NET 10

Rozpoczęcie z IronPDF jest proste. Zainstaluj bibliotekę przez NuGet jak każdą inną zależność .NET. Nie ma potrzeby pobierać dodatkowego oprogramowania ani oddzielnego instalatora runtime do serwerów produkcyjnych.

Wybierz Podejście do Szablonu: Razor, HTML lub Hybrydowe

IronPDF wspiera trzy różne podejścia do budowania szablonów raportów. Każde podejście oferuje specyficzne zalety w zależności od składu zespołu, wymagań projektu i długoterminowych rozważań dotyczących utrzymania.

Widoki Razor oferują najbogatsze środowisko projektowe dla zespołów już pracujących w ekosystemie .NET. Modele silnie typowane z pełnym wsparciem IntelliSense w Visual Studio i VS Code, sprawdzenie w czasie kompilacji oraz pełna moc C# dla pętli, konstrukcji warunkowych, obsługi null i formatowania ciągów znaków są dostępne. Składnia Razor jest znana tym, którzy budowali aplikacje ASP.NET Core, eliminując krzywą uczenia się związaną z silnikami szablonów z innych ekosystemów. Szablony znajdują się w projekcie obok innych plików źródłowych, biorą udział w operacjach refactoringu i kompilują się w ramach normalnego procesu budowy.

Czysty HTML z interpolacją ciągów dobrze sprawdza się przy prostszych raportach lub w zespołach, które wolą utrzymywać szablony całkowicie oddzielnie od kodu .NET. Szablony HTML mogą być przechowywane jako zasoby wkompilowane w assembly, zewnętrzne pliki implementowane obok aplikacji, a nawet odzyskane z bazy danych lub systemu zarządzania treścią w czasie wykonywania. Podstawowe wiązanie danych wykorzystuje string.Replace() dla pojedynczych wartości lub lekką bibliotekę szablonów jak Scriban lub Fluid dla bardziej zaawansowanych scenariuszy. To podejście maksymalizuje przenośność, pozwalając projektantom edytować szablony bez żadnych narzędzi .NET zainstalowanych, używając jedynie edytora tekstu i przeglądarki internetowej do podglądu.

Podejścia hybrydowe łączą obie techniki dla scenariuszy wymagających elastyczności. Na przykład, widok Razor może być użyty do generowania głównej struktury HTML, a następnie przetwarzany z dodatkowymi zamianami ciągów dla dynamicznych elementów, które nie pasują czysto do modelu widoku. Alternatywnie, zaprojektowany przez niedevelopera szablon HTML może być załadowany, a częściowe widoki Razor mogą być użyte do renderowania tylko złożonych, opartych na danych sekcji przed połączeniem całości. Konwersja z HTML do PDF jest niezależna od źródła HTML, co pozwala na mieszanie podejść w zależności od potrzeb każdego raportu.

Biorąc pod uwagę te opcje, ten samouczek skupia się głównie na widokach Razor, ponieważ oferują one najlepszy balans bezpieczeństwa typów, utrzymania i bogactwa funkcji dla typowych scenariuszy raportowania biznesowego. Umiejętności przenoszą się bezpośrednio, jeśli przyszłe wymagania obejmują pracę z czystymi szablonami HTML, ponieważ obie metody produkują łańcuchy HTML.

Build a Data-Driven PDF Report in C#

Ta sekcja pokazuje pełne utworzenie raportu faktury sprzedażowej, od początku do końca. Przykład obejmuje kluczowy wzór używany do wszystkich raportów: definiowanie modelu strukturującego dane, tworzenie szablonu Razor, który przekształca dane w sformatowany HTML, renderowanie tego szablonu do łańcucha HTML i konwersję HTML do dokumentu PDF gotowego do podglądu, wysyłki e-mailem lub archiwizacji.

Utwórz Szablon Raportu HTML/CSS

Pierwszym krokiem jest zdefiniowanie modelu danych. Prawdziwa faktura wymaga informacji o kliencie, pozycji z opisem i cenami, obliczonych sum, obsługi podatków i elementów brandingu firmy. Klasy modelowe powinny być zorganizowane, aby odzwierciedlały te grupy:

// Invoice data model with customer, company, and line item details
public class InvoiceModel
{
    public string InvoiceNumber { get; set; } = string.Empty;
    public DateTime InvoiceDate { get; set; }
    public DateTime DueDate { get; set; }

    public CompanyInfo Company { get; set; } = new();
    public CustomerInfo Customer { get; set; } = new();
    public List<LineItem> Items { get; set; } = new();

    // Computed totals - business logic stays in the model
    public decimal Subtotal => Items.Sum(x => x.Total);
    public decimal TaxRate { get; set; } = 0.08m;
    public decimal TaxAmount => Subtotal * TaxRate;
    public decimal GrandTotal => Subtotal + TaxAmount;
}

// Company details for invoice header
public class CompanyInfo
{
    public string Name { get; set; } = string.Empty;
    public string Address { get; set; } = string.Empty;
    public string City { get; set; } = string.Empty;
    public string Phone { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
    public string LogoPath { get; set; } = string.Empty;
}

// Customer billing information
public class CustomerInfo
{
    public string Name { get; set; } = string.Empty;
    public string Address { get; set; } = string.Empty;
    public string City { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
}

// Individual invoice line item
public class LineItem
{
    public string Description { get; set; } = string.Empty;
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal Total => Quantity * UnitPrice;
}

Obliczone właściwości dla Subtotal, TaxAmount i GrandTotal są uwzględnione w modelu. Te obliczenia należą do modelu, a nie do szablonu, dzięki czemu widoki Razor skupiają się na prezentacji, podczas gdy model obsługuje logikę biznesową. To rozdzielenie ułatwia testowanie jednostkowe, pozwalające zweryfikować obliczenia bez renderowania jakiegokolwiek HTML.

Teraz utwórz widok Razor, który przekształca ten model w profesjonalnie sformatowaną fakturę. Zapisz to jako InvoiceTemplate.cshtml w swoim folderze Views:

@model InvoiceModel
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        /* Reset and base styles */
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: 'Segoe UI', Arial, sans-serif; font-size: 12px; color: #333; line-height: 1.5; }
        .invoice-container { max-width: 800px; margin: 0 auto; padding: 40px; }

        /* Header with company info and invoice title */
        .header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 40px; padding-bottom: 20px; border-bottom: 2px solid #3498db; }
        .company-info h1 { font-size: 24px; color: #2c3e50; margin-bottom: 10px; }
        .company-info p { color: #7f8c8d; font-size: 11px; }
        .invoice-title { text-align: right; }
        .invoice-title h2 { font-size: 32px; color: #3498db; margin-bottom: 10px; }
        .invoice-title p { font-size: 12px; color: #7f8c8d; }

        /* Address blocks */
        .addresses { display: flex; justify-content: space-between; margin-bottom: 30px; }
        .address-block { width: 45%; }
        .address-block h3 { font-size: 11px; text-transform: uppercase; color: #95a5a6; margin-bottom: 8px; letter-spacing: 1px; }
        .address-block p { font-size: 12px; }

        /* Line items table */
        .items-table { width: 100%; border-collapse: collapse; margin-bottom: 30px; }
        .items-table th { background-color: #3498db; color: white; padding: 12px; text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; }
        .items-table th:last-child, .items-table td:last-child { text-align: right; }
        .items-table td { padding: 12px; border-bottom: 1px solid #ecf0f1; }
        .items-table tr:nth-child(even) { background-color: #f9f9f9; }

        /* Totals section */
        .totals { float: right; width: 300px; }
        .totals-row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #ecf0f1; }
        .totals-row.grand-total { border-bottom: none; border-top: 2px solid #3498db; font-size: 16px; font-weight: bold; color: #2c3e50; padding-top: 12px; }

        /* Footer */
        .footer { clear: both; margin-top: 60px; padding-top: 20px; border-top: 1px solid #ecf0f1; text-align: center; color: #95a5a6; font-size: 10px; }
    </style>
</head>
<body>
    <div class="invoice-container">
        <!-- Company header and invoice details -->
        <div class="header">
            <div class="company-info">
                <h1>@Model.Company.Name</h1>
                <p>@Model.Company.Address</p>
                <p>@Model.Company.City</p>
                <p>@Model.Company.Phone | @Model.Company.Email</p>
            </div>
            <div class="invoice-title">
                <h2>INVOICE</h2>
                <p>Invoice #: @Model.InvoiceNumber</p>
                <p>Date: @Model.InvoiceDate.ToString("MMMM dd, yyyy")</p>
                <p>Due Date: @Model.DueDate.ToString("MMMM dd, yyyy")</p>
            </div>
        </div>

        <!-- Bill to address -->
        <div class="addresses">
            <div class="address-block">
                <h3>Bill To</h3>
                <p>@Model.Customer.Name</p>
                <p>@Model.Customer.Address</p>
                <p>@Model.Customer.City</p>
                <p>@Model.Customer.Email</p>
            </div>
        </div>

        <!-- Line items table -->
        <table class="items-table">
            <thead>
                <tr><th>Description</th><th>Quantity</th><th>Unit Price</th><th>Total</th></tr>
            </thead>
            <tbody>
                @foreach (var item in Model.Items)
                {
                    <tr>
                        <td>@item.Description</td>
                        <td>@item.Quantity</td>
                        <td>@item.UnitPrice.ToString("C")</td>
                        <td>@item.Total.ToString("C")</td>
                    </tr>
                }
            </tbody>
        </table>

        <!-- Totals -->
        <div class="totals">
            <div class="totals-row"><span>Subtotal:</span><span>@Model.Subtotal.ToString("C")</span></div>
            <div class="totals-row"><span>Tax (@(Model.TaxRate * 100)%):</span><span>@Model.TaxAmount.ToString("C")</span></div>
            <div class="totals-row grand-total"><span>Total Due:</span><span>@Model.GrandTotal.ToString("C")</span></div>
        </div>

        <!-- Footer message -->
        <div class="footer">
            <p>Thank you for your business!</p>
            <p>Payment is due within 30 days. Please include invoice number with your payment.</p>
        </div>
    </div>
</body>
</html>
HTML

Osadzony w tym szablonie CSS obsługuje całe stylowanie wizualne, takie jak kolory, czcionki, odstępy i formatowanie tabel. IronPDF obsługuje również nowoczesne funkcje CSS, takie jak flexbox, siatki gridowe i zmienne CSS. Generowany PDF dokładnie odpowiada podglądowi wydruku Chrome, co sprawia, że debugowanie jest proste: jeśli coś wygląda źle w PDF, otwórz HTML w przeglądarce i użyj narzędzi dewelopera do inspekcji i dostosowania stylów.

Powiąż Dane z Szablonem

Z modelem i szablonem na miejscu, renderowanie PDF wymaga połączenia ich poprzez ChromePdfRenderer IronPDF. Kluczowym krokiem jest konwersja widoku Razor do łańcucha HTML, a następnie przekazanie tego łańcucha do renderera:

using IronPdf;

// Service class for generating invoice PDFs from Razor views
public class InvoiceReportService
{
    private readonly IRazorViewEngine _razorViewEngine;
    private readonly ITempDataProvider _tempDataProvider;
    private readonly IServiceProvider _serviceProvider;

    public InvoiceReportService(
        IRazorViewEngine razorViewEngine,
        ITempDataProvider tempDataProvider,
        IServiceProvider serviceProvider)
    {
        _razorViewEngine = razorViewEngine;
        _tempDataProvider = tempDataProvider;
        _serviceProvider = serviceProvider;
    }

    // Generate PDF from invoice model
    public async Task<byte[]> GenerateInvoicePdfAsync(InvoiceModel invoice)
    {
        // Render Razor view to HTML string
        string html = await RenderViewToStringAsync("InvoiceTemplate", invoice);

        // Configure PDF renderer with margins and paper size
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.Letter;

        // Convert HTML to PDF and return bytes
        var pdfDocument = renderer.RenderHtmlAsPdf(html);
        return pdfDocument.BinaryData;
    }

    // Helper method to render a Razor view to string
    private async Task<string> RenderViewToStringAsync<TModel>(string viewName, TModel model)
    {
        var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider };
        var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

        using var stringWriter = new StringWriter();
        var viewResult = _razorViewEngine.FindView(actionContext, viewName, false);

        if (!viewResult.Success)
            throw new InvalidOperationException($"View '{viewName}' not found.");

        var viewDictionary = new ViewDataDictionary<TModel>(
            new EmptyModelMetadataProvider(), new ModelStateDictionary()) { Model = model };

        var viewContext = new ViewContext(actionContext, viewResult.View, viewDictionary,
            new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
            stringWriter, new HtmlHelperOptions());

        await viewResult.View.RenderAsync(viewContext);
        return stringWriter.ToString();
    }
}

Dla prostszych scenariuszy, gdy nie potrzebujesz pełnej konfiguracji ASP.NET Core MVC, jak w aplikacji konsolowej czy serwisie w tle, możesz po prostu używać ciągów HTML z interpolacją i StringBuilder dla dynamicznych części.

Przykładowy Wynik

Dodaj Nagłówki, Stopki i Numery Stron

Profesjonalne raporty zazwyczaj zawierają spójne nagłówki i stopki na wszystkich stronach, wyświetlające branding firmy, tytuły dokumentów, daty generacji i numery stron. IronPDF zapewnia dwa podejścia do implementacji tych elementów: nagłówki oparte na tekście dla prostych treści wymagających minimalnego formatowania oraz nagłówki HTML dla pełnej kontroli nad stylizacją z logo i niestandardowymi układami.

Nagłówki oparte na tekście dobrze działają dla podstawowych informacji i renderują się szybciej, ponieważ nie wymagają dodatkowego parsowania HTML:

using IronPdf;
using IronSoftware.Drawing;

// Configure text-based headers and footers
var renderer = new ChromePdfRenderer();

// Set starting page number
renderer.RenderingOptions.FirstPageNumber = 1;

// Add centered header with divider line
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
    CenterText = "CONFIDENTIAL - Internal Use Only",
    DrawDividerLine = true,
    Font = FontTypes.Arial,
    FontSize = 10
};

// Add footer with date on left, page numbers on right
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
    LeftText = "{date} {time}",
    RightText = "Page {page} of {total-pages}",
    DrawDividerLine = true,
    Font = FontTypes.Arial,
    FontSize = 9
};

// Set margins to accommodate header/footer
renderer.RenderingOptions.MarginTop = 25;
renderer.RenderingOptions.MarginBottom = 20;

Dostępne pola scalania obejmują {page} dla obecnego numeru strony, {total-pages} dla całkowitej liczby stron dokumentu, {date} i {time} dla znaczników czasowych generacji, {url} dla źródłowego URL jeśli renderowane z strony internetowej, oraz {html-title} i {pdf-title} dla tytułów dokumentów. Te zastępstwa są automatycznie wykonywane podczas renderowania.

Dla nagłówków z logo, niestandardowymi czcionkami lub złożonymi wielokolumnowymi układami użyj nagłówków HTML, które wspierają pełne stylizowanie CSS:

using IronPdf;
using System;

var renderer = new ChromePdfRenderer();

// Configure HTML header with logo and custom layout
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
    MaxHeight = 30,
    HtmlFragment = @"
<div style='display: flex; justify-content: space-between; align-items: center;
            width: 100%; font-family: Arial; font-size: 10px; color: #666;'>
    <img src='logo.png' style='height: 25px;'>
    <span>Company Name Inc.</span>
    <span>Invoice Report</span>
</div>",
    BaseUrl = new Uri(@"C:\assets\images\").AbsoluteUri
};

// Configure HTML footer with page info and generation date
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    MaxHeight = 20,
    HtmlFragment = @"
<div style='text-align: center; font-size: 9px; color: #999;
            border-top: 1px solid #ddd; padding-top: 5px;'>
    Page {page} of {total-pages} | Generated on {date}
</div>",
    DrawDividerLine = false
};

Przykładowy Wynik

Utwórz Dynamiczne Tabele i Powtarzające Się Sekcje

Raporty często muszą wyświetlać kolekcje danych obejmujących wiele stron. Pętle Razor zajmują się tym naturalnie, iterując po kolekcjach i generując wiersze tabel lub elementy kartowe dla każdego elementu.

Oto kompletny przykład Katalogu Pracowników pokazującego prezentację danych z grupowanymi działami:

// Employee directory data models
public class EmployeeDirectoryModel
{
    public List<Department> Departments { get; set; } = new();
    public DateTime GeneratedDate { get; set; } = DateTime.Now;
}

// Department grouping with manager info
public class Department
{
    public string Name { get; set; } = string.Empty;
    public string ManagerName { get; set; } = string.Empty;
    public List<Employee> Employees { get; set; } = new();
}

// Individual employee details
public class Employee
{
    public string Name { get; set; } = string.Empty;
    public string Title { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
    public string Phone { get; set; } = string.Empty;
    public string PhotoUrl { get; set; } = string.Empty;
    public DateTime HireDate { get; set; }
}

Właściwość CSS page-break-inside: avoid na klasie department mówi rendererowi PDF, aby utrzymał sekcje department razem na jednej stronie, jeśli to możliwe. Jeśli zawartość działu spowodowałaby przerwanie strony w środku sekcji, renderer przesuwa całą sekcję na następną stronę. Selektor .department:not(:first-child) z page-break-before: always wymusza, aby każdy department po pierwszym rozpoczynał się na nowej stronie, tworząc czystą separację sekcji w całym katalogu.

Przykładowy Wynik

Advanced C# Report Generation With IronPDF

Raporty biznesowe często wymagają możliwości wykraczających poza statyczne tabele i tekst. Wykresy wizualizują trendy, które byłyby uciążliwe do zrozumienia w formie tabelarycznej. Formatowanie warunkowe przyciąga uwagę do pozycji wymagających działania. Podraporty łączą dane z wielu źródeł w spójne dokumenty. Ta sekcja obejmuje implementację każdej z tych funkcji z wykorzystaniem silnika renderowania Chromium IronPDF.

Dodaj Wykresy i Diagramy do Raportów PDF

Ponieważ JavaScript wykonuje się podczas renderowania, możesz użyć dowolnej biblioteki wykresów po stronie klienta, aby generować wizualizacje bezpośrednio w swoich raportach. Wykres jest rastrowany jako część strony i pojawia się w końcowym PDF dokładnie tak, jak na ekranie. Chart.js oferuje doskonałą równowagę między prostotą, możliwościami i dokumentacją dla większości potrzeb raportowania.

Dołącz Chart.js z CDN i skonfiguruj swój wykres z danymi zserializowanymi z modelu C#:

@model SalesReportModel

<!-- Include Chart.js library from CDN -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<!-- Canvas element for chart rendering -->
<canvas id="salesChart"></canvas>

<script>
    // Initialize bar chart with data from C# model
    const ctx = document.getElementById('salesChart').getContext('2d');
    new Chart(ctx, {
        type: 'bar',
        data: {
            // Serialize model data to JavaScript arrays
            labels: @Html.Raw(System.Text.Json.JsonSerializer.Serialize(Model.MonthLabels)),
            datasets: [{
                label: 'Monthly Sales',
                data: @Html.Raw(System.Text.Json.JsonSerializer.Serialize(Model.MonthlySales)),
                backgroundColor: 'rgba(52, 152, 219, 0.7)'
            }]
        }
    });
</script>
HTML

Podczas renderowania stron zawierających treści generowane przez JavaScript, skonfiguruj renderer, aby czekał na zakończenie wykonania skryptów przed przechwyceniem strony:

using IronPdf;

string html = "<h1>Report</h1>";

// Configure renderer to wait for JavaScript execution
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.JavaScript(500); // Wait 500ms for JS to complete
var pdf = renderer.RenderHtmlAsPdf(html);

Przykładowy Wynik

Zastosuj Warunkowe Formatowanie i Logikę Biznesową

Raporty inwentaryzacyjne korzystają z wskaźników wizualnych, które od razu przyciągają uwagę do pozycji wymagających działania. Zamiast zmuszać użytkowników do przeglądania setek wierszy w poszukiwaniu problemów, formatowanie warunkowe wyraźnie ukazuje wyjątki. Użyj wewnętrznych wyrażeń Razor, aby zastosować klasy CSS w oparciu o wartości danych:

<!-- Iterate through inventory items sorted by quantity -->
@foreach (var item in Model.Items.OrderBy(x => x.Quantity))
{
    // Apply CSS class based on stock level thresholds
    var rowClass = item.Quantity <= Model.CriticalStockThreshold ? "stock-critical" :
                   item.Quantity <= Model.LowStockThreshold ? "stock-low" : "";

    <tr class="@rowClass">
        <td>@item.SKU</td>
        <td>@item.ProductName</td>
        <td class="text-right">
            <!-- Badge styling for critical stock items -->
            <span class="quantity-badge @(item.Quantity <= 5 ? "badge-critical" : "badge-ok")">
                @item.Quantity
            </span>
        </td>
    </tr>
}
HTML

Przykładowy Wynik

Utwórz Podraporty i Przerwy Sekcji

Aby połączyć niezależnie wygenerowane raporty w jeden dokument, użyj funkcji scałania IronPDF:

using IronPdf;

// Combine multiple reports into a single PDF document
public byte[] GenerateCombinedReport(SalesReportModel sales, InventoryReportModel inventory)
{
    var renderer = new ChromePdfRenderer();

    // Render each report section separately
    var salesPdf = renderer.RenderHtmlAsPdf(RenderSalesReport(sales));
    var inventoryPdf = renderer.RenderHtmlAsPdf(RenderInventoryReport(inventory));

    // Merge PDFs into one document
    var combined = PdfDocument.Merge(salesPdf, inventoryPdf);
    return combined.BinaryData;
}

Przykładowy Wynik

Generuj Spis Treści

IronPDF może automatycznie generować spis treści w oparciu o elementy nagłówków w twoim HTML:

using IronPdf;

// Generate PDF with automatic table of contents
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TableOfContents = TableOfContentsTypes.WithPageNumbers;
var pdf = renderer.RenderHtmlFileAsPdf("report.html");

Moją ulubioną biblioteką tego typu jest IronPDF. Umożliwia ona szybkie i efektywne manipulowanie plikami PDF. Posiada także wiele cennych funkcji, takich jak eksport do formatu PDF/A i cyfrowe podpisywanie dokumentów PDF.

Milan Jovanovic

Microsoft MVP

Zobacz studium przypadku

IronOCR pozwala nam oszczędzić 40 000 USD rocznie na ręcznym przetwarzaniu, jednocześnie zwiększając produktywność i uwalniając zasoby do zadań o wysokim wpływie. Gorąco polecam.

Brent Matzelle

Dyrektor technologiczny, OPYN

Zobacz studium przypadku

IronSuite odgrywa kluczową rolę w naszej działalności. Są to narzędzia zwiększające wydajność w całej firmie, w tym tworzenie planów pięter i poprawa zarządzania zapasami.

David Jones

Główny inżynier oprogramowania, Agorus Build

Zobacz studium przypadku

Migracja z Raporty Crystal Reports do IronPDF

Migracja ustalonego systemu raportowania wymaga starannego planowania, aby zminimalizować zakłócenia, przy jednoczesnym wykorzystaniu okazji do modernizacji i upraszczania. Szybciej poruszysz się, rozumiejąc, jak koncepcje Raporty Crystal Reports mapują się na podejście oparte na HTML, zamiast próbować dosłownie replikówać każdą funkcję lub zachować każdą osobliwość oryginalnych raportów.

Mapowanie Koncepcji Raporty Crystal Reports do IronPDF

Zrozumienie mapowania koncepcyjnego pomaga systematycznie tłumaczyć istniejące raporty:

Raporty Crystal ReportsOdpowiednik IronPDF
Sekcje raportuHTML divs z właściwościami przerwy strony CSS
Pola parametrówWłaściwości modelu przekazywane do widoków Razor
Pola formułyC# właściwości obliczane w klasach modeli
Suma bieżącaAgregacje LINQ
PodraportyWidoki częściowe lub scałane dokumenty PDF
Grupowanie/sortowanieOperacje LINQ przed przekazaniem danych do szablonu
Raporty międzypolaTabele HTML z użyciem zagnieżdżonych pętli
Formatowanie warunkoweBloki Razor @if z klasami CSS

Najlepsza Strategia do Konwersji Szablonów .rpt

Nie próbuj programatycznie analizować plików .rpt. Zamiast tego traktuj istniejące wyjścia PDF jako specyfikacje wizualne i odbuduj logikę używając systemowej, czterostopniowej strategii:

  1. Inwentaryzacja: Kataloguj wszystkie pliki .rpt z ich przeznaczeniem, źródłami danych i częstotliwością użytkowania. Usuń nieaktualne raporty, aby zmniejszyć zakres migracji.

  2. Priorytet: Migruj najpierw raporty o wysokiej częstotliwości. Celuj w raporty z prostymi układami lub z ciągłymi problemami z utrzymaniem.

  3. Odniesienie: Eksportuj istniejące Raporty Crystal Reports jako PDF. Użyj ich jako specyfikacji wizualnych, aby programiści mogli je dopasować.

  4. Walidacja: Testuj z produkcyjnymi wolumenami danych. Szablony, które renderują się natychmiast z 10 wierszami, mogą zwolnić z 10 000 wierszy.

Generowanie i Harmonogramowanie Raportów Wsadowych w .NET

Systemy produkcyjne często muszą generować wiele raportów jednocześnie lub uruchamiać zadania raportowe w harmonogramach. Project safe multi-threaded design supports both scenarios efficiently.

Generuj Wiele Raportów Równolegle

Dla przetwarzania batch, użyj Parallel.ForEachAsync lub asynchronicznych wzorców z Task.WhenAll:

using IronPdf;
using System.Collections.Concurrent;

// Generate multiple invoices in parallel using async processing
public async Task<List<ReportResult>> GenerateInvoiceBatchAsync(List<InvoiceModel> invoices)
{
    var results = new ConcurrentBag<ReportResult>();

    // Process invoices concurrently with controlled parallelism
    await Parallel.ForEachAsync(invoices,
        new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
        async (invoice, token) =>
        {
            // Each thread gets its own renderer instance
            var renderer = new ChromePdfRenderer();
            string html = BuildInvoiceHtml(invoice);
            var pdf = await renderer.RenderHtmlAsPdfAsync(html);

            // Save individual invoice PDF
            string filename = $"Invoice_{invoice.InvoiceNumber}.pdf";
            await pdf.SaveAsAsync(filename);

            results.Add(new ReportResult { InvoiceNumber = invoice.InvoiceNumber, Success = true });
        });

    return results.ToList();
}

Przykładowy Wynik

Przykład przetwarzania wsadowego generuje wiele faktur równolegle. Oto jedna z wygenerowanych wsadowych faktur:

Integruj Generowanie Raportów z ASP.NET Core Background Services

Zaprogramowane generowanie raportów naturalnie pasuje do infrastruktury hostowanych usług ASP.NET Core:

// Background service for scheduled report generation
public class DailyReportService : BackgroundService
{
    private readonly IServiceProvider _serviceProvider;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            // Calculate next run time (6 AM daily)
            var nextRun = DateTime.Now.Date.AddDays(1).AddHours(6);
            await Task.Delay(nextRun - DateTime.Now, stoppingToken);

            // Create scoped service for report generation
            using var scope = _serviceProvider.CreateScope();
            var reportService = scope.ServiceProvider.GetRequiredService<IReportGenerationService>();

            // Generate and distribute daily report
            var salesReport = await reportService.GenerateDailySalesSummaryAsync();
            // Email or save reports as needed
        }
    }
}

Pobierz Pełny Projekt Testowy

Wszystkie przykłady kodu z tego samouczka są dostępne w gotowym do uruchomienia projekcie testowym .NET 10. Pobierz zawiera kompletny kod źródłowy, modele danych, szablony HTML i uruchamiacza testów, który generuje wszystkie pokazane wyżej przykładowe PDF.

Kolejne kroki

Przykłady w całym tym przewodniku pokazują, że IronPDF obsługuje pełny zakres potrzeb raportowania biznesowego: proste faktury z pozycjami i sumami, złożone katalogi pracowników z grupowanymi danymi i zdjęciami, raporty inwentarzowe z formatowaniem warunkowym i wykresami, przetwarzanie wsadowe setek dokumentów równolegle i zaprogramowane generowanie za pomocą usług tła.

Jeśli oceniacie alternatywy dla istniejącej implementacji Raporty Crystal Reports, zacznijcie od jednego raportu o wysokiej wartości. Odbudujcie go używając pokazanych tutaj wzorców HTML do PDF, porównajcie doświadczenie z rozwojem i jakość wyjścia, a następnie rozwińcie. Wiele zespołów odkrywa, że ich pierwszy przekształcony raport zajmuje kilka godzin, ponieważ ustanawiają oni wzorce i szablony podstawowe, podczas gdy kolejne raporty zajmują tylko minuty do złożenia, ponieważ wykorzystują szablony Razor i stylizacje. Dla precyzji układu, przewodnik rendowanie pikselowo dokładne obejmuje, jak dopasować wyjście Raporty Crystal Reports dokładnie za pomocą CSS.

Czy jesteś gotowy do rozpoczęcia budowy? Pobierz IronPDF i wyprobuj go z darmowa wersja probna. Ta sama biblioteka obsługuje wszystko od pojedyncze rendowanie raportów po generację wsadową dużej objętości w środowiskach .NET. Jeśli masz pytania dotyczące migracji raportów lub potrzebujesz wskazówek architektonicznych, skontaktuj się z naszym zespołem wsparcia inżynierskiego.

Często Zadawane Pytania

Czym jest IronPDF?

IronPDF to biblioteka C#, która umożliwia programistom tworzenie, edytowanie i generowanie dokumentów PDF programowo, stanowiąc nowoczesną alternatywę dla tradycyjnych narzędzi do raportowania, takich jak Crystal Reports.

W jaki sposób IronPDF może służyć jako alternatywa dla Crystal Reports?

IronPDF zapewnia elastyczne i nowoczesne podejście do generowania raportów, umożliwiając programistom korzystanie z szablonów HTML/CSS, które można łatwo stylizować i modyfikować, w przeciwieństwie do bardziej sztywnej struktury Crystal Reports.

Czy mogę tworzyć faktury za pomocą IronPDF?

Tak, za pomocą IronPDF można tworzyć szczegółowe i spersonalizowane faktury przy użyciu szablonów HTML/CSS, co ułatwia projektowanie profesjonalnie wyglądających dokumentów.

Czy za pomocą IronPDF można generować katalogi pracowników?

Oczywiście. IronPDF pozwala generować kompleksowe katalogi pracowników, wykorzystując dane dynamiczne oraz HTML/CSS w celu uzyskania przejrzystej i uporządkowanej prezentacji.

W jaki sposób IronPDF może pomóc w tworzeniu raportów dotyczących zapasów?

IronPDF może usprawnić tworzenie raportów magazynowych dzięki szablonom HTML/CSS, które dynamicznie wypełniają dane, zapewniając aktualne i atrakcyjne wizualnie raporty.

Jakie są zalety korzystania z szablonów HTML/CSS w IronPDF?

Korzystanie z szablonów HTML/CSS w IronPDF zapewnia elastyczność projektowania, łatwość aktualizacji oraz kompatybilność z technologiami internetowymi, co ułatwia utrzymanie i ulepszanie układów raportów.

Czy IronPDF obsługuje .NET 10?

Tak, IronPDF jest kompatybilny z .NET 10, co gwarantuje, że programiści mogą korzystać z najnowszych funkcji i ulepszeń platformy .NET w celu generowania raportów.

W jaki sposób IronPDF przyspiesza generowanie raportów?

IronPDF jest zoptymalizowany pod kątem wydajności, co pozwala mu szybko generować raporty poprzez wydajne przetwarzanie HTML/CSS i renderowanie ich do wysokiej jakości dokumentów PDF.

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ęczników.

...
Czytaj więcej

Gotowy, aby rozpocząć?

Nuget Downloads 20,667,543Wersja:2026.7właśnie wydany

Otrzymaj swój darmowy Klucz Próbny na 30 dni natychmiast.
Nie wymaga karty kredytowej ani tworzenia konta
Biblioteka C# NuGet dla plików PDF
Zainstaluj za pomocą NuGet

Wersja: 2026.7

PM > Install-Package IronPdf
nuget.org/packages/IronPdf/
  1. W Eksploratorze Rozwiązań, kliknij prawym przyciskiem Myszy na Odwołania, Zarządzaj pakietami NuGet
  2. Wybierz opcję Przeglądaj i wyszukaj „IronPdf”
  3. Wybierz pakiet i zainstaluj
DLL PDF dla C#
Pobierz DLL

Wersja: 2026.7

Pobierz teraz

lub pobierz instalator Windows tutaj.

  1. Pobierz i rozpakuj IronPDF do lokalizacji takiej jak ~/Libs w katalogu Solution
  2. W Eksploratorze rozwiązań programu Visual Studio kliknij prawym przyciskiem myszy opcję Odwołania. Wybierz opcję Przeglądaj, „IronPdf.dll”

Licencje od 749 USD

Key in blue circle

Uzyskaj natychmiast swój darmowy 30-dniowy Klucz Testowy.

Brak ograniczeń. 100% dostępności. Bez karty kredytowej.

bullet_checkedNie wymaga karty kredytowej ani tworzenia kontaBrak ograniczeń. 100% dostępności. Bez karty kredytowej.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Zarezerwuj swoje darmowe Demo na żywo
Booking Badge

Zaufane przez miliony inżynierów na całym świecie

Logotypy klientów Iron Software
Otrzymaj swoje Konsultacja Bez Zobowiązań
Wypełnij poniższy formularz lub wyślij e-mail na sales@ironsoftware.com
Twoje dane zawsze będą utrzymywane w tajemnicy.
Zaufane przez miliony inżynierów na całym świecie
Logotypy klientów Iron Software
Otrzymaj swój darmowy Klucz Próbny na 30 dni natychmiast.
Nie wymaga karty kredytowej ani tworzenia konta