跳至頁尾內容
使用IRONPDF

如何在 .NET 中將 PDF 轉換為圖像

自動化文件傳遞是在幾乎每個業務線的.NET應用程式中出現的需求。 當訂單下達時,發票必須在幾秒鐘內到達客戶手中。 當報告在夜間運行時,持份人期望它能在他們到達辦公室前出現在收件箱中。最簡單的、最廣泛支持的傳遞格式是作為電子郵件附件發送的PDF。 本指南將引導您完成使用C#的完整工作流程——在記憶體中使用IronPDF生成PDF文件,然後使用MailKit或內建的System.Net.Mail命名空間將其作為電子郵件附件發送,而不寫入單一字節至磁碟。

如何安裝所需的程式包?

這個工作流程由兩個程式包推動:PDF生成庫和電子郵件發送庫。 通過Visual Studio中的套件管理器控制台或.NET CLI安裝兩者。

Install-Package IronPdf, MailKit

IronPDF帶來了一個基於Chromium的渲染引擎,將HTML、CSS和JavaScript轉換為像素完美的PDF文件。 它可以在Windows、Linux和macOS上運行,這意味著相同的程式碼可以在ASP.NET Core網頁API、背景服務或Azure函式中運行。 MailKit是Microsoft推薦用於所有新.NET電子郵件開發的庫——它支持SMTP、IMAP、POP3、OAuth 2.0以及完整的MIME構造。 MailKit的源程式碼和文件可在GitHub上獲得。

如何在記憶體中生成PDF文件?

ChromePdfRendererHTML到PDF轉換的入口。 傳遞一個HTML字串到PdfDocument物件。 通過BinaryData屬性存取原始位元組資料——這個位元組陣列正是電子郵件附件API所期望的。

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

RenderHtmlAsPdf方法使用Google Chrome提供的相同Chromium引擎來解析HTML,因此表格、CSS網格、Flexbox和嵌入字型都會像在瀏覽器中一樣精確渲染。 結果是一個BinaryData屬性返回完整的PDF二進位文件,無需任何磁碟讀寫。 對於需要引入外部圖像或樣式表的文件,使用可選的BasePath參數告訴IronPDF在哪裡解析相對資源URL,這在HTML文件到PDF使用指南中有詳細介紹。

設定頁面佈局和自定義頁眉

在附加PDF之前,您可能需要配置邊距、頁眉或頁脚。 所有佈局選項都在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
$vbLabelText   $csharpLabel

邊距單位為毫米。 {total-pages}標記會在渲染時替換。HTML字串到PDF使用指南涵蓋了完整的渲染選項集。 您還可以在生成的文件上增加水印蓋章文字和圖像,然後再附加它。

如何使用MailKit將PDF附加到電子郵件中?

MailKit直接構建了一棵MIME消息樹,讓您完全控制內容型別、編碼和附件元資料。 BodyBuilder輔助類簡化了包含一個或多個文件附件的文字或HTML正文的常見情況。

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

ContentType實例。 非同步的SMTP方法在網路操作完成時保持調用執行緒空閒——這在ASP.NET Core控制器中處理多個同時請求時尤為關鍵。

AuthenticateAsync。 對於Microsoft 365,在MailKit的SaslMechanismOAuth2類中配置OAuth 2.0身份驗證,如果您的租戶已禁用基本身份驗證。

發送給多個收件人

要將相同電子郵件副本發送給多個人,請在調用Bcc集合中:

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

一個SendAsync調用將消息傳遞給所有地址。 MailKit在一次SMTP會話中批次執行RCPT TO命令,因此多個收件人不會影響性能。

如何使用System.Net.Mail作為替代方案?

對於針對舊的.NET版本的專案或不允許增加第三方NuGet包的專案,內建的System.Net.Mail命名空間可以進行基本的SMTP傳遞。 Microsoft不再建議將其用於新開發,但它可以覆蓋常見的使用情境而無需額外依賴。

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

與MailKit相比的關鍵區別在於using語句中,這會在發送後處置SMTP連接並刷新底層流。 如果您省略MailMessage上的調用,附件流可能會在某些運行時完成發送前被處置。

在MailKit和System.Net.Mail之間選擇

MailKit與System.Net.Mail功能比較
功能 MailKit System.Net.Mail
OAuth 2.0身份驗證
IMAP / POP3支持
優先非同步的API 部分
Microsoft的推薦 推薦 傳統
附加的NuGet包 需要 不需要
複雜的MIME構造 完全支持 基本

對於任何新專案,尤其是如果SMTP伺服器需要OAuth或您需要IMAP以讀取回覆時,選擇MailKit。 當程式碼庫已經依賴於System.Net.Mail而轉移成本不合理時使用。

如何將此模式應用於實際的業務工作流程?

這種記憶體中PDF到電子郵件的模式可以直接應用於驅動大多數業務應用的文件自動化場景。

發票自動化

一個電商訂單處理器在付款捕獲後立即生成發票PDF。 RenderHtmlAsPdf,然後將結果發送到客戶的電子郵件地址。 由於PDF從未觸及文件系統,因此無需清理遺留文件,對共享臨時目錄的競賽條件也不會存在,容器化部署中也不會有許可權問題。 關於從Razor視圖渲染HTML的更多資訊,請參閱ASP.NET Core PDF生成指南

計劃報告分發

