為 .NET 8 選擇文檔產生庫
.NET 8 引入了執行時間更改,破壞了與許多傳統 PDF 程式庫的兼容性。 System.Drawing.Common 在非 Windows 平台上已被棄用,原生 AOT 對大量使用反射的庫施加了新的限制,並且容器優先部署模型暴露了在 Windows 開發機器上未出現的依賴性問題。 在.NET Framework甚至.NET 6 中運作正常的函式庫在.NET 8 中可能會出現 DllNotFoundException 或 PlatformNotSupportedException 錯誤。
本文記錄了哪些 PDF 程式庫可與.NET 8 搭配使用,展示了與不相容的程式庫一起使用時會遇到的具體錯誤,並提供了 Docker 和 Azure Functions 的部署配置。
快速入門:在.NET 8 中從 HTML 產生 PDF
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
var pdf = renderer.RenderHtmlAsPdf(@"
<html>
<head><style>
body { font-family: 'Segoe UI', sans-serif; padding: 40px; }
h1 { color: #2563eb; }
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th { background: #2563eb; color: white; padding: 12px; text-align: left; }
td { padding: 10px; border-bottom: 1px solid #e5e7eb; }
</style></head>
<body>
<h1>Q4 Report</h1>
<table>
<tr><th>Metric</th><th>Value</th><th>Change</th></tr>
<tr><td>Revenue</td><td>$1.2M</td><td>+12%</td></tr>
<tr><td>Users</td><td>45,230</td><td>+23%</td></tr>
</table>
</body></html>");
pdf.SaveAs("report.pdf");using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
var pdf = renderer.RenderHtmlAsPdf(@"
<html>
<head><style>
body { font-family: 'Segoe UI', sans-serif; padding: 40px; }
h1 { color: #2563eb; }
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th { background: #2563eb; color: white; padding: 12px; text-align: left; }
td { padding: 10px; border-bottom: 1px solid #e5e7eb; }
</style></head>
<body>
<h1>Q4 Report</h1>
<table>
<tr><th>Metric</th><th>Value</th><th>Change</th></tr>
<tr><td>Revenue</td><td>$1.2M</td><td>+12%</td></tr>
<tr><td>Users</td><td>45,230</td><td>+23%</td></tr>
</table>
</body></html>");
pdf.SaveAs("report.pdf");透過NuGet安裝:Install-Package IronPdf。 目標 net8.0 無需額外配置。 無需針對特定平台進行設置,即可部署至 Windows、Linux、macOS、Docker 和 Azure。
為什麼舊版 PDF 庫在.NET 8 中無法正常運作?
iTextSharp — 與.NET 8 不相容
iTextSharp(iText 的原始.NET版本)自 2018 年以來就未更新過。它只面向.NET Framework :
錯誤 NU1202:iTextSharp 5.5.13 程式包與 net8.0 不相容。遷移路徑是 iText 7,它具有不同的 API,並且需要遵守 AGPL 協議(開源您的整個應用程式)或獲得商業許可。 價格未公開-第三方數據顯示每年費用為 15,000 美元至 210,000 美元。
wkhtmltopdf 封裝器 — .NET 8 上的 DLL 載入失敗
對 wkhtmltopdf 的 C# 封裝(DinkToPdf、Rotativa、NReco.PdfGenerator)會因.NET 8 部署模型特有的平台特定錯誤而失敗:
DinkToPdf — 未找到本機程式庫:
System.DllNotFoundException:無法載入 DLL"libwkhtmltox"Rotativa.AspNetCore — 需要手動配置二進位檔案路徑,這與.NET 8 的容器優先部署方式相衝突:
// This pattern requires deploying wkhtmltopdf binaries alongside your app
// and breaks in Docker containers without explicit path configuration
RotativaConfiguration.Setup(env.WebRootPath, "wkhtmltopdf");// This pattern requires deploying wkhtmltopdf binaries alongside your app
// and breaks in Docker containers without explicit path configuration
RotativaConfiguration.Setup(env.WebRootPath, "wkhtmltopdf");TuesPechkin / NReco — 架構不符:
System.BadImageFormatException:無法載入檔案或組件這些錯誤反映了一個更深層的問題:wkhtmltopdf於 2024 年 7 月存檔,但其中存在的 CVE 漏洞尚未修復。 原生二進位架構早於.NET 8 的平台偵測改進。 沒有解決辦法——只能遷移到另一個庫。
PdfSharp — Linux 系統繪圖常見故障
PdfSharp 依賴 System.Drawing.Common,而微軟在.NET 6 中已棄用其在非 Windows 平台上的相容性。在.NET 8 中,當部署到 Linux 或 Docker 時,這會導致執行時間失敗:
using PdfSharp.Pdf;
using PdfSharp.Drawing;
var document = new PdfDocument();
// PlatformNotSupportedException on Linux:
// System.Drawing.Common is not supported on this platformusing PdfSharp.Pdf;
using PdfSharp.Drawing;
var document = new PdfDocument();
// PlatformNotSupportedException on Linux:
// System.Drawing.Common is not supported on this platformPdfSharp 6.x 一直在努力消除這種依賴性,但截至 2026 年初,跨平台支援仍不完善。對於僅限 Windows 的部署,PdfSharp 可與.NET 8 搭配使用。對於 Linux、Docker 或雲端部署,其相容性不穩定。
哪些 PDF 函式庫與.NET 8 相容?
IronPDF — 完全支援.NET 8,跨平台
IronPDF原生支援 net8.0 和嵌入式 Chromium 渲染。 不依賴 System.Drawing.Common,不進行本地二進位管理,不進行平台特定的配置。
最小化 API 整合( .NET 8 的主要模式):
using IronPdf;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/invoice/{id}/pdf", async (int id, InvoiceService service) =>
{
var invoice = await service.GetInvoiceAsync(id);
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(invoice.ToHtml());
return Results.File(pdf.BinaryData, "application/pdf", $"invoice-{id}.pdf");
});
app.Run();using IronPdf;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/invoice/{id}/pdf", async (int id, InvoiceService service) =>
{
var invoice = await service.GetInvoiceAsync(id);
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(invoice.ToHtml());
return Results.File(pdf.BinaryData, "application/pdf", $"invoice-{id}.pdf");
});
app.Run();對於使用控制器模式的團隊來說,相同的程式碼可以在控制器操作中運行——RenderHtmlAsPdf 返回一個 PdfDocument,你可以使用 .BinaryData 將其轉換為位元組。
授權:永久授權起價 749 美元(精簡版 — 1 位開發者,1 個專案)。 專業版:1,499 美元(10 位開發人員)。 企業版:2,999 美元(無限制)。 發佈於IronPDF 。
QuestPDF — 相容.NET 8,無需 HTML
QuestPDF 可與.NET 8 搭配使用,無需平台依賴。 它流暢的 C# API 以程式設計方式建立文件——無需 HTML 解析器、CSS 引擎或瀏覽器引擎:
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
QuestPDF.Settings.License = LicenseType.Community; // Free under $1M revenue
Document.Create(container =>
{
container.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);
page.Content().Column(col =>
{
col.Item().Text("Q4 Report").FontSize(24).Bold();
col.Item().Table(table =>
{
table.ColumnsDefinition(c => { c.RelativeColumn(2); c.RelativeColumn(1); c.RelativeColumn(1); });
table.Header(h =>
{
h.Cell().Text("Metric").Bold();
h.Cell().Text("Value").Bold();
h.Cell().Text("Change").Bold();
});
table.Cell().Text("Revenue"); table.Cell().Text("$1.2M"); table.Cell().Text("+12%");
table.Cell().Text("Users"); table.Cell().Text("45,230"); table.Cell().Text("+23%");
});
});
});
}).GeneratePdf("report.pdf");using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
QuestPDF.Settings.License = LicenseType.Community; // Free under $1M revenue
Document.Create(container =>
{
container.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);
page.Content().Column(col =>
{
col.Item().Text("Q4 Report").FontSize(24).Bold();
col.Item().Table(table =>
{
table.ColumnsDefinition(c => { c.RelativeColumn(2); c.RelativeColumn(1); c.RelativeColumn(1); });
table.Header(h =>
{
h.Cell().Text("Metric").Bold();
h.Cell().Text("Value").Bold();
h.Cell().Text("Change").Bold();
});
table.Cell().Text("Revenue"); table.Cell().Text("$1.2M"); table.Cell().Text("+12%");
table.Cell().Text("Users"); table.Cell().Text("45,230"); table.Cell().Text("+23%");
});
});
});
}).GeneratePdf("report.pdf");QuestPDF 不轉換 HTML。 如果您的工作流程使用 HTML 範本(Razor視圖、儀表板匯出、Web 內容歸檔),則需要不同的程式庫。 社區許可證適用於年收入低於 100 萬美元的企業; 此外,還需要商業許可。
iText 7 — 相容.NET 8,AGPL 許可
iText 7(iTextSharp 的繼任者)支援.NET 8。 pdfHTML 外掛程式使用自訂解析器提供 HTML 到 PDF 的轉換,而不是瀏覽器引擎,因此現代 CSS 功能(Flexbox、Grid)無法正確渲染。
許可:開源用途採用AGPL 許可,專有應用程式採用商業許可(訂閱,價格未公佈)。 iText 於 2024 年轉型為基於訂閱的商業授權模式。
Docker部署
標準 Debian 鏡像(建議)
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["MyApp.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
# IronPDF works without additional apt-get installs
# Chromium dependencies are handled internally
COPY --from=build /app/publish .
ENV DOTNET_RUNNING_IN_CONTAINER=true
EXPOSE 8080
ENTRYPOINT ["dotnet", "MyApp.dll"]高山影像(佔地面積較小)
FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build
WORKDIR /src
COPY ["MyApp.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
WORKDIR /app
# Alpine requires explicit Chromium dependencies
RUN apk add --no-cache chromium nss freetype harfbuzz ca-certificates ttf-freefont
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]Debian鏡像不需要任何額外的軟體包。 Alpine鏡像檔較小,但需要明確安裝Chromium庫。 對於大多數部署而言,標準的 Debian 鏡像更簡單、更可靠。
Azure Functions(獨立工作流程)
.NET 8 Azure Functions 使用隔離工作器模型。 IronPDF採用這種模式進行按需PDF生成:
using IronPdf;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
namespace MyApp.Functions;
public class PdfFunctions
{
[Function("GenerateInvoice")]
public async Task<HttpResponseData> GenerateInvoice(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req)
{
var invoice = await req.ReadFromJsonAsync<InvoiceRequest>();
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(BuildInvoiceHtml(invoice));
var response = req.CreateResponse(System.Net.HttpStatusCode.OK);
response.Headers.Add("Content-Type", "application/pdf");
response.Headers.Add("Content-Disposition",
$"attachment; filename=invoice-{invoice.Id}.pdf");
await response.Body.WriteAsync(pdf.BinaryData);
return response;
}
private string BuildInvoiceHtml(InvoiceRequest invoice)
{
return $@"<html><body>
<h1>Invoice #{invoice.Id}</h1>
<p>Amount: ${invoice.Amount:F2}</p>
</body></html>";
}
}
public record InvoiceRequest(string Id, decimal Amount);using IronPdf;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
namespace MyApp.Functions;
public class PdfFunctions
{
[Function("GenerateInvoice")]
public async Task<HttpResponseData> GenerateInvoice(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req)
{
var invoice = await req.ReadFromJsonAsync<InvoiceRequest>();
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(BuildInvoiceHtml(invoice));
var response = req.CreateResponse(System.Net.HttpStatusCode.OK);
response.Headers.Add("Content-Type", "application/pdf");
response.Headers.Add("Content-Disposition",
$"attachment; filename=invoice-{invoice.Id}.pdf");
await response.Body.WriteAsync(pdf.BinaryData);
return response;
}
private string BuildInvoiceHtml(InvoiceRequest invoice)
{
return $@"<html><body>
<h1>Invoice #{invoice.Id}</h1>
<p>Amount: ${invoice.Amount:F2}</p>
</body></html>";
}
}
public record InvoiceRequest(string Id, decimal Amount);部署注意事項: IronPDF 的 Chromium 二進位檔案會使部署包增加約 200MB。 Azure Functions 消耗計畫的部署大小限制為 1.5GB - 請確認您的總套件大小。高級版或專用版計劃不受此限制。 由於 Chromium 初始化,首次產生 PDF 的冷啟動延遲為 2-5 秒。
原生 AOT 相容性
.NET 8 擴展了原生 AOT 支持,但 PDF 庫面臨根本性的限制。 基於 Chromium 的函式庫(IronPDF、Puppeteer Sharp)無法編譯 AOT,因為它們嵌入或產生瀏覽器進程。 iText 7 使用了大量的反射功能,這與裁切功能相衝突。
與 <PublishAot>true</PublishAot> 的目前狀態:
| 圖書館 | AOT狀態 | 原因 |
|---|---|---|
| IronPDF | 不相容 | 嵌入 Chromium 運行時 |
| iText 7 | 不相容 | 深度反射,動態程式碼生成 |
| QuestPDF | 部份(含 TrimMode=partial) | 一些反思用法 |
| PdfSharp | 不相容 | 系統.繪圖.通用依賴關係 |
如果原生 AOT 是硬性要求,那麼 QuestPDF 和 TrimMode=partial 是最接近的選擇——但僅用於程式化文件生成,而不是 HTML 轉換。 對於 HTML 轉 PDF 的場景,目前沒有任何函式庫支援 AOT。
許可比較
| 圖書館 | 模型 | 成本 | .NET 8 支持 |
|---|---|---|---|
| IronPDF | 永久 | 749 美元(精簡版)/ 1,499 美元(專業版)/ 2,999 美元(企業版) | 滿的 |
| iText 7 | AGPL 或訂閱 | 未公佈(估計年薪 1.5 萬至 21 萬美元) | 滿的 |
| QuestPDF | 社區/商業 | 免費,收入低於 100 萬美元,然後商業化 | 滿的 |
| PdfSharp | 麻省理工學院(免費) | $0 | 僅限 Windows 系統(Linux 系統功能不完整) |
| Aspose.PDF | 每個開發商 | 約999美元以上 | 記憶體不足(Linux 記憶體問題) |
.NET 9 向前相容性
.NET 9(2025 年 11 月發布)延續了.NET 8 中建立的模式。與.NET 8 相容的程式庫通常無需更改即可與.NET 9 相容。 與 PDF 生成相關的.NET 9 的主要新增功能包括改進的 ARM64 性能(有利於 Apple Silicon 和 AWS Graviton 上的基於 Chromium 的渲染)以及持續的 Native AOT 改進(儘管 PDF 庫的基本限制仍然存在)。
如果您面向.NET 9 或計劃升級,那麼選擇一個完全支援.NET 8 跨平台部署的程式庫是最安全的途徑。 存在平台特定問題的程式庫(例如 Linux 上的 PdfSharp、帶有 libgdiplus 的 Aspose)不太可能在.NET 9 中解決這些問題,因為底層依賴項的棄用是永久性的。
遷移指南
從 iTextSharp 到IronPDF
// Before (iTextSharp — doesn't compile against net8.0)
using iTextSharp.text;
using iTextSharp.text.pdf;
var doc = new Document();
PdfWriter.GetInstance(doc, new FileStream("output.pdf", FileMode.Create));
doc.Open();
doc.Add(new Paragraph("Hello World"));
doc.Close();
// After (IronPDF — targets net8.0)
using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<p>Hello World</p>");
pdf.SaveAs("output.pdf");// Before (iTextSharp — doesn't compile against net8.0)
using iTextSharp.text;
using iTextSharp.text.pdf;
var doc = new Document();
PdfWriter.GetInstance(doc, new FileStream("output.pdf", FileMode.Create));
doc.Open();
doc.Add(new Paragraph("Hello World"));
doc.Close();
// After (IronPDF — targets net8.0)
using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<p>Hello World</p>");
pdf.SaveAs("output.pdf");從 wkhtmltopdf 封裝器到IronPDF
// Before (DinkToPdf — DllNotFoundException on .NET 8)
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument
{
Objects = { new ObjectSettings { HtmlContent = html } }
};
var bytes = converter.Convert(doc);
// After (IronPDF — native .NET 8 support)
using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
var bytes = pdf.BinaryData;// Before (DinkToPdf — DllNotFoundException on .NET 8)
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument
{
Objects = { new ObjectSettings { HtmlContent = html } }
};
var bytes = converter.Convert(doc);
// After (IronPDF — native .NET 8 support)
using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
var bytes = pdf.BinaryData;兩種情況下,API介面都更簡單。 遷移的主要成本是使用新的渲染器測試現有的 HTML 模板,以驗證輸出是否符合預期。
建議
對於需要將 HTML 轉換為 PDF 的.NET 8 專案: IronPDF提供嵌入式 Chromium 渲染,無需配置即可跨平台工作。 它開箱即用,可處理 Docker 部署、Azure Functions 和 Linux 容器。
對於使用.NET 8 以程式設計方式從資料建立文件的專案:QuestPDF 的流暢 API 設計精良,與.NET 8 相容,社群授權涵蓋了大多數新創公司和小型團隊。
對於 Windows 上的 PDF 處理(合併、分割、表單):如果您的部署目標僅限於 Windows,則 PdfSharp 仍然可用。
避免使用 iTextSharp(不相容)、wkhtmltopdf 包裝器(已存檔,存在 CVE)以及任何依賴 System.Drawing.Common 的程式庫進行跨平台部署。
