푸터 콘텐츠로 바로가기
마이그레이션 가이드

C#에서 wkhtmltopdf에서 IronPDF로 마이그레이션하는 방법

wkhtmltopdf는 Qt WebKit을 사용하여 HTML 문서를 PDF로 변환하는 데 널리 사용된 도구였습니다. 명령줄 기능과 무료 라이선스로 인해 개발자들 사이에서 인기가 높지만, 이 프로젝트는 이제 더 이상 무시할 수 없는 심각한 보안 위험을 제기합니다. 이 라이브러리는 2016-2017년에 공식적으로 포기되었으며, 중요한 심각도의 취약점(CVE-2022-35583)이 영구적으로 패치되지 않습니다.

이 가이드는 wkhtmltopdf에서 IronPDF로의 완전한 마이그레이션 경로를 제공하며, 단계별 지침, 코드 비교 및 응용 프로그램에서 이 보안 위험을 제거해야 하는 전문 .NET 개발자를 위한 실용적인 예제를 포함합니다.

중대한 보안 경고: CVE-2022-35583

wkhtmltopdf는 절대 고쳐지지 않을 심각한 보안 취약점을 포함하고 있습니다:

문제 심각도 상태
CVE-2022-35583 심각한 (9.8/10) 패치되지 않음
SSRF 취약성 인프라 점거 위험 패치되지 않음
마지막 업데이트 2016-2017 포기됨
WebKit 버전 2015년 (Qt WebKit) 구식
CSS Grid 지원 없음 깨짐
Flexbox 지원 부분적 깨짐
ES6+ JavaScript 없음 깨짐

SSRF 공격이 작동하는 방식

서버 사이드 요청 위조 취약점을 통해 공격자는 내부 서비스에 접근하고 자격 증명을 훔치며 내부 네트워크를 스캔하여 민감한 데이터를 조작된 HTML을 통해 탈취할 수 있습니다:


<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-database:5432/admin"/>

<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-database:5432/admin"/>
HTML

wkhtmltopdf가 이 HTML을 렌더링할 때, 서버의 네트워크 컨텍스트에서 이 URL들을 가져오며, 방화벽과 보안 제어를 우회합니다.

영향을 받는 래퍼 라이브러리

wkhtmltopdf에 대한 모든 .NET 래퍼는 이러한 취약점을 상속합니다:

래퍼 라이브러리 상태 보안 위험
DinkToPdf 버려짐 ⚠️ 심각
Rotativa 버려짐 ⚠️ 심각
TuesPechkin 버려짐 ⚠️ 심각
WkHtmlToPdf-DotNet 버려짐 ⚠️ 심각
NReco.PdfGenerator wkhtmltopdf사용 ⚠️ 심각

이러한 라이브러리를 사용하는 경우 CVE-2022-35583에 취약합니다.

IronPDFvs wkhtmltopdf: 기능 비교

구조적 차이를 이해하면 기술 결정을 내리는데 이주 투자를 평가하는데 도움이 됩니다:

기능 wkhtmltopdf IronPDF
라이선스 LGPLv3 (무료) 상업적
렌더링 엔진 Qt WebKit (2015) 현재 Chromium 엔진
보안 취약점 CVE-2022-35583, 주요 패치되지 않은 문제 알려진 CVE 없음
활성 유지보수 2017년 이후로 중요한 업데이트 없음, 포기됨 정기적인 릴리스와 함께 적극적으로 관리됨
최신 웹 표준 지원 제한적 (깨진 flexbox, CSS Grid 없음) 지원됨
통합 및 지원 커뮤니티 포럼으로 제한됨 광범위한 문서 및 전용 지원
CSS Grid ❌ 지원되지 않음 ✅ 지원됨
Flexbox ⚠️ 깨짐 ✅ 지원됨
ES6+ JavaScript ❌ 지원되지 않음 ✅ 지원됨
Async/Await ❌ 지원되지 않음 ✅ 지원됨
PDF 조작 ❌ 지원되지 않음 ✅ 지원됨
디지털 서명 ❌ 지원되지 않음 ✅ 지원됨
PDF/A 준수 ❌ 지원되지 않음 ✅ 지원됨

빠른 시작: wkhtmltopdf에서 IronPDF로의 마이그레이션

이러한 기본 단계를 통해 즉시 이주를 시작할 수 있습니다.

1단계:wkhtmltopdf패키지와 바이너리를 제거하세요

모든wkhtmltopdf래퍼 패키지를 제거하십시오:

