.NET 8 문서 생성 라이브러리 선택
.NET 8에서는 많은 전통적인 PDF 라이브러리와의 호환성을 깨는 런타임 변경사항이 도입되었습니다. System.Drawing.Common은 비-윈도우 플랫폼에서 더 이상 사용되지 않으며, Native AOT는 반사에 무거운 라이브러리에 새로운 제약을 가하고 있으며, 컨테이너 우선 배포 모델은 윈도우 개발 기계에서 드러나지 않았던 종속성 문제를 드러냅니다. .NET Framework 또는 .NET 6에서 작동했던 라이브러리는 .NET 8에서 NU1202, DllNotFoundException 또는 PlatformNotSupportedException 오류가 발생할 수 있습니다.
이 기사는 .NET 8과 호환되는 PDF 라이브러리를 문서화하고, 맞지 않는 라이브러리에서 발생하는 특정 오류를 보여주며, 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를 타겟으로 합니다. 윈도우, 리눅스, macOS, Docker 및 Azure에도 플랫폼별 설정 없이 배포됩니다.
구형 PDF 라이브러리가 .NET 8에서 실패하는 이유는 무엇입니까?
iTextSharp — .NET 8과 호환되지 않음
iText의 원래 .NET 포트인 iTextSharp은 2018년 이후로 업데이트되지 않았습니다. .NET Framework에만 타겟됩니다:
error NU1202: 패키지 iTextSharp 5.5.13은 net8.0과 호환되지 않습니다.마이그레이션 경로는 iText 7이며, 이는 다른 API를 가지며 AGPL 준수(전체 애플리케이션을 오픈 소스로 공개) 또는 상용 라이선스를 요구합니다. 가격은 공개되지 않았으며, 제3자 데이터에 따르면 연간 $15,000–$210,000입니다.
wkhtmltopdf 래퍼 — .NET 8에서 DLL 로딩 실패
wkhtmltopdf(DinkToPdf, Rotativa, NReco.PdfGenerator) 주위의 C# 래퍼는 .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— 리눅스에서 System.Drawing.Common 실패
PdfSharp는 System.Drawing.Common에 의존하며, 마이크로소프트는 .NET 6에서 비-윈도우 플랫폼용으로 자주적되지 않았습니다. .NET 8에서는 리눅스 또는 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년 초까지 크로스 플랫폼 지원이 불완전합니다. 윈도우 전용 배포의 경우, PdfSharp는 .NET 8과 잘 작동합니다. 리눅스, Docker, 클라우드 배포의 경우, 신뢰할 수 없습니다.
.NET 8과 호환되는 PDF 라이브러리는 무엇입니까?
IronPDF— 전체 .NET 8 지원, 크로스 플랫폼
IronPDF는 내장된 Chromium 렌더링으로 net8.0를 본래적으로 타겟합니다. 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는 .BinaryData로 바이트로 변환할 수 있는 PdfDocument를 반환합니다.
라이선싱: $749부터 시작하는 영구 라이선스 (Lite — 1 개발자, 1 프로젝트). Professional: $1,499 (10 개발자). Enterprise: $2,999 (무제한). ironpdf.com에서 발행되었습니다.
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 뷰, 대시보드 내보내기, 웹 콘텐츠 아카이빙)을 사용하는 경우, 다른 라이브러리가 필요합니다. 커뮤니티 라이선스는 연간 수익 $1M 이하의 비즈니스를 커버합니다; 이를 초과하는 경우, 상용 라이선스가 필요합니다.
iText 7— .NET 8 호환, AGPL 라이선스
iText 7 (iTextSharp의 후속)은 .NET 8을 지원합니다. pdfHTML 애드온은 사용자 지정 파서로 HTML을 PDF로 변환합니다 - 브라우저 엔진이 아닙니다, 따라서 현대의 CSS 기능(플렉스박스, 그리드)은 올바르게 렌더링되지 않습니다.
라이선싱: 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
#IronPDFworks 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"]Alpine 이미지 (더 작은 발자국)
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의 배포 크기 제한이 있습니다 — 총 패키지 크기를 확인하십시오. 프리미엄 또는 전용 계획에서는 이 제한이 적용되지 않습니다. 첫 번째 PDF 생성의 콜드 스타트 지연 시간은 Chromium이 초기화됨에 따라 2–5초입니다.
원주형 AOT 호환성
.NET 8은 원주형 AOT 지원을 확장했지만 PDF 라이브러리는 근본적인 제약에 직면합니다. Chromium 기반 라이브러리(IronPDF, Puppeteer Sharp)는 브라우저 프로세스를 포함하거나 스폰하기 때문에 AOT로 컴파일할 수 없습니다. iText 7은 다수의 반사를 사용하여 트리밍과 충돌합니다.
<PublishAot>true</PublishAot>를 통한 현재 상태:
| 라이브러리 | AOT 상태 | 이유 |
|---|---|---|
| IronPDF | 호환되지 않음 | Chromium 런타임 포함 |
| iText 7 | 호환되지 않음 | 많은 반사, 동적 코드 생성 |
| QuestPDF | 부분적 (with TrimMode=partial) | 일부 반사 사용 |
| PdfSharp | 호환되지 않음 | System.Drawing.Common 종속성 |
Native AOT가 필수 조건이라면, QuestPDF와 TrimMode=partial가 가장 가까운 옵션입니다 — 그러나 HTML 변환이 아닌 프로그래밍 방식의 문서 생성을 위한 것입니다. HTML에서 PDF로의 시나리오에서는 현재 어떤 라이브러리와도 AOT가 사용 가능하지 않습니다.
라이센스 비교
| 라이브러리 | 모델 | 비용 | .NET 8 지원 |
|---|---|---|---|
| IronPDF | 영구적 | $749 (Lite) / $1,499 (Pro) / $2,999 (Enterprise) | 전체 |
| iText 7 | AGPL 또는 구독 | 미발표 ($15K–$210K/년 추정) | 전체 |
| QuestPDF | 커뮤니티 / 상업적 | 수입이 $1M 미만이면 무료, 이후 상업적 | 전체 |
| PdfSharp | MIT (무료) | $0 | Windows 전용 (Linux 불완전) |
| Aspose.PDF | 개발자 당 | ~$999+ | 완전함 (Linux 메모리 문제) |
.NET 9 전방 호환성
.NET 9 (2025년 11월 출시)는 .NET 8에서 확립된 패턴을 계속 따릅니다. .NET 8과 함께 작동하는 라이브러리는 일반적으로 변경 없이 .NET 9에서도 작동합니다. .NET 9의 PDF 생성과 관련된 주요 추가 사항은 ARM64 성능 개선 (Apple Silicon 및 AWS Graviton에서 Chromium 기반 렌더링에 이점)과 계속되는 원주형 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 템플릿을 테스트하여 출력이 기대에 부합하는지 확인하는 것입니다.
추천 사항
.NET 8 프로젝트가 HTML에서 PDF로의 변환을 요구하는 경우: IronPDF는 설정 없이 크로스 플랫폼에서 작동하는 Chromium 포함 렌더링을 제공합니다. 이는 Docker 배포, Azure Functions, 리눅스 컨테이너를 즉시 처리합니다.
.NET 8 프로젝트에서 데이터를 사용해 문서를 프로그래밍 방식으로 생성하는 경우: QuestPDF의 유창한 API는 잘 설계되어 있으며 .NET 8과 호환됩니다. 커뮤니티 라이선스는 대부분의 스타트업과 소규모 팀을 포괄합니다.
Windows에서 PDF 조작(병합, 분할, 양식): 배포 대상이 Windows 전용인 경우 PdfSharp는 여전히 유효합니다.
iTextSharp(호환되지 않음), wkhtmltopdf 래퍼(보관됨, CVE 대상) 및 교차 플랫폼 배포를 위한 System.Drawing.Common에 의존하는 모든 라이브러리를 피하십시오.
