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

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

wkhtmltopdf는 Qt 4.8 + QtWebKit을 사용하여 HTML 문서를 PDF로 변환하는 데 널리 사용된 도구입니다. 명령줄 기능과 무료 라이선스로 인해 개발자들 사이에서 인기가 높지만, 이 프로젝트는 이제 더 이상 무시할 수 없는 심각한 보안 위험을 제기합니다. GitHub 저장소는 2023년 1월 2일에 보관되었습니다; 마지막 업스트림 릴리스는 2020년 6월 11일의 0.12.6입니다; 그리고 CVE-2022-35583 (CVSS 9.8, SSRF)는 패치되지 않은 채로 남아 있습니다.

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

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

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

문제 상세 정보 상태
CVE-2022-35583 (SSRF, CWE-918) 중요 (CVSS 9.8) 패치되지 않음 — 유지 보수자에 의해 논쟁 중임
GitHub 저장소 보관됨 읽기 전용 2023년 1월 2일
마지막 업스트림 릴리스 0.12.6 2020년 6월 11일
기본 엔진 Qt 4.8 + QtWebKit (Qt 4.8 EOL 2015) 구식
CSS Grid 지원 None 깨짐
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들을 가져오며, 방화벽과 보안 제어를 우회합니다.

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

모든 .NET 래퍼는 동일한 wkhtmltopdf 네이티브 바이너리를 번들로 묶거나 셸로 출력하므로, 래퍼 자체의 활성화 여부와 관계없이 CVE 노출을 모두 상속받습니다:

래퍼 라이브러리 최신 NuGet 보안 위험
DinkToPdf 1.0.8 (2017년 4월) — 지원 종료 CVE-2022-35583 상속
Rotativa.AspNetCore (webgio fork) 1.4.0 (2023년 11월) — 래퍼 업데이트됨, 바이너리 동결됨 CVE-2022-35583 상속
TuesPechkin 2.1.1 (2015년 1월) — 지원 종료 CVE-2022-35583 상속
Haukcode.WkHtmlToPdfDotNet (formerly WkHtmlToPdf-DotNet) 1.5.95 (2024년 10월) — 래퍼 업데이트됨, 바이너리 동결됨 CVE-2022-35583 상속
NReco.PdfGenerator 래퍼 업데이트됨, wkhtmltopdf 번들로 묶임 CVE-2022-35583 상속

이 라이브러리 중 하나를 사용하면 모든 HTML 입력을 정규화하지 않는 한 CVE-2022-35583에 노출됩니다.

IronPDF vs wkhtmltopdf: 기능 비교

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

기능 wkhtmltopdf IronPDF
라이선스 LGPLv3 (무료) 상업적
렌더링 엔진 Qt 4.8 + QtWebKit (Qt 4.8 EOL 2015) 현재 Chromium 엔진
보안 취약점 CVE-2022-35583 (CVSS 9.8) 패치되지 않음, 논쟁 중 치명적인 CVE 보고 없음
활성 유지보수 GitHub 리포지토리 2023년 1월 2일 아카이브됨; 마지막 릴리스 2020년 6월 정기적인 릴리스와 함께 적극적으로 관리됨
최신 웹 표준 지원 제한적 (깨진 flexbox, CSS Grid 없음) 지원됨
통합 및 지원 커뮤니티 포럼으로 제한됨 광범위한 문서 및 전용 지원
CSS Grid ❌ 지원되지 않음 ✅ 지원됨
Flexbox ⚠ 고장남 ✅ 지원됨
ES6+ JavaScript ❌ 지원되지 않음 ✅ 지원됨
Async/Await ❌ 지원되지 않음 ✅ 지원됨
PDF 조작 ❌ 지원되지 않음 ✅ 지원됨
디지털 서명 ❌ 지원되지 않음 ✅ 지원됨
PDF/A 준수 ❌ 지원되지 않음 ✅ 지원됨

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

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

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

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

# Remove wkhtmltopdf wrapper (whichever you're using)
dotnet remove package Haukcode.WkHtmlToPdfDotNet
dotnet remove package DinkToPdf
dotnet remove package TuesPechkin
dotnet remove package Rotativa
dotnet remove package Rotativa.AspNetCore
dotnet remove package NReco.PdfGenerator

# Remove wkhtmltopdf binary from your deployment
# Delete wkhtmltopdf.exe, wkhtmltox.dll, etc.
# Remove wkhtmltopdf wrapper (whichever you're using)
dotnet remove package Haukcode.WkHtmlToPdfDotNet
dotnet remove package DinkToPdf
dotnet remove package TuesPechkin
dotnet remove package Rotativa
dotnet remove package Rotativa.AspNetCore
dotnet remove package NReco.PdfGenerator

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