# Removewkhtmltopdfwrapper (whichever you're using)
dotnet remove package WkHtmlToPdf-DotNet
dotnet remove package DinkToPdf
dotnet remove package TuesPechkin
dotnet remove package Rotativa
dotnet remove package Rotativa.AspNetCore
dotnet remove package NReco.PdfGenerator

# Removewkhtmltopdfbinary from your deployment
# Delete wkhtmltopdf.exe, wkhtmltox.dll, etc.
# Removewkhtmltopdfwrapper (whichever you're using)
dotnet remove package WkHtmlToPdf-DotNet
dotnet remove package DinkToPdf
dotnet remove package TuesPechkin
dotnet remove package Rotativa
dotnet remove package Rotativa.AspNetCore
dotnet remove package NReco.PdfGenerator

# Removewkhtmltopdfbinary from your deployment
# Delete wkhtmltopdf.exe, wkhtmltox.dll, etc.
SHELL

2단계:IronPDF설치

# AddIronPDF(secure, modern alternative)
dotnet add package IronPdf
# AddIronPDF(secure, modern alternative)
dotnet add package IronPdf
SHELL

3단계: 네임스페이스 업데이트

wkhtmltopdf 네임스페이스를 IronPdf 네임스페이스로 교체하십시오:

// Before (wkhtmltopdf)
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;

// After (IronPDF)
using IronPdf;
// Before (wkhtmltopdf)
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;

// After (IronPDF)
using IronPdf;
' Before (wkhtmltopdf)
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts

' After (IronPDF)
Imports IronPdf
$vbLabelText   $csharpLabel

4단계: 라이센스 초기화

애플리케이션 시작 시 라이선스 초기화를 추가합니다:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

코드 마이그레이션 예제

HTML을 PDF로 변환

.NET PDF 접근방식 간의 복잡도 차이를 가장 근본적인 작업으로 드러냅니다.

wkhtmltopdf 접근 방식:

// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4
            },
            Objects = {
                new ObjectSettings()
                {
                    HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4
            },
            Objects = {
                new ObjectSettings()
                {
                    HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
' NuGet: Install-Package WkHtmlToPdf-DotNet
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts
Imports System.IO

Class Program
    Shared Sub Main()
        Dim converter = New SynchronizedConverter(New PdfTools())
        Dim doc = New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = {
                New ObjectSettings() With {
                    .HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("output.pdf", pdf)
    End Sub
End Class
$vbLabelText   $csharpLabel

IronPDF 접근법:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
        pdf.SaveAs("output.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>")
        pdf.SaveAs("output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

wkhtmltopdf는 SynchronizedConverterPdfTools로 생성하고, GlobalSettingsObjectsHtmlToPdfDocument를 구성하며, ColorMode, OrientationPaperSize와 같은 속성을 설정하고, converter.Convert()를 호출하여 원시 바이트를 얻고, File.WriteAllBytes()로 파일에 수동으로 기록하는 것을 요구합니다.

IronPDF는 이러한 절차를 전혀 필요로 하지 않습니다—ChromePdfRenderer를 만들고, RenderHtmlAsPdf()를 호출하며, 내장된 SaveAs() 메소드를 사용하세요.

고급 HTML에서 PDF로의 시나리오는 HTML to PDF 변환 가이드를 참조하십시오.

URL을 PDF로 변환

URL에서 PDF로 변환은 유사한 복잡성 패턴을 보여줍니다.

wkhtmltopdf 접근 방식:

// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "https://www.example.com"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "https://www.example.com"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
' NuGet: Install-Package WkHtmlToPdf-DotNet
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter As New SynchronizedConverter(New PdfTools())
        Dim doc As New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = {
                New ObjectSettings() With {
                    .Page = "https://www.example.com"
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("webpage.pdf", pdf)
    End Sub
End Module
$vbLabelText   $csharpLabel

IronPDF 접근법:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
        pdf.SaveAs("webpage.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

wkhtmltopdf는 URL을 지정하기 위해 ObjectSettings에서 Page 속성을 사용하며, 동일한 문서 구성 패턴을 요구합니다. IronPDF는 의도를 명확히 표현하는 전용 RenderUrlAsPdf() 메소드를 제공합니다.

URL to PDF 문서에서 인증 및 사용자 정의 헤더 옵션을 탐색하십시오.

사용자 정의 설정: 페이지 구성과 HTML 파일

방향, 여백, 용지 크기 설정에는 다른 접근 방식이 필요합니다.

wkhtmltopdf 접근 방식:

// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Landscape,
                PaperSize = PaperKind.A4,
                Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "input.html",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("custom-output.pdf", pdf);
    }
}
// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Landscape,
                PaperSize = PaperKind.A4,
                Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "input.html",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("custom-output.pdf", pdf);
    }
}
' NuGet: Install-Package WkHtmlToPdf-DotNet
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts
Imports System.IO

Class Program
    Shared Sub Main()
        Dim converter As New SynchronizedConverter(New PdfTools())
        Dim doc As New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Landscape,
                .PaperSize = PaperKind.A4,
                .Margins = New MarginSettings() With {.Top = 10, .Bottom = 10, .Left = 10, .Right = 10}
            },
            .Objects = {
                New ObjectSettings() With {
                    .Page = "input.html",
                    .WebSettings = New WebSettings() With {.DefaultEncoding = "utf-8"}
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("custom-output.pdf", pdf)
    End Sub
End Class
$vbLabelText   $csharpLabel

IronPDF 접근법:

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;

        var pdf = renderer.RenderHtmlFileAsPdf("input.html");
        pdf.SaveAs("custom-output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;

        var pdf = renderer.RenderHtmlFileAsPdf("input.html");
        pdf.SaveAs("custom-output.pdf");
    }
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System

Class Program
    Shared Sub Main()
        Dim renderer As New ChromePdfRenderer()
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
        renderer.RenderingOptions.MarginTop = 10
        renderer.RenderingOptions.MarginBottom = 10
        renderer.RenderingOptions.MarginLeft = 10
        renderer.RenderingOptions.MarginRight = 10
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4

        Dim pdf = renderer.RenderHtmlFileAsPdf("input.html")
        pdf.SaveAs("custom-output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

wkhtmltopdf는 GlobalSettingsObjects 내부에 설정을 중첩시키고, MarginSettings를 별도의 객체로 다룹니다. IronPDF는 PaperOrientation, MarginTopPaperSize와 같은 명확한 이름의 직접적인 RenderingOptions 속성을 제공합니다.

wkhtmltopdfAPI에서 IronPDF로의 매핑 참조

이 매핑은 직접적인 API 대응을 보여주어 마이그레이션을 가속화합니다:

CLI에서 IronPDF로의 매핑

wkhtmltopdfCLI 옵션 IronPDF 동등
wkhtmltopdf input.html output.pdf renderer.RenderHtmlFileAsPdf()
wkhtmltopdf URL output.pdf renderer.RenderUrlAsPdf()
--page-size A4 RenderingOptions.PaperSize = PdfPaperSize.A4
--page-size Letter RenderingOptions.PaperSize = PdfPaperSize.Letter
--orientation Landscape RenderingOptions.PaperOrientation = Landscape
--margin-top 10mm RenderingOptions.MarginTop = 10
--margin-bottom 10mm RenderingOptions.MarginBottom = 10
--margin-left 10mm RenderingOptions.MarginLeft = 10
--margin-right 10mm RenderingOptions.MarginRight = 10
--header-html header.html RenderingOptions.HtmlHeader
--footer-center "[page]" {page} placeholder
--footer-center "[toPage]" {total-pages} placeholder
--enable-javascript 기본적으로 활성화됨
--javascript-delay 500 RenderingOptions.WaitFor.RenderDelay = 500
--dpi 300 RenderingOptions.Dpi = 300
--grayscale RenderingOptions.GrayScale = true

C# 래퍼 API 매핑

wkhtmltopdf 래퍼 IronPDF
SynchronizedConverter ChromePdfRenderer
HtmlToPdfDocument RenderingOptions
GlobalSettings.Out pdf.SaveAs()
GlobalSettings.PaperSize RenderingOptions.PaperSize
GlobalSettings.Orientation RenderingOptions.PaperOrientation
GlobalSettings.Margins RenderingOptions.Margin*
ObjectSettings.Page RenderHtmlFileAsPdf()
ObjectSettings.HtmlContent RenderHtmlAsPdf()
converter.Convert(doc) renderer.RenderHtmlAsPdf()

플레이스홀더 구문 마이그레이션

wkhtmltopdf 플레이스홀더 IronPDF 플레이스홀더
[page] {page}
[toPage] {total-pages}
[date] {date}
[time] {time}
[title] {html-title}
[url] {url}

일반적인 마이그레이션 문제와 해결책

문제 1: 헤더/푸터 자리 표시자 구문

wkhtmltopdf: [page][toPage]와 같은 대괄호 구문을 사용합니다.

해결책: IronPDF의 중괄호 플레이스홀더로 업데이트 하세요:

// Before (wkhtmltopdf)
FooterSettings = { Left = "Page [page] of [toPage]" }

// After (IronPDF)
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div style='text-align:left;'>Page {page} of {total-pages}</div>",
    MaxHeight = 25
};
// Before (wkhtmltopdf)
FooterSettings = { Left = "Page [page] of [toPage]" }

// After (IronPDF)
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div style='text-align:left;'>Page {page} of {total-pages}</div>",
    MaxHeight = 25
};
' Before (wkhtmltopdf)
FooterSettings = New With {.Left = "Page [page] of [toPage]"}

' After (IronPDF)
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
    .HtmlFragment = "<div style='text-align:left;'>Page {page} of {total-pages}</div>",
    .MaxHeight = 25
}
$vbLabelText   $csharpLabel

문제 2: JavaScript 지연 구성

wkhtmltopdf: 제한된 신뢰성을 가진 JavaScriptDelay 속성을 사용합니다.

해결책: IronPDF는 여러 옵션을 제공합니다:

renderer.RenderingOptions.EnableJavaScript = true;

// Option 1: Fixed delay
renderer.RenderingOptions.WaitFor.RenderDelay(500);

// Option 2: Wait for specific element (more reliable)
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded");

// Option 3: Wait for JavaScript condition
renderer.RenderingOptions.WaitFor.JavaScript("window.renderComplete === true");
renderer.RenderingOptions.EnableJavaScript = true;

// Option 1: Fixed delay
renderer.RenderingOptions.WaitFor.RenderDelay(500);

// Option 2: Wait for specific element (more reliable)
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded");

// Option 3: Wait for JavaScript condition
renderer.RenderingOptions.WaitFor.JavaScript("window.renderComplete === true");
renderer.RenderingOptions.EnableJavaScript = True

' Option 1: Fixed delay
renderer.RenderingOptions.WaitFor.RenderDelay(500)

' Option 2: Wait for specific element (more reliable)
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded")

' Option 3: Wait for JavaScript condition
renderer.RenderingOptions.WaitFor.JavaScript("window.renderComplete === true")
$vbLabelText   $csharpLabel

문제 3: 최신 CSS가 렌더링되지 않음

증상: wkhtmltopdf에서 CSS Grid 및 Flexbox 레이아웃이 잘못 렌더링됩니다.

해결책: IronPDF의 Chromium 엔진은 최신 CSS를 올바르게 처리합니다:

// This CSS now works with IronPDF
var html = @"
<style>
    .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
    .flex { display: flex; justify-content: space-between; align-items: center; }
</style>
<div class='grid'>
    <div>Column 1</div>
    <div>Column 2</div>
    <div>Column 3</div>
</div>";

var pdf = renderer.RenderHtmlAsPdf(html);
// This CSS now works with IronPDF
var html = @"
<style>
    .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
    .flex { display: flex; justify-content: space-between; align-items: center; }
</style>
<div class='grid'>
    <div>Column 1</div>
    <div>Column 2</div>
    <div>Column 3</div>
</div>";

var pdf = renderer.RenderHtmlAsPdf(html);
Dim html As String = "
<style>
    .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
    .flex { display: flex; justify-content: space-between; align-items: center; }
</style>
<div class='grid'>
    <div>Column 1</div>
    <div>Column 2</div>
    <div>Column 3</div>
</div>"

Dim pdf = renderer.RenderHtmlAsPdf(html)
$vbLabelText   $csharpLabel

문제 4: 동기식 대 비동기식 렌더링

wkhtmltopdf: 래퍼는 동기식이며 스레드를 차단합니다.

해결책: IronPDF는 비동기 렌더링을 지원합니다:

public async Task<byte[]> GeneratePdfAsync(string html)
{
    var renderer = new ChromePdfRenderer();
    var pdf = await renderer.RenderHtmlAsPdfAsync(html);
    return pdf.BinaryData;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
    var renderer = new ChromePdfRenderer();
    var pdf = await renderer.RenderHtmlAsPdfAsync(html);
    return pdf.BinaryData;
}
Imports System.Threading.Tasks

Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
    Dim renderer As New ChromePdfRenderer()
    Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
    Return pdf.BinaryData
End Function
$vbLabelText   $csharpLabel

wkhtmltopdf마이그레이션 검사 목록

이동 전 작업

코드베이스를 감사하여 모든wkhtmltopdf사용을 식별하십시오:

# Find allwkhtmltopdfreferences
grep -r "WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa" --include="*.cs" .
grep -r "wkhtmltopdf" --include="*.yml" --include="*.yaml" --include="Dockerfile" .
# Find allwkhtmltopdfreferences
grep -r "WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa" --include="*.cs" .
grep -r "wkhtmltopdf" --include="*.yml" --include="*.yaml" --include="Dockerfile" .
SHELL

제거를 위해wkhtmltopdf바이너리 파일의 위치를 찾아 기록하십시오. 현재 설정(용지 크기, 여백, 헤더/푸터)을 문서화하십시오.

코드 업데이트 작업

  1. 모든wkhtmltopdf래퍼 NuGet 패키지를 제거하십시오 2.wkhtmltopdf바이너리(wkhtmltopdf.exe, wkhtmltox.dll)를 제거하십시오
  2. IronPdf NuGet Install-Package
  3. 네임스페이스 가져오기를 WkHtmlToPdfDotNet에서 IronPdf로 업데이트합니다
  4. SynchronizedConverterChromePdfRenderer로 교체합니다
  5. HtmlToPdfDocument 패턴을 직접 렌더링 메소드로 변환합니다
  6. GlobalSettings 구성을 RenderingOptions로 업데이트합니다
  7. 마진 구성을 MarginSettings에서 개별 속성으로 변환합니다
  8. 자리 표시자 구문을 업데이트합니다 ( [page]{page}, [toPage]{total-pages} )
  9. 시작 시IronPDF라이선스 초기화를 추가하십시오

마이그레이션 후 테스트

마이그레이션 후 다음 측면을 검증:

  • PDF 출력의 시각적 비교 (최신 CSS 지원으로 개선될 것입니다)
  • 최신 CSS 렌더링을 확인하십시오 (CSS Grid 및 Flexbox가 이제 작동합니다)
  • JavaScript 중심의 페이지를 테스트하십시오 -wkhtmltopdf바이너리가 남아 있지 않은지 확인하기 위한 보안 스캔
  • 성능 비교를 위한 부하 테스트

보안 검증

# Scan for any remainingwkhtmltopdfartifacts
find /var/www/ -name "*wkhtmlto*" 2>/dev/null
find /usr/local/bin/ -name "*wkhtmlto*" 2>/dev/null
docker images | grep wkhtmltopdf

# Check if any process is still using it
ps aux | grep wkhtmltopdf
# Scan for any remainingwkhtmltopdfartifacts
find /var/www/ -name "*wkhtmlto*" 2>/dev/null
find /usr/local/bin/ -name "*wkhtmlto*" 2>/dev/null
docker images | grep wkhtmltopdf

# Check if any process is still using it
ps aux | grep wkhtmltopdf
SHELL

IronPDF로 마이그레이션할 때의 주요 이점

wkhtmltopdf에서 IronPDF로 이동하면 여러 가지 중요한 이점을 제공합니다:

보안: CVE-2022-35583과 모든wkhtmltopdf취약점이 제거되었습니다. IronPDF는 알려진 CVE가 없으며 정기적인 보안 업데이트를 받습니다.

최신 렌더링 엔진: IronPDF는 현재 Chromium 엔진을 사용하여 전체 CSS3, CSS Grid, Flexbox, 및 ES6+ JavaScript 지원을 보장합니다. 모던 프레임워크는 정확하게 렌더링합니다.

단순화된 API: 문서 생성 패턴을 대체하는 직접적인 렌더링 메서드. 내장된 SaveAs() 메소드는 수동 바이트 처리를 제거합니다.

확장된 기능: PDF 조작, 디지털 서명, PDF/A 준수, 워터마크 및 병합/분할 작업은 wkhtmltopdf가 제공할 수 없었던 기본 기능입니다.

활발한 개발: .NET 10 및 C# 14의 채택이 2026년까지 증가함에 따라 IronPDF의 정기 업데이트는 현재 및 미래의 .NET 버전과의 호환성을 보장합니다.

비동기 지원: 네이티브 async/await 지원으로 높은 부하의 웹 애플리케이션에서 스레드 차단을 방지합니다.

커티스 차우
기술 문서 작성자

커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다.

커티스는 개발 분야 외에도 사물 인터넷(IoT)에 깊은 관심을 가지고 있으며, 하드웨어와 소프트웨어를 통합하는 혁신적인 방법을 연구합니다. 여가 시간에는 게임을 즐기거나 디스코드 봇을 만들면서 기술에 대한 애정과 창의성을 결합합니다.

아이언 서포트 팀

저희는 주 5일, 24시간 온라인으로 운영합니다.
채팅
이메일
전화해