一個使用IHostedService進行計劃的背景服務每週一早上06:00生成每週分析摘要。 它查詢資料庫,構建HTML報告字串,用IronPDF渲染,並使用MailKit發送到分發列表。整個管道作為非同步工作流程運行,因此在SMTP握手期間不會佔用執行緒池執行緒。 對於以Azure為主機的工作負載,Azure PDF生成器指南解釋了如何在Azure應用服務和Azure函式內部署IronPDF。

在ASP.NET Core中生成收據

在ASP.NET Core輕量API或控制器操作中,POST端點接收結帳有效載荷,生成收據PDF,並在同時發送電子郵件時返回HTTP 200。 將電子郵件發送邏輯保持在背景Task中,以便HTTP響應立即返回給客戶端:

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

即使SMTP伺服器速度較慢,也能保持API響應時間低於100毫秒。 emailService註冊為封裝MailKit SmtpClient的範疇或瞬態服務。

如何處理錯誤和重試?

網路操作會失敗。 SMTP伺服器暫時無法使用,身份驗證令牌過期,附件大小限制因提供者而異。 從一開始就在電子郵件發送路徑中建立彈性。

將MailKit發送邏輯包裹在try/catch中並將失敗記錄到持久化隊列中,以便可以重試:

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

指數回退——第一次失敗後2秒,第二次後4秒——防止打擊過載的SMTP伺服器。 在生產應用中,將重試迴圈替換為消息隊列(Azure Service Bus,RabbitMQ或AWS SQS),以便失敗能夠在應用重啟後存活。

如果HTML內容無法渲染,IronPDF也會拋出PdfException。 從SMTP異常中單獨捕獲它,以便錯誤消息能夠明確:

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

將渲染錯誤與傳遞錯誤分開,使故障排除過程更快。 5步PDF生成指南涵蓋了自動文件流水線中錯誤處理解決方案的詳細內容。

如何保持附件在提供者限制範圍內?

大多數商業電子郵件提供商強制執行最大附件大小限制。Gmail將個別附件限制為25 MB; Microsoft 365的標準信箱預設限制為20 MB。 樣式繁重的HTML報告中包含的嵌入圖像可以意外超出這些限制。

三種技術可以幫助保持在限制內:

在渲染前壓縮圖像。內嵌圖像應使用壓縮的JPEG或WebP而非未壓縮的PNG。 一個600 dpi的PNG標誌可以為PDF增加好幾MB的大小; 使用85%品質的JPEG通常在200 KB以下,並且視覺效果相同。

使用IronPDF的壓縮設置。PdfDocument.CompressImages方法在渲染后減少嵌入位圖的解析度。 在讀取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
$vbLabelText   $csharpLabel

將大型報告拆分為多封電子郵件。如果報告在壓縮後仍超出提供者限制,則生成分段的PDF,並分別以多封電子郵件形式發送。 PDF拆分和合併使用指南展示了如何使用PdfDocument

SMTP大小限制的外部參考:Gmail附件限制, Microsoft 365郵件大小限制

您的下一步該怎麼做?

您現在擁有一個工作模板來利用IronPDF在記憶體中生成PDF並使用MailKit或System.Net.Mail將其作為電子郵件附件發送。 這種記憶體中方法消除了磁碟讀寫,簡化了容器化部署,並且在不需要清理臨時文件的情況下擴展到高吞吐量場景。

要深入整合:

常見問題

如何在C#中將生成的PDF作為電子郵件附件發送?

使用IronPDF,您可以通過將其PDF建立功能與.NET的電子郵件發送功能整合,將生成的PDF文件作為電子郵件附件發送。

在.NET應用程式中通過電子郵件發送PDF文件有什麼好處?

在.NET應用程式中通過電子郵件發送PDF文件有助於自動化文件傳送,簡化業務工作流程和提升客戶通信。

IronPDF能否在PDFs中處理動態內容用於電子郵件附件?

是的,IronPDF可以動態生成PDF內容,使其適用於需要發送定制PDFs作為電子郵件附件的事件驅動應用程式。

在使用IronPDF的電子郵件發送方法中常用哪些參數?

常用的參數包括電子郵件主題、發件人的資訊和EventArgs,這些確保在事件驅動的應用程式中有效處理。

為何IronPDF適合自動化文件傳送?

IronPDF適合自動化文件傳送,因為它提供可靠的PDF建立功能,並與C#的電子郵件發送功能整合。

能否使用IronPDF安排PDF電子郵件發送日程?

是的,IronPDF可以整合到計畫任務中,以自動化在指定時間發送PDF電子郵件,提高工作流程效率。

IronPDF是否支持從各種資料源建立PDFs用於電子郵件附件?

IronPDF支持從多個資料源建立PDFs,允許開發者生成詳細的文件,用於電子郵件附件。

IronPDF如何提升與客戶的電子郵件通信?

通過允許生成並發送詳細的PDF文件作為附件,IronPDF提升了與客戶的電子郵件通信的專業性和清晰度。

IronPDF是否可以用於發送發票和報告作為PDF附件?

是的,IronPDF非常適合生成並發送發票、報告及其他文件作為PDF附件,滿足各種業務需求。

IronPDF在改進業務工作流程中扮演什麼角色?

IronPDF透過啟用PDF文件的建立和分發,減少人工干預和錯誤,提高了業務工作流程。

Curtis Chau
技術作家

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

除了開發,Curtis對物聯網(IoT)有濃厚的興趣,探索創新的方法來整合硬體和軟體。在空閒時間,他喜歡玩遊戲和建立Discord機器人,結合他對技術的熱愛與創造力。

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話