Przejdź do treści stopki
KORZYSTANIE Z IRONPDF

Tworzenie generatora plików PDF w Azure przy użyciu IronPDF (przewodnik po platformie .NET 10)

Problem z zapisami spraw, które istnieją tylko w systemie biletowania

Strona główna IronPDF Kiedy przychodzi zapytanie regulacyjne lub spór klienta eskaluje do poziomu prawnego, pierwszą rzeczą, o którą się prosi, jest kompletna rejestracja komunikacji. W rzeczywistości istnieje webowy interfejs użytkownika, który wymaga logowania do systemu biletowania, wątek rozłożony na dziesiątki stronicowanych wiadomości i notatki wewnętrzne zmieszane z odpowiedziami skierowanymi do klienta. Nic z tego nie jest do przedłożenia regulatorowi ani dopuszczalne w przypadku sporu.

Ręczne obejścia są równie wolne, co podatne na błędy. Menedżer wsparcia robi zrzuty ekranu z każdej strony wątku i kompiluje je w dokumencie Word. Agent kopiuje i wkleja wiadomości do emaila uporządkowanego chronologicznie. Developer eksportuje surowy JSON z API systemu biletowania i przekazuje go prawnikowi, który nie może go zinterpretować. Sprawy długoterminowe: sześciomiesięczny spór o rachunek, reklamacja gwarancyjna z dwudziestoma wymianami wiadomości między trzema agentami są niemal niemożliwe do całkowitego odtworzenia ręcznie bez błędnego uporządkowania wpisów lub pominięcia załączników.

Wymiar zgodności czyni stawkę rzeczywistą. Firma usług finansowych odpowiadająca na zapytanie regulacyjne potrzebuje każdej komunikacji z klientem w kolejności, z datą i niezmienionej. Firma SaaS w sporze kontraktowym musi wykazać, co zostało powiedziane i kiedy. Pomoc techniczna opieki zdrowotnej pod audytem potrzebuje logów interakcji z pacjentami w formacie, który audytorzy mogliby odczytać bez prezentacji systemu. Platforma e-commerce realizująca żądanie dostępu do danych podmiotu GDPR potrzebuje każdej konwersacji wsparcia wyeksportowanej dla tego klienta, wszystkich, a nie tylko tych, które ktoś zapamiętał, by ściągnąć.

Webowy interfejs użytkownika systemu biletów nie jest formatem archiwalnym. Musi się nim stać.

Rozwiązanie: Sformatowana transkrypcja spraw wygenerowana z pełnego wątku

IronPDF umożliwia aplikacjom .NET renderowanie kompletnej historii przypadków wsparcia: każda wiadomość, notatka wewnętrzna, zmiana statusu i oznaczenie czasowe do sformatowanej, samodzielnej transkrypcji PDF. Aplikacja odpytuje bazę danych systemu biletów o pełny wątek sprawy, wypełnia nowy lub istniejący szablon pliku HTML, który przedstawia rozmowę w kolejności chronologicznej z jasnymi etykietami nadawców i znacznikami czasowymi, a ChromePdfRenderer tworzy PDF.

Rezultatem jest dokument, który wygląda jak log rozmowy wydrukowany, interpretowalny przez prawnika, audytora lub klienta bez potrzeby dostępu do systemu biletów ani wytłumaczenia struktury danych. Bez zrzutów ekranu, bez kopiowania i wklejania, bez surowych zrzutów danych. Renderowanie uruchamia się w istniejącej aplikacji .NET jako jeden pakiet NuGet bez procesów zewnętrznych.

Jak to działa w praktyce

1. Uruchomienie eksportu

Eksport może być inicjowany na trzy sposoby. Członek zespołu prawnego klika "Eksportuj sprawę jako format PDF" w wewnętrznym narzędziu administracyjnym, odwołując się do konkretnego ID sprawy. Przepływ zgodności automatycznie archiwizuje zamknięte sprawy po skonfigurowanym okresie przechowywania. Żądanie dostępu do danych podmiotu inicjuje masowy eksport wszystkich spraw powiązanych z konkretnym kontem klienta.

Wszystkie trzy ścieżki trafiają do tej samej logiki generacji, mechanizm wyzwalający jedynie określa, które ID spraw są do niego wczytywane.

2. Pełne zapis sprawy zapytane z bazy danych

Aplikacja odpytuje o pełne zapisy sprawy: ID sprawy, temat, priorytet, historia statusu, daty utworzenia i rozdzielczości oraz pełny wątek wiadomości. Wątek zawiera wiadomości klientów, odpowiedzi agentów, notatki wewnętrzne i wpisy generowane przez system dotyczące zmian statusu, uporządkowane według rosnącej daty, aby transkrypcja wyglądała jak rozmowa chronologiczna.

Dla eksportów zewnętrznych (Żądania GDPR klientów, zgłoszenia regulacyjne), notatki wewnętrzne są wykluczane na poziomie zapytań zanim dojdzie do jakiegokolwiek renderowania. Dla odkryć prawnych i przeglądów wewnętrznych, notatki wewnętrzne są uwzględnione z wizualną etykietą odróżniającą je od treści skierowanej do klientów.

