Jak przekonwertować PDF na obraz w .NET
Automatyzacja dostarczania dokumentów to wymóg, który pojawia się w niemalnie każdej aplikacji .NET przeznaczonej dla konkretnej branży. Po złożeniu zamówienia faktura musi dotrzeć do klienta w ciągu kilku sekund. Kiedy raport jest generowany w nocy, interesariusze oczekują, że znajdą go w swojej skrzynce odbiorczej, zanim dotrą do biura. Najprostszym i powszechnie obsługiwanym formatem dostarczania jest plik PDF wysłany jako załącznik do wiadomości e-mail. Ten przewodnik przeprowadzi cie przez pelny proces w C# - generowanie dokumentu PDF w pamieci za pomoca IronPDF, a nastepnie wysylanie go jako zalacznika do emaila przy uzyciu zarowno MailKit, jak i wbudowanej przestrzeni nazw System.Net.Mail, wszystko bez zapisania ani jednego bajtu na dysku.
Jak zainstalować wymagane pakiety?
Ten proces opiera się na dwóch pakietach: bibliotece do generowania plików PDF oraz bibliotece do wysyłania wiadomości e-mail. Zainstaluj oba za pomocą konsoli menedżera pakietów w Visual Studio lub poprzez .NET CLI.
Install-Package IronPdf, MailKit
IronPDF oferuje silnik renderujący oparty na Chromium, który konwertuje HTML, CSS i JavaScript na dokumenty PDF o idealnej rozdzielczości. Działa na systemach Windows, Linux i macOS, co oznacza, że ten sam kod działa w interfejsie API .NET Core, usłudze działającej w tle lub funkcji Azure. MailKit to biblioteka zalecana przez Microsoft do wszystkich nowych projektów związanych z pocztą elektroniczną w środowisku .NET — obsługuje protokoły SMTP, IMAP, POP3, OAuth 2.0 oraz pełną konstrukcję MIME. Kod źródłowy i dokumentacja MailKit są dostępne na GitHubie.
Jak wygenerować dokument PDF w pamięci?
Klasa ChromePdfRenderer jest punktem wejsciowym do konwersji HTML na PDF. Przekaz napis HTML do RenderHtmlAsPdf, a otrzymasz obiekt PdfDocument, ktory calkowicie istnieje w pamieci. Uzyskaj dostep do surowych bajtow przez wlasciwosc BinaryData — ta tablica bajtow to dokladnie to, czego oczekuja API zalacznikow do emaila.
using IronPdf;
var renderer = new ChromePdfRenderer();
string htmlContent = """
<h1>Order Confirmation</h1>
<p>Thank you for your purchase.</p>
<table>
<tr><th>Item</th><th>Qty</th><th>Price</th></tr>
<tr><td>Widget A</td><td>2</td><td>$19.99</td></tr>
<tr><td>Widget B</td><td>1</td><td>$59.99</td></tr>
</table>
<p><strong>Order Total: $99.97</strong></p>
""";
PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
// pdf.BinaryData holds the complete PDF as a byte array
byte[] pdfBytes = pdf.BinaryData;
Console.WriteLine($"PDF generated: {pdfBytes.Length} bytes");
using IronPdf;
var renderer = new ChromePdfRenderer();
string htmlContent = """
<h1>Order Confirmation</h1>
<p>Thank you for your purchase.</p>
<table>
<tr><th>Item</th><th>Qty</th><th>Price</th></tr>
<tr><td>Widget A</td><td>2</td><td>$19.99</td></tr>
<tr><td>Widget B</td><td>1</td><td>$59.99</td></tr>
</table>
<p><strong>Order Total: $99.97</strong></p>
""";
PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
// pdf.BinaryData holds the complete PDF as a byte array
byte[] pdfBytes = pdf.BinaryData;
Console.WriteLine($"PDF generated: {pdfBytes.Length} bytes");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
Dim htmlContent As String = "
<h1>Order Confirmation</h1>
<p>Thank you for your purchase.</p>
<table>
<tr><th>Item</th><th>Qty</th><th>Price</th></tr>
<tr><td>Widget A</td><td>2</td><td>$19.99</td></tr>
<tr><td>Widget B</td><td>1</td><td>$59.99</td></tr>
</table>
<p><strong>Order Total: $99.97</strong></p>
"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(htmlContent)
' pdf.BinaryData holds the complete PDF as a byte array
Dim pdfBytes As Byte() = pdf.BinaryData
Console.WriteLine($"PDF generated: {pdfBytes.Length} bytes")
Metoda RenderHtmlAsPdf analizuje HTML przy uzyciu tego samego silnika Chromium, ktory napedza Google Chrome, wiec tabele, CSS Grid, Flexbox i osadzone czcionki sa renderowane dokladnie tak, jak w przegladarce. Wynikiem jest PdfDocument, ktorego wlasciwosc BinaryData zwraca cale binarium PDF bez zadnych odczytow i zapisow na dysku. Dla dokumentow, ktore zalapuja zewnetrzne obrazy lub arkusze stylow, uzyj opcjonalnego parametru BasePath, aby powiedziec IronPDF, gdzie rozwiazac wzgledne URL-e zasobow — jest to omowione szczegolowo na stronie jak-to-zrobic HTML na PDF.
Ustawianie układu strony i niestandardowych nagłówków
Przed dołączeniem pliku PDF warto skonfigurować marginesy, nagłówki lub stopki. Wszystkie opcje ukladu znajduja sie we wlasciwosci RenderingOptions:
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.MarginTop = 15;
renderer.RenderingOptions.MarginBottom = 15;
renderer.RenderingOptions.MarginLeft = 12;
renderer.RenderingOptions.MarginRight = 12;
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:9pt;color:#666;text-align:right;'>Monthly Report</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:8pt;text-align:center;'>{page} of {total-pages}</div>"
};
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Monthly Summary</h1><p>See attached data.</p>");
byte[] pdfBytes = pdf.BinaryData;
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.MarginTop = 15;
renderer.RenderingOptions.MarginBottom = 15;
renderer.RenderingOptions.MarginLeft = 12;
renderer.RenderingOptions.MarginRight = 12;
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:9pt;color:#666;text-align:right;'>Monthly Report</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:8pt;text-align:center;'>{page} of {total-pages}</div>"
};
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Monthly Summary</h1><p>See attached data.</p>");
byte[] pdfBytes = pdf.BinaryData;
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.MarginTop = 15
renderer.RenderingOptions.MarginBottom = 15
renderer.RenderingOptions.MarginLeft = 12
renderer.RenderingOptions.MarginRight = 12
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='font-size:9pt;color:#666;text-align:right;'>Monthly Report</div>",
.DrawDividerLine = True
}
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='font-size:8pt;text-align:center;'>{page} of {total-pages}</div>"
}
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>Monthly Summary</h1><p>See attached data.</p>")
Dim pdfBytes As Byte() = pdf.BinaryData
Marginesy są w milimetrach. Tokeny {page} i {total-pages} zostaja zamienione przy renderowaniu. Strona HTML napis na PDF jak-to-zrobic zawiera pelny zestaw opcji renderowania. Przed załączeniem wygenerowanego dokumentu można również dodać do niego znaki wodne lub umieścić na nim tekst i obrazy.
Jak załączyć plik PDF do wiadomości e-mail za pomocą MailKit?
MailKit tworzy drzewo komunikatów MIME bezpośrednio, zapewniając pełną kontrolę nad typem zawartości, kodowaniem i metadanymi załączników. Pomocnicza klasa BodyBuilder upraszcza powszechny przypadek napisu lub ciala HTML z jednym lub kilkoma zalacznikami plikowymi.
using IronPdf;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
// Step 1 -- generate the PDF in memory
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Monthly Report</h1><p>Generated automatically.</p>");
// Step 2 -- build the email message
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Reports Service", "reports@example.com"));
message.To.Add(new MailboxAddress("Alice Smith", "alice@example.com"));
message.Subject = "Your Monthly Report is Ready";
var builder = new BodyBuilder();
builder.TextBody = "Hello Alice,\n\nPlease find your monthly report attached.\n\nRegards,\nReports Service";
builder.HtmlBody = "<p>Hello Alice,</p><p>Please find your monthly report attached.</p>";
// Add the in-memory PDF as an attachment
builder.Attachments.Add("MonthlyReport.pdf", pdf.BinaryData, new ContentType("application", "pdf"));
message.Body = builder.ToMessageBody();
// Step 3 -- send via SMTP with TLS
using var client = new SmtpClient();
await client.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls);
await client.AuthenticateAsync("username", "app-password");
await client.SendAsync(message);
await client.DisconnectAsync(true);
using IronPdf;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
// Step 1 -- generate the PDF in memory
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Monthly Report</h1><p>Generated automatically.</p>");
// Step 2 -- build the email message
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Reports Service", "reports@example.com"));
message.To.Add(new MailboxAddress("Alice Smith", "alice@example.com"));
message.Subject = "Your Monthly Report is Ready";
var builder = new BodyBuilder();
builder.TextBody = "Hello Alice,\n\nPlease find your monthly report attached.\n\nRegards,\nReports Service";
builder.HtmlBody = "<p>Hello Alice,</p><p>Please find your monthly report attached.</p>";
// Add the in-memory PDF as an attachment
builder.Attachments.Add("MonthlyReport.pdf", pdf.BinaryData, new ContentType("application", "pdf"));
message.Body = builder.ToMessageBody();
// Step 3 -- send via SMTP with TLS
using var client = new SmtpClient();
await client.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls);
await client.AuthenticateAsync("username", "app-password");
await client.SendAsync(message);
await client.DisconnectAsync(true);
Imports IronPdf
Imports MailKit.Net.Smtp
Imports MailKit.Security
Imports MimeKit
' Step 1 -- generate the PDF in memory
Dim renderer As New ChromePdfRenderer()
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>Monthly Report</h1><p>Generated automatically.</p>")
' Step 2 -- build the email message
Dim message As New MimeMessage()
message.From.Add(New MailboxAddress("Reports Service", "reports@example.com"))
message.To.Add(New MailboxAddress("Alice Smith", "alice@example.com"))
message.Subject = "Your Monthly Report is Ready"
Dim builder As New BodyBuilder()
builder.TextBody = "Hello Alice," & vbCrLf & vbCrLf & "Please find your monthly report attached." & vbCrLf & vbCrLf & "Regards," & vbCrLf & "Reports Service"
builder.HtmlBody = "<p>Hello Alice,</p><p>Please find your monthly report attached.</p>"
' Add the in-memory PDF as an attachment
builder.Attachments.Add("MonthlyReport.pdf", pdf.BinaryData, New ContentType("application", "pdf"))
message.Body = builder.ToMessageBody()
' Step 3 -- send via SMTP with TLS
Using client As New SmtpClient()
Await client.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls)
Await client.AuthenticateAsync("username", "app-password")
Await client.SendAsync(message)
Await client.DisconnectAsync(True)
End Using
Funkcja builder.Attachments.Add przyjmuje trzy argumenty: nazwe pliku, ktora odbiorca widzi w swoim kliencie pocztowym, surowa tablice bajtow z pdf.BinaryData oraz instancje ContentType okreslajacego typ MIME jako application/pdf. Asynchroniczne metody SMTP pozwalają na zwolnienie wątku wywołującego na czas trwania operacji sieciowej — ma to kluczowe znaczenie w kontrolerach .NET Core, które obsługują dziesiątki równoczesnych żądań.
Funkcja SecureSocketOptions.StartTls negocjuje szyfrowany kanal z serwerem SMTP na porcie 587. Dla Gmaila uzyj hasla aplikacji zamiast swojego hasla konta: wygeneruj je pod Bezpieczenstwo konta Google > Hasla aplikacji, a nastepnie przekaż je do AuthenticateAsync. W przypadku Microsoft 365, skonfiguruj uwierzytelnianie OAuth 2.0 poprzez klase SaslMechanismOAuth2 MailKit, jesli twoj najemca ma wylaczone podstawowe uwierzytelnianie.
Wysyłanie do wielu odbiorców
Aby skopiowac wiecej osob na tym samym emailu, dodaj adresy do kolekcji To, Cc, lub Bcc przed wywolaniem SendAsync:
message.To.Add(new MailboxAddress("Alice Smith", "alice@example.com"));
message.To.Add(new MailboxAddress("Bob Jones", "bob@example.com"));
message.Cc.Add(new MailboxAddress("Carol Manager", "carol@example.com"));
message.To.Add(new MailboxAddress("Alice Smith", "alice@example.com"));
message.To.Add(new MailboxAddress("Bob Jones", "bob@example.com"));
message.Cc.Add(new MailboxAddress("Carol Manager", "carol@example.com"));
message.To.Add(New MailboxAddress("Alice Smith", "alice@example.com"))
message.To.Add(New MailboxAddress("Bob Jones", "bob@example.com"))
message.Cc.Add(New MailboxAddress("Carol Manager", "carol@example.com"))
Pojedyncze wywolanie SendAsync dostarcza wiadomosc do wszystkich adresow. MailKit grupuje polecenia RCPT TO w jednej sesji SMTP, dzięki czemu wysyłanie wiadomości do wielu odbiorców nie powoduje spadku wydajności.
Jak korzystać z System.Net.Mail jako alternatywy?
Dla projektow celujacych w starsze wersje .NET lub projektow, gdzie dodanie zewnetrznego pakietu NuGet nie jest dozwolone, wbudowana przestrzen nazw System.Net.Mail zajmuje sie podstawowa dostawa SMTP. Microsoft nie zaleca już tego rozwiązania do nowych projektów, ale obsługuje ono typowe przypadki użycia bez dodatkowych zależności.
using IronPdf;
using System.Net;
using System.Net.Mail;
// Generate the PDF
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Invoice #1001</h1><p>Amount due: $350.00</p>");
// Build the mail message
using var message = new MailMessage("invoices@example.com", "customer@example.com");
message.Subject = "Invoice #1001 Attached";
message.Body = "Your invoice is attached to this email. Please remit payment within 30 days.";
message.IsBodyHtml = false;
// Wrap the byte array in a MemoryStream for the Attachment constructor
var stream = new MemoryStream(pdf.BinaryData);
message.Attachments.Add(new Attachment(stream, "Invoice-1001.pdf", "application/pdf"));
// Send via SMTP
using var client = new SmtpClient("smtp.example.com", 587)
{
Credentials = new NetworkCredential("username", "password"),
EnableSsl = true
};
await client.SendMailAsync(message);
using IronPdf;
using System.Net;
using System.Net.Mail;
// Generate the PDF
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Invoice #1001</h1><p>Amount due: $350.00</p>");
// Build the mail message
using var message = new MailMessage("invoices@example.com", "customer@example.com");
message.Subject = "Invoice #1001 Attached";
message.Body = "Your invoice is attached to this email. Please remit payment within 30 days.";
message.IsBodyHtml = false;
// Wrap the byte array in a MemoryStream for the Attachment constructor
var stream = new MemoryStream(pdf.BinaryData);
message.Attachments.Add(new Attachment(stream, "Invoice-1001.pdf", "application/pdf"));
// Send via SMTP
using var client = new SmtpClient("smtp.example.com", 587)
{
Credentials = new NetworkCredential("username", "password"),
EnableSsl = true
};
await client.SendMailAsync(message);
Imports IronPdf
Imports System.Net
Imports System.Net.Mail
Imports System.IO
' Generate the PDF
Dim renderer As New ChromePdfRenderer()
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>Invoice #1001</h1><p>Amount due: $350.00</p>")
' Build the mail message
Using message As New MailMessage("invoices@example.com", "customer@example.com")
message.Subject = "Invoice #1001 Attached"
message.Body = "Your invoice is attached to this email. Please remit payment within 30 days."
message.IsBodyHtml = False
' Wrap the byte array in a MemoryStream for the Attachment constructor
Dim stream As New MemoryStream(pdf.BinaryData)
message.Attachments.Add(New Attachment(stream, "Invoice-1001.pdf", "application/pdf"))
' Send via SMTP
Using client As New SmtpClient("smtp.example.com", 587)
client.Credentials = New NetworkCredential("username", "password")
client.EnableSsl = True
Await client.SendMailAsync(message)
End Using
End Using
Kluczowa roznica w porownaniu do MailKit jest taka, ze System.Net.Mail.Attachment nie akceptuje tablicy bajtow bezposrednio — musisz najpierw owinać pdf.BinaryData w MemoryStream. Zarowno MailMessage, jak i SmtpClient sa owinięte w instrukcje using, ktore usuwaja polaczenie SMTP i oproznia strumien po wyslaniu. Jesli pominiesz using na MailMessage, strumien zalacznika moze zostac usuniety, zanim wysylka skonczy sie w niektorych runtime'ach.
Wybór między MailKit a System.Net.Mail
| Funkcja | MailKit | System.Net.Mail |
|---|---|---|
| Uwierzytelnianie OAuth 2.0 | Tak | Nie |
| Obsługa protokołów IMAP / POP3 | Tak | Nie |
| API oparte na asynchroniczności | Tak | Częściowe |
| Zalecenie firmy Microsoft | Zalecane | Starsze wersje |
| Dodatkowy pakiet NuGet | Wymagane | Nie jest wymagane |
| Złożona konstrukcja MIME | Pełne wsparcie | Podstawowe |
Wybierz MailKit do każdego nowego projektu, zwłaszcza jeśli serwer SMTP wymaga OAuth lub jeśli potrzebujesz IMAP do odczytu odpowiedzi. Uzyj System.Net.Mail, gdy baza kodu juz od niego zalezy, a koszt migracji nie jest uzasadniony.
Jak zastosować ten wzorzec w rzeczywistych procesach biznesowych?
Wzorzec "PDF do e-maila w pamięci" ma bezpośrednie zastosowanie w scenariuszach automatyzacji dokumentów, które napędzają większość aplikacji biznesowych.
Automatyzacja fakturowania
Moduł obsługi zamówień w sklepie internetowym generuje fakturę w formacie PDF natychmiast po zaksięgowaniu płatności. Wydarzenie OrderConfirmed wyzwala metode, ktora wywoluje RenderHtmlAsPdf z szablonowanym w Razor napisem HTML wypełnionym danymi zamowienia, a nastepnie wysyla wynik na adres email klienta. Ponieważ PDF nigdy nie dotyka systemu plików, nie ma pozostałych plików do usunięcia, brak wyścigów w współdzielonym katalogu tymczasowym i brak problemów z uprawnieniami w wdrażaniu kontenerów. Więcej informacji na temat renderowania HTML z widoków Razor można znaleźć w przewodniku po generowaniu plików PDF w ASP.NET Core.
Zaplanowana dystrybucja raportów
Usługa w tle zaplanowana za pomocą IHostedService generuje tygodniowe podsumowanie analityczne o 06:00 kazdego poniedzialku. Wysyła zapytanie do bazy danych, tworzy ciąg znaków raportu HTML, renderuje go za pomocą IronPDF i wykorzystuje MailKit do wysłania go na listę dystrybucyjną. Cały proces przebiega jako asynchroniczny przepływ pracy, więc nie zajmuje wątku z puli wątków podczas uzgadniania połączenia SMTP. W przypadku obciążeń hostowanych w Azure przewodnik po generatorze PDF Azure wyjaśnia, jak wdrożyć IronPDF w ramach usługi Azure App Service i Azure Functions.
Generowanie paragonów w ASP.NET Core
W minimalnym API lub akcji kontrolera .NET Core punkt końcowy POST odbiera ładunek transakcji, generuje paragon w formacie PDF i zwraca kod HTTP 200, jednocześnie wysyłając wiadomość e-mail. Zachowaj logike wysylania emaila w tle Task, aby odpowiedz HTTP natychmiast wrocila do klienta:
app.MapPost("/checkout", async (CheckoutRequest req, IEmailService emailService) =>
{
var renderer = new ChromePdfRenderer();
PdfDocument receipt = renderer.RenderHtmlAsPdf(BuildReceiptHtml(req));
// Fire and forget -- do not await so the HTTP response is immediate
_ = emailService.SendReceiptAsync(req.CustomerEmail, receipt.BinaryData);
return Results.Ok(new { message = "Order confirmed." });
});
app.MapPost("/checkout", async (CheckoutRequest req, IEmailService emailService) =>
{
var renderer = new ChromePdfRenderer();
PdfDocument receipt = renderer.RenderHtmlAsPdf(BuildReceiptHtml(req));
// Fire and forget -- do not await so the HTTP response is immediate
_ = emailService.SendReceiptAsync(req.CustomerEmail, receipt.BinaryData);
return Results.Ok(new { message = "Order confirmed." });
});
Imports System.Threading.Tasks
app.MapPost("/checkout", Async Function(req As CheckoutRequest, emailService As IEmailService) As Task(Of IResult)
Dim renderer As New ChromePdfRenderer()
Dim receipt As PdfDocument = renderer.RenderHtmlAsPdf(BuildReceiptHtml(req))
' Fire and forget -- do not await so the HTTP response is immediate
_ = emailService.SendReceiptAsync(req.CustomerEmail, receipt.BinaryData)
Return Results.Ok(New With {.message = "Order confirmed."})
End Function)
Dzięki temu czas odpowiedzi API pozostaje poniżej 100 ms, nawet gdy serwer SMTP działa wolno. emailService jest zarejestrowana jako usluga o zasiegu lub przejściowa, ktora owija SmtpClient MailKit.
Jak radzisz sobie z błędami i ponownymi próbami?
Operacje sieciowe kończą się niepowodzeniem. Serwery SMTP są chwilowo niedostępne, tokeny uwierzytelniające tracą ważność, a limity rozmiaru załączników różnią się w zależności od dostawcy. Od samego początku zadbaj o odporność ścieżki wysyłania wiadomości e-mail.
Zawiąż logikę wysyłania MailKit w try/catch i rejestruj błędy w stałej kolejce, aby można było je ponownie przetestować:
using IronPdf;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
using Microsoft.Extensions.Logging;
async Task SendPdfEmailWithRetryAsync(
byte[] pdfBytes,
string recipientEmail,
string subject,
ILogger logger,
int maxAttempts = 3)
{
for (int attempt = 1; attempt <= maxAttempts; attempt++)
{
try
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Mailer", "mailer@example.com"));
message.To.Add(MailboxAddress.Parse(recipientEmail));
message.Subject = subject;
var builder = new BodyBuilder { TextBody = "Your document is attached." };
builder.Attachments.Add("document.pdf", pdfBytes, new ContentType("application", "pdf"));
message.Body = builder.ToMessageBody();
using var smtpClient = new SmtpClient();
await smtpClient.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls);
await smtpClient.AuthenticateAsync("user", "pass");
await smtpClient.SendAsync(message);
await smtpClient.DisconnectAsync(true);
logger.LogInformation("Email sent to {Email} on attempt {Attempt}", recipientEmail, attempt);
return;
}
catch (Exception ex) when (attempt < maxAttempts)
{
logger.LogWarning(ex, "Send attempt {Attempt} failed. Retrying...", attempt);
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
}
}
}
using IronPdf;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
using Microsoft.Extensions.Logging;
async Task SendPdfEmailWithRetryAsync(
byte[] pdfBytes,
string recipientEmail,
string subject,
ILogger logger,
int maxAttempts = 3)
{
for (int attempt = 1; attempt <= maxAttempts; attempt++)
{
try
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Mailer", "mailer@example.com"));
message.To.Add(MailboxAddress.Parse(recipientEmail));
message.Subject = subject;
var builder = new BodyBuilder { TextBody = "Your document is attached." };
builder.Attachments.Add("document.pdf", pdfBytes, new ContentType("application", "pdf"));
message.Body = builder.ToMessageBody();
using var smtpClient = new SmtpClient();
await smtpClient.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls);
await smtpClient.AuthenticateAsync("user", "pass");
await smtpClient.SendAsync(message);
await smtpClient.DisconnectAsync(true);
logger.LogInformation("Email sent to {Email} on attempt {Attempt}", recipientEmail, attempt);
return;
}
catch (Exception ex) when (attempt < maxAttempts)
{
logger.LogWarning(ex, "Send attempt {Attempt} failed. Retrying...", attempt);
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
}
}
}
Imports IronPdf
Imports MailKit.Net.Smtp
Imports MailKit.Security
Imports MimeKit
Imports Microsoft.Extensions.Logging
Public Async Function SendPdfEmailWithRetryAsync(
pdfBytes As Byte(),
recipientEmail As String,
subject As String,
logger As ILogger,
Optional maxAttempts As Integer = 3) As Task
For attempt As Integer = 1 To maxAttempts
Try
Dim message = New MimeMessage()
message.From.Add(New MailboxAddress("Mailer", "mailer@example.com"))
message.To.Add(MailboxAddress.Parse(recipientEmail))
message.Subject = subject
Dim builder = New BodyBuilder With {
.TextBody = "Your document is attached."
}
builder.Attachments.Add("document.pdf", pdfBytes, New ContentType("application", "pdf"))
message.Body = builder.ToMessageBody()
Using smtpClient = New SmtpClient()
Await smtpClient.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls)
Await smtpClient.AuthenticateAsync("user", "pass")
Await smtpClient.SendAsync(message)
Await smtpClient.DisconnectAsync(True)
End Using
logger.LogInformation("Email sent to {Email} on attempt {Attempt}", recipientEmail, attempt)
Return
Catch ex As Exception When attempt < maxAttempts
logger.LogWarning(ex, "Send attempt {Attempt} failed. Retrying...", attempt)
Await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)))
End Try
Next
End Function
Wykładnicze opóźnienie — 2 sekundy po pierwszej niepowodzeniu, 4 po drugiej — zapobiega nadmiernemu obciążaniu przeciążonego serwera SMTP. W aplikacjach produkcyjnych należy zastąpić pętlę ponownych prób kolejką komunikatów (Azure Service Bus, RabbitMQ lub AWS SQS), aby awarie nie miały wpływu na ponowne uruchomienie aplikacji.
IronPDF rowniez wyrzuci PdfException, jesli zawartosc HTML nie moze zostac wyrenderowana. Wyłapuj to oddzielnie od wyjątków SMTP, aby komunikat o błędzie był konkretny:
PdfDocument pdf;
try
{
pdf = renderer.RenderHtmlAsPdf(htmlContent);
}
catch (IronPdf.Exceptions.PdfException ex)
{
logger.LogError(ex, "PDF rendering failed");
throw;
}
PdfDocument pdf;
try
{
pdf = renderer.RenderHtmlAsPdf(htmlContent);
}
catch (IronPdf.Exceptions.PdfException ex)
{
logger.LogError(ex, "PDF rendering failed");
throw;
}
Imports IronPdf.Exceptions
Dim pdf As PdfDocument
Try
pdf = renderer.RenderHtmlAsPdf(htmlContent)
Catch ex As PdfException
logger.LogError(ex, "PDF rendering failed")
Throw
End Try
Oddzielenie błędów renderowania od błędów dostarczania przyspiesza debugowanie. Aby uzyskać szerszy obraz obsługi błędów w zautomatyzowanych procesach przetwarzania dokumentów, 5-etapowy przewodnik po generowaniu plików PDF szczegółowo omawia wzorce walidacji.
Jak utrzymać rozmiar załącznika poniżej limitów dostawcy?
Większość komercyjnych dostawców poczty elektronicznej nakłada ograniczenia dotyczące maksymalnego rozmiaru załączników. Gmail ogranicza rozmiar pojedynczego załącznika do 25 MB; W usłudze Microsoft 365 domyślny limit dla standardowych skrzynek pocztowych wynosi 20 MB. Bogato sformatowany raport HTML z osadzonymi obrazami może nieoczekiwanie przekroczyć te limity.
Trzy techniki pomagają zachować te ograniczenia:
Kompresuj obrazy przed renderowaniem. Obrazy wbudowane powinny być w formacie skompresowanym JPEG lub WebP, a nie nieskompresowanym PNG. Logo w formacie PNG o rozdzielczości 600 dpi może zwiększyć rozmiar pliku PDF o kilka megabajtów; Plik JPEG o jakości 85% ma zazwyczaj mniej niż 200 KB przy takim samym efekcie wizualnym.
Uzyj ustawien kompresji IronPDF. Metoda PdfDocument.CompressImages zmniejsza rozdzielczosc osadzonych bitmap po renderowaniu. Wywolaj to przed odczytaniem BinaryData:
pdf.CompressImages(60); // quality 0-100
byte[] compressedPdfBytes = pdf.BinaryData;
pdf.CompressImages(60); // quality 0-100
byte[] compressedPdfBytes = pdf.BinaryData;
pdf.CompressImages(60) ' quality 0-100
Dim compressedPdfBytes As Byte() = pdf.BinaryData
Duże raporty należy podzielić na kilka wiadomości e-mail. Jeśli raport przekracza limit dostawcy nawet po kompresji, należy wygenerować jeden plik PDF na sekcję i wysłać każdy z nich w osobnej wiadomości e-mail. Strona jak-to-zrobic dzielic i laczyc PDF pokazuje, jak podzielic PdfDocument wedlug zakresu stron uzywajac CopyPages.
Zewnętrzne źródła dotyczące limitów rozmiaru w protokole SMTP: limity załączników w Gmailu, limity rozmiaru wiadomości w Microsoft 365.
Jakie są Twoje kolejne kroki?
Masz teraz dzialajacy szablon do generowania PDF w pamieci za pomoca IronPDF i wysylania go jako zalacznik do emaila przy uzyciu zarowno MailKit, jak i System.Net.Mail. Podejście oparte na pamięci eliminuje odczyty i zapisy na dysku, upraszcza wdrażanie w kontenerach, i skalowalne do scenariuszy o wysokiej przepustowości bez potrzeby czyszczenia tymczasowych plików.
Aby pogłębić integrację:
- Zapoznaj się z samouczkiem dotyczącym konwersji HTML do PDF, aby opanować złożone układy dokumentów z nagłówkami, stopkami i numeracją stron.
- Zapoznaj się z opcjami niestandardowego renderowania plików PDF, aby kontrolować marginesy, rozmiar strony i limit czasu wykonywania kodu JavaScript.
- Dodaj podpis cyfrowy do wygenerowanego pliku PDF przed załączeniem go, zapewniając odbiorcom dokumenty zabezpieczone przed manipulacją.
- Wdroż w Azure Functions lub App Service, aby generować dokumenty bezserwerowo na dużą skalę.
- Wypróbuj IronPDF za darmo, aby przetestować pełen zestaw funkcji przed zakupem licencji produkcyjnej, lub zapoznaj się z opcjami licencyjnymi, aby poznać ceny wdrożenia.
Często Zadawane Pytania
Jak mogę wysłać wygenerowany plik PDF jako załącznik do wiadomości e-mail w języku C#?
Korzystając z IronPDF, można wysyłać wygenerowane pliki PDF jako załączniki do wiadomości e-mail, integrując jego funkcje tworzenia plików PDF z funkcjami wysyłania wiadomości e-mail w .NET.
Jakie są zalety wysyłania plików PDF pocztą elektroniczną w aplikacjach .NET?
Wysyłanie plików PDF pocztą elektroniczną w aplikacjach .NET pomaga zautomatyzować dostarczanie dokumentów, usprawniając przepływ pracy w firmie i poprawiając komunikację z klientami.
Czy IronPDF obsługuje treści dynamiczne w plikach PDF załączanych do wiadomości e-mail?
Tak, IronPDF dynamicznie generuje zawartość plików PDF, dzięki czemu nadaje się do aplikacji sterowanych zdarzeniami, które wymagają wysyłania spersonalizowanych plików PDF jako załączników do wiadomości e-mail.
Jakie parametry są powszechnie używane w metodach wysyłania wiadomości e-mail za pomocą IronPDF?
Typowe parametry obejmują temat wiadomości e-mail, informacje o nadawcy oraz EventArgs, które zapewniają wydajne przetwarzanie w aplikacjach sterowanych zdarzeniami.
Dlaczego IronPDF nadaje się do automatyzacji dostarczania dokumentów?
IronPDF nadaje się do automatyzacji dostarczania dokumentów, ponieważ zapewnia niezawodne tworzenie plików PDF i integruje się z funkcjami wysyłania wiadomości e-mail w języku C#.
Czy za pomocą IronPDF można zaplanować wysyłanie plików PDF pocztą elektroniczną?
Tak, IronPDF można zintegrować z zaplanowanymi zadaniami w celu automatyzacji wysyłania wiadomości e-mail w formacie PDF o określonych porach, co poprawia wydajność przepływu pracy.
Czy IronPDF obsługuje tworzenie plików PDF z różnych źródeł danych na potrzeby załączników do wiadomości e-mail?
IronPDF obsługuje tworzenie plików PDF z wielu źródeł danych, umożliwiając programistom generowanie szczegółowych dokumentów do załączników w wiadomościach e-mail.
W jaki sposób IronPDF usprawnia komunikację e-mailową z klientami?
Umożliwiając generowanie i wysyłanie szczegółowych dokumentów PDF jako załączników, IronPDF zwiększa profesjonalizm i przejrzystość komunikacji e-mailowej z klientami.
Czy IronPDF może służyć do wysyłania faktur i raportów jako załączników w formacie PDF?
Tak, IronPDF doskonale nadaje się do generowania i wysyłania faktur, raportów oraz innych dokumentów jako załączników w formacie PDF, zaspokajając różnorodne potrzeby biznesowe.
Jaką rolę odgrywa IronPDF w usprawnianiu procesów biznesowych?
IronPDF usprawnia procesy biznesowe, umożliwiając tworzenie i dystrybucję dokumentów PDF, co ogranicza ręczne interwencje i błędy.