2단계:IronPDF설치

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

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

wkhtmltopdf 네임스페이스를IronPDF네임스페이스로 대체하십시오:

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

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

// After (IronPDF)
using 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 Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.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 Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.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);
    }
}
Imports Haukcode.WkHtmlToPdfDotNet
Imports Haukcode.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 List(Of ObjectSettings) From {
                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 Module
$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과 함께 생성하고, HtmlToPdfDocumentGlobalSettingsObjects와 함께 구성하며, ColorMode, Orientation, PaperSize 같은 속성을 설정하고, 원시 바이트를 얻기 위해 converter.Convert()을 호출한 다음 File.WriteAllBytes()로 파일에 수동으로 작성해야 합니다.

IronPDF는 이 절차를 완전히 제거합니다—ChromePdfRenderer를 생성하고, RenderHtmlAsPdf()을 호출하며, 내장된 SaveAs() 메서드를 사용합니다.

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

URL을 PDF로 변환

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

wkhtmltopdf 접근 방식:

// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.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 Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.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);
    }
}
Imports Haukcode.WkHtmlToPdfDotNet
Imports Haukcode.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 List(Of ObjectSettings) From {
                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을 지정하기 위해 Page 속성을 ObjectSettings 내에서 사용하며 동일한 문서 구성 패턴이 필요합니다. IronPDF는 의도를 명확히 표현하는 전용 RenderUrlAsPdf() 메서드를 제공합니다.

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

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

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

wkhtmltopdf 접근 방식:

// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.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 Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.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);
    }
}
Imports Haukcode.WkHtmlToPdfDotNet
Imports Haukcode.WkHtmlToPdfDotNet.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter = New SynchronizedConverter(New PdfTools())
        Dim doc = 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 Module
$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는 RenderingOptions와 같은 명확한 이름을 가진 직접적인 속성과 PaperOrientation, MarginTop, PaperSize 같은 속성을 제공합니다.

wkhtmltopdf API에서 IronPDF로의 매핑 참조

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

CLI에서 IronPDF로의 매핑

wkhtmltopdf CLI 옵션 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} 플레이스홀더
--footer-center "[toPage]" {total-pages} 플레이스홀더
--enable-javascript 기본적으로 활성화됨
--javascript-delay 500 RenderingOptions.WaitFor.RenderDelay = 500
--dpi 300 RenderingOptions.Dpi = 300
--grayscale RenderingOptions.GrayScale = true

C# Wrapper 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 all wkhtmltopdf references
grep -r "Haukcode.WkHtmlToPdfDotNet\|WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa\|NReco.PdfGenerator" --include="*.cs" .
grep -r "wkhtmltopdf" --include="*.yml" --include="*.yaml" --include="Dockerfile" .
# Find all wkhtmltopdf references
grep -r "Haukcode.WkHtmlToPdfDotNet\|WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa\|NReco.PdfGenerator" --include="*.cs" .
grep -r "wkhtmltopdf" --include="*.yml" --include="*.yaml" --include="Dockerfile" .
SHELL

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

코드 업데이트 작업

  1. 모든 wkhtmltopdf 래퍼 NuGet 패키지를 제거하십시오
  2. wkhtmltopdf 바이너리(wkhtmltopdf.exe, wkhtmltox.dll)를 제거하십시오 3.IronPDF NuGet Install-Package
  3. 네임스페이스를 Haukcode.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 remaining wkhtmltopdf artifacts
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 remaining wkhtmltopdf artifacts
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가 제공할 수 없었던 기본 기능입니다.

활발한 개발: IronPDF의 정기적인 업데이트는 최신 .NET 릴리스에 맞춰지므로 최신 .NET 및 C# 언어 버전을 지원합니다.

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

참고해 주세요DinkToPdf, NReco, Rotativa, TuesPechkin, wkhtmltopdf는 각 소유자의 등록상표입니다. 이 사이트는 DinkToPdf, NReco, Rotativa, TuesPechkin, wkhtmltopdf와 관련이 없으며, 이들에 의해 승인되거나 지원받고 있지 않습니다. 모든 제품명, 로고 및 브랜드는 해당 소유자의 자산입니다. 비교는 정보 제공 목적으로만 사용되며, 작성 시점에 공개적으로 이용 가능한 정보를 반영합니다.

Curtis Chau
기술 문서 작성자

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

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

아이언 서포트 팀

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