C#에서 Api2pdf에서 IronPDF로 마이그레이션하는 방법
Api2pdf는 PDF 생성을 위한 클라우드 기반 서비스를 제공하지만, 민감한 문서를 외부 서버에 보내면 보안 위험, 규정 준수 문제, 시간이 지남에 따라 증가할 수 있는 지속적인 비용을 초래할 수 있습니다. 이 가이드는 Api2pdf에서 IronPDF로의 자세한 마이그레이션 경로를 제공하며, IronPDF는 문서를 완전히 자체 인프라에서 처리하여 데이터 전송 문제를 제거하고 변환당 비용을 일회성 투자로 전환합니다.
왜 Api2pdf에서 이동을 고려해야 하나요?
Api2pdf는 편리한 클라우드 기반 PDF 생성을 제공하지만, 몇 가지 요인으로 인해 개발 팀은 PDF 생성 요구 사항을 위한 온프레미스 대안을 찾습니다.
보안 및 규정 준수 관련 문제
Api2pdf는 클라우드 기반 서비스로, 귀하의 민감한 HTML 및 문서를 타사 서버에 처리하기 위해 보냅니다. 이는 규제 데이터를 처리하는 조직에 상당한 우려를 불러일으킵니다.
| 위험 | Api2pdf | IronPDF |
|---|---|---|
| 데이터 전송 | 모든 콘텐츠가 외부 서버로 전송됨 | 귀하의 인프라에서 로컬로 처리됨 |
| GDPR 준수 | 데이터가 관할권을 넘나듦 | 데이터가 귀하의 환경을 떠나지 않음 |
| HIPAA 준수 | PHI가 외부로 전송됨 | PHI가 귀하의 시스템 내에 유지됨 |
| SOC 2 | 타사 의존성 | 데이터 처리에 대한 완전한 제어 |
| PCI DSS | 카드 데이터가 잠재적으로 노출됨 | 외부 전송이 없음 |
시간이 지남에 따른 비용 누적
Api2pdf는 변환당 약 $0.005를 무기한 청구하는 반면, IronPDF는 영구적인 일회성 라이선스를 제공합니다. 상당한 PDF 볼륨을 생성하는 애플리케이션의 경우 비용 차이가 상당해집니다:
| 볼륨 | Api2pdf (연간) | IronPDF (일회성) |
|---|---|---|
| 10,000 PDF/월 | ~$600/년 | $749 (Lite) |
| 50,000 PDF/월 | ~$3,000/년 | $749 (Lite) |
| 100,000 PDF/월 | ~$6,000/년 | $1,499 (Plus) |
IronPDF는 대부분의 프로덕션 애플리케이션에서 몇 달 이내에 본전을 찾습니다.
성능 및 가용성
Api2pdf는 네트워크 왕복이 필요하여 PDF 생성 요청당 2~5초의 지연 시간을 추가합니다. IronPDF는 로컬에서 100~500 밀리초에 처리합니다. 또한, IronPDF는 오프라인 환경과 에어갭 환경에서 완전히 작동하며, 외부 서비스 가용성에 의존할 수 없는 애플리케이션에 필수적입니다.
Api2pdfvs. IronPDF: 주요 차이점
| 측면 | Api2pdf | IronPDF |
|---|---|---|
| 데이터 처리 | 제3자 클라우드 서버로 전송 | 귀하의 인프라에서 로컬로 처리 |
| 가격 | 변환당 요금(~$0.005/PDF) | 일회성 영구 라이선스 |
| 지연 시간 | 2-5초(네트워크 왕복 시간) | 100-500ms(로컬 처리) |
| 오프라인 | 사용 불가 | 완전한 오프라인 작동 |
| 설치 | API 키 + HTTP 클라이언트 | 간단한 NuGet 패키지 |
| 규정 준수 | GDPR/HIPAA 문제 (데이터가 네트워크를 떠남) | 완전한 규정 준수 제어 |
단계별 마이그레이션 프로세스
1단계: NuGet 패키지 업데이트
Api2pdf 패키지를 제거하고 IronPDF를 설치하세요:
# Remove Api2pdf
dotnet remove package Api2Pdf
# Install IronPDF
dotnet add package IronPdf
# Remove Api2pdf
dotnet remove package Api2Pdf
# Install IronPDF
dotnet add package IronPdf
또는 패키지 관리자 콘솔을 통해:
Uninstall-Package Api2Pdf
Install-Package IronPdf
2단계: 네임스페이스 참조 업데이트
Api2pdf 네임스페이스를 IronPDF로 교체하세요:
// Remove these
using Api2Pdf;
using Api2Pdf.DotNet;
// Add these
using IronPdf;
using IronPdf.Rendering;
// Remove these
using Api2Pdf;
using Api2Pdf.DotNet;
// Add these
using IronPdf;
using IronPdf.Rendering;
Imports IronPdf
Imports IronPdf.Rendering
3단계: 라이선스 키 구성
어플리케이션 시작 시IronPDF라이선스 키를 설정하세요:
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Or configure via appsettings.json:
// { "IronPdf.LicenseKey": "YOUR-IRONPDF-LICENSE-KEY" }
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Or configure via appsettings.json:
// { "IronPdf.LicenseKey": "YOUR-IRONPDF-LICENSE-KEY" }
' Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY"
' Or configure via appsettings.json:
' { "IronPdf.LicenseKey": "YOUR-IRONPDF-LICENSE-KEY" }
4단계: API 키 구성 제거
IronPDF는 로컬에서 실행되며 API 키가 필요하지 않습니다:
// Remove thisApi2pdfpattern
var client = new Api2PdfClient("API_KEY");
// Just create the renderer directly
var renderer = new ChromePdfRenderer();
// Remove thisApi2pdfpattern
var client = new Api2PdfClient("API_KEY");
// Just create the renderer directly
var renderer = new ChromePdfRenderer();
' Remove thisApi2pdfpattern
Dim client = New Api2PdfClient("API_KEY")
' Just create the renderer directly
Dim renderer = New ChromePdfRenderer()
완전한 API 마이그레이션 참조
핵심 클래스 매핑
| Api2pdf 클래스 | IronPDF 동등 |
|---|---|
Api2PdfClient |
ChromePdfRenderer |
Api2PdfResult |
PdfDocument |
HeadlessChromeOptions |
ChromePdfRenderOptions |
메서드 매핑
| Api2pdf 메서드 | IronPDF 메소드 |
|---|---|
client.HeadlessChrome.FromHtmlAsync(html) |
renderer.RenderHtmlAsPdf(html) |
client.HeadlessChrome.FromUrlAsync(url) |
renderer.RenderUrlAsPdf(url) |
response.Pdf (URL) |
pdf.SaveAs(path) |
response.Pdf (download) |
pdf.BinaryData |
client.PdfSharp.MergePdfsAsync(urls) |
PdfDocument.Merge(pdfs) |
client.PdfSharp.SetPasswordAsync(url, pwd) |
pdf.SecuritySettings.OwnerPassword |
렌더링 옵션 매핑
| Api2pdf 옵션 | IronPDF 옵션 |
|---|---|
Landscape = true |
RenderingOptions.PaperOrientation = Landscape |
PageSize = "A4" |
RenderingOptions.PaperSize = PdfPaperSize.A4 |
PrintBackground = true |
RenderingOptions.PrintHtmlBackgrounds = true |
MarginTop, etc. |
RenderingOptions.MarginTop, etc. |
Delay = 5000 |
RenderingOptions.WaitFor.RenderDelay(5000) |
코드 마이그레이션 예제
HTML을 PDF로 변환
가장 일반적인Api2pdf작업은 클라우드 API 호출에서 로컬 처리로의 근본적인 전환을 보여줍니다.
Api2pdf 구현:
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
var apiResponse = await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Hello World</h1>");
Console.WriteLine(apiResponse.Pdf);
}
}
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
var apiResponse = await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Hello World</h1>");
Console.WriteLine(apiResponse.Pdf);
}
}
Imports System
Imports System.Threading.Tasks
Imports Api2Pdf.DotNet
Module Program
Async Function Main(args As String()) As Task
Dim a2pClient = New Api2PdfClient("your-api-key")
Dim apiResponse = Await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Hello World</h1>")
Console.WriteLine(apiResponse.Pdf)
End Function
End Module
IronPDF 구현:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}
Imports System
Imports IronPdf
Class Program
Shared Sub Main(ByVal args As String())
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>")
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF created successfully")
End Sub
End Class
IronPDF는 네트워크 왕복, API 키 관리, 그리고 Api2pdf의 URL 기반 응답 패턴이 요구하는 별도의 다운로드 단계를 제거합니다.
URL을 PDF로 변환
Api2pdf 구현:
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
var apiResponse = await a2pClient.HeadlessChrome.FromUrlAsync("https://www.example.com");
Console.WriteLine(apiResponse.Pdf);
}
}
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
var apiResponse = await a2pClient.HeadlessChrome.FromUrlAsync("https://www.example.com");
Console.WriteLine(apiResponse.Pdf);
}
}
Imports System
Imports System.Threading.Tasks
Imports Api2Pdf.DotNet
Module Program
Async Function Main(args As String()) As Task
Dim a2pClient = New Api2PdfClient("your-api-key")
Dim apiResponse = Await a2pClient.HeadlessChrome.FromUrlAsync("https://www.example.com")
Console.WriteLine(apiResponse.Pdf)
End Function
End Module
IronPDF 구현:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF created from URL successfully");
}
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF created from URL successfully");
}
}
Imports System
Imports IronPdf
Module Program
Sub Main(args As String())
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
pdf.SaveAs("webpage.pdf")
Console.WriteLine("PDF created from URL successfully")
End Sub
End Module
HTML 파일을 PDF로 변환 (옵션 포함)
Api2pdf 구현:
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.IO;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
string html = File.ReadAllText("input.html");
var options = new HeadlessChromeOptions
{
Landscape = true,
PrintBackground = true
};
var apiResponse = await a2pClient.HeadlessChrome.FromHtmlAsync(html, options);
Console.WriteLine(apiResponse.Pdf);
}
}
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.IO;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
string html = File.ReadAllText("input.html");
var options = new HeadlessChromeOptions
{
Landscape = true,
PrintBackground = true
};
var apiResponse = await a2pClient.HeadlessChrome.FromHtmlAsync(html, options);
Console.WriteLine(apiResponse.Pdf);
}
}
no response after 91 seconds
IronPDF 구현:
// NuGet: Install-Package IronPdf
using System;
using System.IO;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Landscape;
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
string html = File.ReadAllText("input.html");
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created with options successfully");
}
}
// NuGet: Install-Package IronPdf
using System;
using System.IO;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Landscape;
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
string html = File.ReadAllText("input.html");
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created with options successfully");
}
}
Imports System
Imports System.IO
Imports IronPdf
Module Program
Sub Main(args As String())
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Landscape
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
Dim html As String = File.ReadAllText("input.html")
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF created with options successfully")
End Sub
End Module
IronPDF는 각 API 호출에 별도의 옵션 매개변수로 전달하는 대신, 렌더러 객체에서 직접 렌더링 옵션을 구성합니다.
여러 PDF 병합
Api2pdf 구현:
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
var pdfUrls = new List<string>
{
"https://example.com/pdf1.pdf",
"https://example.com/pdf2.pdf",
"https://example.com/pdf3.pdf"
};
var request = new PdfMergeRequest { Urls = pdfUrls };
var response = await a2pClient.PdfSharp.MergePdfsAsync(request);
if (response.Success)
{
// Download merged PDF from response.Pdf URL
}
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
var pdfUrls = new List<string>
{
"https://example.com/pdf1.pdf",
"https://example.com/pdf2.pdf",
"https://example.com/pdf3.pdf"
};
var request = new PdfMergeRequest { Urls = pdfUrls };
var response = await a2pClient.PdfSharp.MergePdfsAsync(request);
if (response.Success)
{
// Download merged PDF from response.Pdf URL
}
Imports Api2Pdf.DotNet
Dim a2pClient = New Api2PdfClient("YOUR_API_KEY")
Dim pdfUrls = New List(Of String) From {
"https://example.com/pdf1.pdf",
"https://example.com/pdf2.pdf",
"https://example.com/pdf3.pdf"
}
Dim request = New PdfMergeRequest With {.Urls = pdfUrls}
Dim response = Await a2pClient.PdfSharp.MergePdfsAsync(request)
If response.Success Then
' Download merged PDF from response.Pdf URL
End If
IronPDF 구현:
using IronPdf;
// Load PDFs from files
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var pdf3 = PdfDocument.FromFile("document3.pdf");
// Merge all PDFs
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("merged.pdf");
using IronPdf;
// Load PDFs from files
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var pdf3 = PdfDocument.FromFile("document3.pdf");
// Merge all PDFs
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("merged.pdf");
Imports IronPdf
' Load PDFs from files
Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")
Dim pdf3 = PdfDocument.FromFile("document3.pdf")
' Merge all PDFs
Dim merged = PdfDocument.Merge(pdf1, pdf2, pdf3)
merged.SaveAs("merged.pdf")
IronPDF의 정적 Merge 메서드는 여러 문서를 직접 수락하여 URL 기반 워크플로를 제거합니다.
비밀번호로 보호된 PDF
Api2pdf 구현:
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
// Generate PDF first
var pdfResponse = await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Confidential</h1>");
// Then add password protection in separate call
var protectedResponse = await a2pClient.PdfSharp.SetPasswordAsync(
pdfResponse.Pdf,
"secretpassword"
);
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
// Generate PDF first
var pdfResponse = await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Confidential</h1>");
// Then add password protection in separate call
var protectedResponse = await a2pClient.PdfSharp.SetPasswordAsync(
pdfResponse.Pdf,
"secretpassword"
);
Imports Api2Pdf.DotNet
Dim a2pClient = New Api2PdfClient("YOUR_API_KEY")
' Generate PDF first
Dim pdfResponse = Await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Confidential</h1>")
' Then add password protection in separate call
Dim protectedResponse = Await a2pClient.PdfSharp.SetPasswordAsync(pdfResponse.Pdf, "secretpassword")
IronPDF 구현:
using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential</h1>");
// Set security in one step
pdf.SecuritySettings.OwnerPassword = "owner123";
pdf.SecuritySettings.UserPassword = "user123";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs("protected.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential</h1>");
// Set security in one step
pdf.SecuritySettings.OwnerPassword = "owner123";
pdf.SecuritySettings.UserPassword = "user123";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs("protected.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Confidential</h1>")
' Set security in one step
pdf.SecuritySettings.OwnerPassword = "owner123"
pdf.SecuritySettings.UserPassword = "user123"
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit
pdf.SaveAs("protected.pdf")
IronPDF는 SecuritySettings 속성을 통해 PDF 권한에 대한 세밀한 제어를 제공합니다.
머리말과 바닥글
Api2pdf 구현:
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
var options = new HeadlessChromeOptions
{
HeaderHtml = "<div style='font-size:10px'>Company Header</div>",
FooterHtml = "<div style='font-size:10px'>Page <span class='pageNumber'></span></div>"
};
var response = await a2pClient.HeadlessChrome.FromHtmlAsync(html, options);
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
var options = new HeadlessChromeOptions
{
HeaderHtml = "<div style='font-size:10px'>Company Header</div>",
FooterHtml = "<div style='font-size:10px'>Page <span class='pageNumber'></span></div>"
};
var response = await a2pClient.HeadlessChrome.FromHtmlAsync(html, options);
Imports Api2Pdf.DotNet
Dim a2pClient = New Api2PdfClient("YOUR_API_KEY")
Dim options = New HeadlessChromeOptions With {
.HeaderHtml = "<div style='font-size:10px'>Company Header</div>",
.FooterHtml = "<div style='font-size:10px'>Page <span class='pageNumber'></span></div>"
}
Dim response = Await a2pClient.HeadlessChrome.FromHtmlAsync(html, options)
IronPDF 구현:
using IronPdf;
var renderer = new ChromePdfRenderer();
// HTML headers and footers with full styling
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:10px; text-align:center;'>Company Header</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:10px; text-align:center;'>Page {page} of {total-pages}</div>",
DrawDividerLine = true
};
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("with-headers.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
// HTML headers and footers with full styling
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:10px; text-align:center;'>Company Header</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:10px; text-align:center;'>Page {page} of {total-pages}</div>",
DrawDividerLine = true
};
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("with-headers.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
' HTML headers and footers with full styling
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='font-size:10px; text-align:center;'>Company Header</div>",
.DrawDividerLine = True
}
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='font-size:10px; text-align:center;'>Page {page} of {total-pages}</div>",
.DrawDividerLine = True
}
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("with-headers.pdf")
IronPDF는 {page} 및 {total-pages}와 같은 자리 표시자 토큰을 지원하여 동적 페이지 번호 매기기를 제공합니다. 더 많은 옵션은 헤더 및 푸터 문서를 참조하세요.
ASP.NET Core 통합
Api2pdf의 비동기 HTTP 패턴은 IronPDF의 직접적인 PDF 생성과 상당히 다릅니다.
Api2pdf 패턴:
[ApiController]
public class PdfController : ControllerBase
{
private readonly Api2PdfClient _client;
public PdfController()
{
_client = new Api2PdfClient("YOUR_API_KEY");
}
[HttpGet("generate")]
public async Task<IActionResult> GeneratePdf()
{
var response = await _client.HeadlessChrome.FromHtmlAsync("<h1>Report</h1>");
if (!response.Success)
return BadRequest(response.Error);
// Redirect to download URL
return Redirect(response.Pdf);
}
}
[ApiController]
public class PdfController : ControllerBase
{
private readonly Api2PdfClient _client;
public PdfController()
{
_client = new Api2PdfClient("YOUR_API_KEY");
}
[HttpGet("generate")]
public async Task<IActionResult> GeneratePdf()
{
var response = await _client.HeadlessChrome.FromHtmlAsync("<h1>Report</h1>");
if (!response.Success)
return BadRequest(response.Error);
// Redirect to download URL
return Redirect(response.Pdf);
}
}
Imports Microsoft.AspNetCore.Mvc
<ApiController>
Public Class PdfController
Inherits ControllerBase
Private ReadOnly _client As Api2PdfClient
Public Sub New()
_client = New Api2PdfClient("YOUR_API_KEY")
End Sub
<HttpGet("generate")>
Public Async Function GeneratePdf() As Task(Of IActionResult)
Dim response = Await _client.HeadlessChrome.FromHtmlAsync("<h1>Report</h1>")
If Not response.Success Then
Return BadRequest(response.Error)
End If
' Redirect to download URL
Return Redirect(response.Pdf)
End Function
End Class
IronPDF 패턴:
[ApiController]
public class PdfController : ControllerBase
{
[HttpGet("generate")]
public IActionResult GeneratePdf()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>");
// Return PDF directly - no download step needed
return File(pdf.BinaryData, "application/pdf", "report.pdf");
}
[HttpGet("generate-async")]
public async Task<IActionResult> GeneratePdfAsync()
{
var renderer = new ChromePdfRenderer();
var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>");
return File(pdf.Stream, "application/pdf", "report.pdf");
}
}
[ApiController]
public class PdfController : ControllerBase
{
[HttpGet("generate")]
public IActionResult GeneratePdf()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>");
// Return PDF directly - no download step needed
return File(pdf.BinaryData, "application/pdf", "report.pdf");
}
[HttpGet("generate-async")]
public async Task<IActionResult> GeneratePdfAsync()
{
var renderer = new ChromePdfRenderer();
var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>");
return File(pdf.Stream, "application/pdf", "report.pdf");
}
}
Imports Microsoft.AspNetCore.Mvc
Imports System.Threading.Tasks
<ApiController>
Public Class PdfController
Inherits ControllerBase
<HttpGet("generate")>
Public Function GeneratePdf() As IActionResult
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>")
' Return PDF directly - no download step needed
Return File(pdf.BinaryData, "application/pdf", "report.pdf")
End Function
<HttpGet("generate-async")>
Public Async Function GeneratePdfAsync() As Task(Of IActionResult)
Dim renderer = New ChromePdfRenderer()
Dim pdf = Await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>")
Return File(pdf.Stream, "application/pdf", "report.pdf")
End Function
End Class
IronPDF는 BinaryData 또는 Stream을 통해 PDF를 직접 반환하여 다운로드로 리디렉션하는 패턴을 제거합니다.
의존성 주입 구성
// Program.cs or Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IPdfService, IronPdfService>();
}
// IPdfService.cs
public interface IPdfService
{
PdfDocument GenerateFromHtml(string html);
Task<PdfDocument> GenerateFromHtmlAsync(string html);
}
// IronPdfService.cs
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PrintHtmlBackgrounds = true;
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public PdfDocument GenerateFromHtml(string html) =>
_renderer.RenderHtmlAsPdf(html);
public Task<PdfDocument> GenerateFromHtmlAsync(string html) =>
_renderer.RenderHtmlAsPdfAsync(html);
}
// Program.cs or Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IPdfService, IronPdfService>();
}
// IPdfService.cs
public interface IPdfService
{
PdfDocument GenerateFromHtml(string html);
Task<PdfDocument> GenerateFromHtmlAsync(string html);
}
// IronPdfService.cs
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PrintHtmlBackgrounds = true;
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public PdfDocument GenerateFromHtml(string html) =>
_renderer.RenderHtmlAsPdf(html);
public Task<PdfDocument> GenerateFromHtmlAsync(string html) =>
_renderer.RenderHtmlAsPdfAsync(html);
}
' Program.vb or Startup.vb
Public Sub ConfigureServices(services As IServiceCollection)
services.AddScoped(Of IPdfService, IronPdfService)()
End Sub
' IPdfService.vb
Public Interface IPdfService
Function GenerateFromHtml(html As String) As PdfDocument
Function GenerateFromHtmlAsync(html As String) As Task(Of PdfDocument)
End Interface
' IronPdfService.vb
Public Class IronPdfService
Implements IPdfService
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer()
_renderer.RenderingOptions.PrintHtmlBackgrounds = True
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
End Sub
Public Function GenerateFromHtml(html As String) As PdfDocument Implements IPdfService.GenerateFromHtml
Return _renderer.RenderHtmlAsPdf(html)
End Function
Public Function GenerateFromHtmlAsync(html As String) As Task(Of PdfDocument) Implements IPdfService.GenerateFromHtmlAsync
Return _renderer.RenderHtmlAsPdfAsync(html)
End Function
End Class
오류 처리 마이그레이션
Api2pdf는 응답 객체 검사를 사용합니다. IronPDF는 표준 .NET 예외를 사용합니다.
Api2pdf 패턴:
var response = await a2pClient.HeadlessChrome.FromHtmlAsync(html);
if (!response.Success)
{
Console.WriteLine($"Error: {response.Error}");
return;
}
var response = await a2pClient.HeadlessChrome.FromHtmlAsync(html);
if (!response.Success)
{
Console.WriteLine($"Error: {response.Error}");
return;
}
Imports System
Dim response = Await a2pClient.HeadlessChrome.FromHtmlAsync(html)
If Not response.Success Then
Console.WriteLine($"Error: {response.Error}")
Return
End If
IronPDF 패턴:
try
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
catch (IronPdf.Exceptions.IronPdfLicenseException ex)
{
Console.WriteLine($"License error: {ex.Message}");
}
catch (IronPdf.Exceptions.IronPdfRenderingException ex)
{
Console.WriteLine($"Rendering error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
try
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
catch (IronPdf.Exceptions.IronPdfLicenseException ex)
{
Console.WriteLine($"License error: {ex.Message}");
}
catch (IronPdf.Exceptions.IronPdfRenderingException ex)
{
Console.WriteLine($"Rendering error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
Imports IronPdf.Exceptions
Try
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
Catch ex As IronPdfLicenseException
Console.WriteLine($"License error: {ex.Message}")
Catch ex As IronPdfRenderingException
Console.WriteLine($"Rendering error: {ex.Message}")
Catch ex As Exception
Console.WriteLine($"Error: {ex.Message}")
End Try
성능 비교
| 미터법 | Api2pdf | IronPDF |
|---|---|---|
| 간단한 HTML | 2-5초 (네트워크) | 100-500ms (로컬) |
| 복잡한 페이지 | 5-10초 | 500ms-2초 |
| 100개의 배치 | 몇 분 (속도 제한) | 몇 초 (병렬 처리) |
| 오프라인 | 사용 불가 | 완전히 작동합니다 |
| 콜드 스타트 | 없음 | ~2s (첫 번째 렌더) |
성능 최적화 팁
// 1. Reuse renderer instance
private static readonly ChromePdfRenderer SharedRenderer = new ChromePdfRenderer();
public PdfDocument GeneratePdf(string html)
{
return SharedRenderer.RenderHtmlAsPdf(html);
}
// 2. Parallel generation
var tasks = htmlDocs.Select(html =>
Task.Run(() => SharedRenderer.RenderHtmlAsPdf(html)));
var results = await Task.WhenAll(tasks);
// 3. Disable unnecessary features for speed
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = false; // If not needed
renderer.RenderingOptions.WaitFor.RenderDelay(0); // No delay
// 1. Reuse renderer instance
private static readonly ChromePdfRenderer SharedRenderer = new ChromePdfRenderer();
public PdfDocument GeneratePdf(string html)
{
return SharedRenderer.RenderHtmlAsPdf(html);
}
// 2. Parallel generation
var tasks = htmlDocs.Select(html =>
Task.Run(() => SharedRenderer.RenderHtmlAsPdf(html)));
var results = await Task.WhenAll(tasks);
// 3. Disable unnecessary features for speed
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = false; // If not needed
renderer.RenderingOptions.WaitFor.RenderDelay(0); // No delay
Imports System.Threading.Tasks
' 1. Reuse renderer instance
Private Shared ReadOnly SharedRenderer As New ChromePdfRenderer()
Public Function GeneratePdf(html As String) As PdfDocument
Return SharedRenderer.RenderHtmlAsPdf(html)
End Function
' 2. Parallel generation
Dim tasks = htmlDocs.Select(Function(html) Task.Run(Function() SharedRenderer.RenderHtmlAsPdf(html)))
Dim results = Await Task.WhenAll(tasks)
' 3. Disable unnecessary features for speed
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.EnableJavaScript = False ' If not needed
renderer.RenderingOptions.WaitFor.RenderDelay(0) ' No delay
일반적인 마이그레이션 문제 해결
문제: PDF가Api2pdf출력과 다르게 보임
Api2pdf의 헤드리스 Chrome 설정과 일치시키세요:
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
renderer.RenderingOptions.PrintHtmlBackgrounds = true;
renderer.RenderingOptions.ViewPortWidth = 1280;
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.RenderDelay(1000);
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
renderer.RenderingOptions.PrintHtmlBackgrounds = true;
renderer.RenderingOptions.ViewPortWidth = 1280;
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.RenderDelay(1000);
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print
renderer.RenderingOptions.PrintHtmlBackgrounds = True
renderer.RenderingOptions.ViewPortWidth = 1280
renderer.RenderingOptions.EnableJavaScript = True
renderer.RenderingOptions.WaitFor.RenderDelay(1000)
문제: 외부 리소스가 로드되지 않음
리소스 로드 타임아웃을 구성하십시오:
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(timeout: 10000);
renderer.RenderingOptions.WaitFor.NetworkIdle(timeout: 10000);
// Or use base URL for relative paths
var pdf = renderer.RenderHtmlAsPdf(html, baseUrl: "https://example.com/");
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(timeout: 10000);
renderer.RenderingOptions.WaitFor.NetworkIdle(timeout: 10000);
// Or use base URL for relative paths
var pdf = renderer.RenderHtmlAsPdf(html, baseUrl: "https://example.com/");
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.WaitFor.AllFontsLoaded(timeout:=10000)
renderer.RenderingOptions.WaitFor.NetworkIdle(timeout:=10000)
' Or use base URL for relative paths
Dim pdf = renderer.RenderHtmlAsPdf(html, baseUrl:="https://example.com/")
문제: 큰 PDF 파일 크기
생성 후 이미지를 압축합니다:
renderer.RenderingOptions.ImageQuality = 80;
// Or compress after generation
pdf.CompressImages(quality: 75);
pdf.SaveAs("compressed.pdf");
renderer.RenderingOptions.ImageQuality = 80;
// Or compress after generation
pdf.CompressImages(quality: 75);
pdf.SaveAs("compressed.pdf");
renderer.RenderingOptions.ImageQuality = 80
' Or compress after generation
pdf.CompressImages(quality:=75)
pdf.SaveAs("compressed.pdf")
마이그레이션 후 점검 목록
코드 마이그레이션을 완료한 후, 다음을 확인하십시오:
- PDF 출력 품질이 기대치와 일치하는지 확인하세요
- 모든 엣지 케이스를 테스트하세요 (큰 문서, 특수 문자)
- 성능 지표를 검증하세요 (눈에 띄는 개선이 있어야 함)
- 해당하는 경우 Docker 구성을 업데이트하세요 -Api2pdf포털 계정과 API 키 삭제하세요
- 모니터링을 업데이트하세요 (더 이상 API 지연 문제 추적이 필요 없음)
- 팀을 위한 새로운 패턴을 문서화하세요
- CI/CD 파이프라인을 업데이트하세요
PDF 인프라의 미래 대비
.NET 10의 접근과 C# 14에서 새로운 언어 기능 도입이 예고된 가운데, 네이티브 .NET PDF 라이브러리를 선택하면 변화하는 런타임 기능과 호환성을 보장합니다. IronPDF가 최신 .NET 버전을 지원하기 위해 헌신하고 있으므로, 2025년과 2026년까지 프로젝트가 확장되면서 전환 투자에 대한 이상의 혜택을 얻으며 추가적인 변환당 비용이 누적되지 않습니다.
추가 리소스
Api2pdf에서 IronPDF로의 마이그레이션은 클라우드 의존, 변환당 비용 모델에서 로컬, 일회 투자로 PDF 생성 방식을 변화시킵니다. 귀하의 중요 문서는 인프라에 보관되며, 대기시간이 몇 초에서 밀리초로 감소되며, 이 중요한 애플리케이션 기능에 대해 공급업체 의존성을 제거합니다.