3. Konwersja HTML na PDF z ChromePdfRenderer

using IronPdf;

var renderer = new ChromePdfRenderer();

renderer.RenderingOptions.MarginTop = 25;
renderer.RenderingOptions.MarginBottom = 25;

var messageHtml = string.Concat(caseRecord.Messages.Select(m => $@"
    <div class='message {m.SenderRole.ToLower()}' style='
        background:{(m.SenderRole == "Agent" ? "#f0f4ff" : m.SenderRole == "Internal" ? "#fff8e1" : "#fff")};
        border-left: 4px solid {(m.SenderRole == "Internal" ? "#f59e0b" : "#3b82f6")};
        margin-bottom:12px; padding:10px;'>
        <p style='margin:0; font-size:11px; color:#555;'>
            <strong>{m.SenderName}</strong> ({m.SenderRole}) — {m.SentAt:f}
        </p>
        <p style='margin-top:6px;'>{m.Body}</p>
    </div>"));

string html = $@"
    <h1 style='font-size:16px;'>Case #{caseRecord.CaseId}: {caseRecord.Subject}</h1>
    <p>Status: {caseRecord.Status} &nbsp;|&nbsp; Priority: {caseRecord.Priority}</p>
    <p>Opened: {caseRecord.CreatedAt:f} &nbsp;|&nbsp; Resolved: {caseRecord.ResolvedAt:f}</p>
    <hr/>
    {messageHtml}";

PdfDocument transcript = renderer.RenderHtmlAsPdf(html);

transcript.SaveAs($"transcripts/case-{caseRecord.CaseId}.pdf");
using IronPdf;

var renderer = new ChromePdfRenderer();

renderer.RenderingOptions.MarginTop = 25;
renderer.RenderingOptions.MarginBottom = 25;

var messageHtml = string.Concat(caseRecord.Messages.Select(m => $@"
    <div class='message {m.SenderRole.ToLower()}' style='
        background:{(m.SenderRole == "Agent" ? "#f0f4ff" : m.SenderRole == "Internal" ? "#fff8e1" : "#fff")};
        border-left: 4px solid {(m.SenderRole == "Internal" ? "#f59e0b" : "#3b82f6")};
        margin-bottom:12px; padding:10px;'>
        <p style='margin:0; font-size:11px; color:#555;'>
            <strong>{m.SenderName}</strong> ({m.SenderRole}) — {m.SentAt:f}
        </p>
        <p style='margin-top:6px;'>{m.Body}</p>
    </div>"));

string html = $@"
    <h1 style='font-size:16px;'>Case #{caseRecord.CaseId}: {caseRecord.Subject}</h1>
    <p>Status: {caseRecord.Status} &nbsp;|&nbsp; Priority: {caseRecord.Priority}</p>
    <p>Opened: {caseRecord.CreatedAt:f} &nbsp;|&nbsp; Resolved: {caseRecord.ResolvedAt:f}</p>
    <hr/>
    {messageHtml}";

PdfDocument transcript = renderer.RenderHtmlAsPdf(html);

transcript.SaveAs($"transcripts/case-{caseRecord.CaseId}.pdf");
Imports IronPdf

Dim renderer As New ChromePdfRenderer()

renderer.RenderingOptions.MarginTop = 25
renderer.RenderingOptions.MarginBottom = 25

Dim messageHtml = String.Concat(caseRecord.Messages.Select(Function(m) $"
    <div class='message {m.SenderRole.ToLower()}' style='
        background:{If(m.SenderRole = ""Agent"", ""#f0f4ff"", If(m.SenderRole = ""Internal"", ""#fff8e1"", ""#fff""))};
        border-left: 4px solid {If(m.SenderRole = ""Internal"", ""#f59e0b"", ""#3b82f6"")};
        margin-bottom:12px; padding:10px;'>
        <p style='margin:0; font-size:11px; color:#555;'>
            <strong>{m.SenderName}</strong> ({m.SenderRole}) — {m.SentAt:f}
        </p>
        <p style='margin-top:6px;'>{m.Body}</p>
    </div>"))

Dim html As String = $"
    <h1 style='font-size:16px;'>Case #{caseRecord.CaseId}: {caseRecord.Subject}</h1>
    <p>Status: {caseRecord.Status} &nbsp;|&nbsp; Priority: {caseRecord.Priority}</p>
    <p>Opened: {caseRecord.CreatedAt:f} &nbsp;|&nbsp; Resolved: {caseRecord.ResolvedAt:f}</p>
    <hr/>
    {messageHtml}"

Dim transcript As PdfDocument = renderer.RenderHtmlAsPdf(html)

transcript.SaveAs($"transcripts/case-{caseRecord.CaseId}.pdf")
$vbLabelText   $csharpLabel

Przykładowy wyjściowy dokument PDF IronPDF

Przykładowy wynik IronPDF Długie sprawy z wieloma wiadomościami naturalnie przechodzą na wiele stron, nie ma limitu stron, ani progu liczby wiadomości, który łamie układ.

4. Nagłówek i stopka ustanawiają genealogę na każdej stronie

renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
    HtmlFragment = $@"
        <div style='font-size:9px; color:#555; width:100%; border-bottom:1px solid #ddd; padding-bottom:4px;'>
            Case #{caseRecord.CaseId} — Exported: {DateTime.UtcNow:u} UTC
        </div>",
};

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = @"
        <div style='font-size:9px; color:#555; text-align:center; width:100%;'>
            CONFIDENTIAL — Page {page} of {total-pages}
        </div>",
    DrawDividerLine = true
};
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
    HtmlFragment = $@"
        <div style='font-size:9px; color:#555; width:100%; border-bottom:1px solid #ddd; padding-bottom:4px;'>
            Case #{caseRecord.CaseId} — Exported: {DateTime.UtcNow:u} UTC
        </div>",
};

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = @"
        <div style='font-size:9px; color:#555; text-align:center; width:100%;'>
            CONFIDENTIAL — Page {page} of {total-pages}
        </div>",
    DrawDividerLine = true
};
HTML

Wyjściowy dokument PDF z nagłówkiem i stopką

Plik PDF z nagłówkiem/stopką Nagłówek na każdej stronie identyfikuje ID sprawy i datę eksportu, więc nawet jeśli pojedyncza strona zostanie oddzielona od reszty, jej pochodzenie jest jednoznaczne. Liczba stron w stopce wyjaśnia, czy dokument jest kompletny, gdy jest przekazywany do recenzenta.

Dla masowych eksportów w ramach żądania dostępu do danych podmiotu GDPR, ta sama pętla generacyjna działa dla każdej sprawy, a PdfDocument.Merge() scala wszystkie sprawy dla tego klienta w jeden dokument lub zachowuje je jako indywidualne pliki w zipie, w zależności od tego, czego wymaga obsługa żądania.

Korzyści w praktyce

Gotowość prawna. Kompletną transkrypcję sprawy produkuje się w ciągu kilku sekund. Kiedy dział prawny lub regulator żąda zapisów komunikacyjnych, odpowiedzią jest dokument, a nie wielodniowy wysiłek kompilowania zrzutów ekranu i wklejania wiadomości do Worda.

Niezmienny zapis. Wygenerowany dokument PDF to migawka sprawy w momencie eksportu. Nie można go zmienić po wygenerowaniu, co czyni go odpowiednim jako dowód w procesie odkrywania lub jako dokumentację w audycie zgodności.

Czytelny format. Sformatowany dziennik rozmów nie wymaga wyjaśnień. Prawnicy, audytorzy i klienci czytają to w taki sam sposób, jak by czytali wydrukowany wątek e-maili - nadawca, czas, wiadomość - bez potrzeby przechodzenia przez system ticketowy lub interpretacji surowych danych.

Kontrola redakcji. Notatki wewnętrzne są uwzględniane lub wykluczane na poziomie zapytania, zanim zostanie skonstruowane jakiekolwiek HTML. Ta sama linia eksportu obsługuje zarówno odkrywanie prawne (pełny zapis, w tym notatki wewnętrzne), jak i eksporty RODO dla klientów (tylko widoczne dla klientów wiadomości) bez duplikacji szablonów.

Masowy eksport. Żądania dostępu do danych podmiotu są obsługiwane programowo, wszystkie przypadki dla jednego klienta są zapytane, wygenerowane i dostarczone w jednej partii. Nie ma ręcznego eksportu przypadku po przypadku, nie ma ryzyka pominięcia przypadku ani wysiłku dewelopera proporcjonalnego do liczby przypadków.

Brak kosztów za eksport. Renderowanie działa w procesie. Nie ma mierzenia API eksportu firm trzecich, nie ma opłat za dokument i nie ma modelu cenowego, który sprawia, że duże zamówienie odkrywcze jest nieproporcjonalnie drogie.

Zakończenie

Historia przypadków wsparcia, która istnieje tylko w interfejsie ticketowym, staje się problemem w momencie, gdy prawnik, zgodność lub klient o nią poproszą. Generowanie sformatowanego transkryptu PDF w momencie żądania - lub automatycznie po zakończeniu przypadku - przekształca ten problem w dokument, który organizacja faktycznie może wytworzyć i za nim stać.

Linia jest prosta: zapytaj o pełny wątek, renderuj go jako czytelny układ HTML, dodaj nagłówki i stopki dla pochodzenia, i zwróć plik. IronPDF obsługuje cały cykl życiowy generowania PDF w C# na ironpdf.com, od renderowania szablonów HTML po zapisywanie, przesyłanie strumieniowe i manipulację dokumentami. Jeśli tworzysz funkcję eksportu przypadków lub ulepszasz istniejącą, rozpocznij bezpłatną 30-dniową próbę i zweryfikuj wyjście w stosunku do własnych danych ticketowych przed przybyciem kolejnego żądania prawnego.

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ę...

Czytaj więcej

Zespół wsparcia Iron

Jesteśmy online 24 godziny, 5 dni w tygodniu.
Czat
E-mail
Zadzwoń do mnie