푸터 콘텐츠로 바로가기
IRONPDF 사용하기

관리자 대시보드용 C#에서 PDF로 원클릭 내보내기

대량 HTML 콘텐츠 보존 문제

IronPDF 홈페이지 조직이 레거시 CMS, 인트라넷 또는 공개 포털을 중단하면 그 콘텐츠가 중요하지 않게 되지 않습니다. 환자 건강 기사 데이터베이스를 퇴역시키는 병원은 여전히 그 기사를 보존해야 하며, 웹사이트를 재설계하는 정부 기관은 특정 지점에 존재했던 공지를 유지해야 하며, 사건 조사 플랫폼을 종료하는 로펌은 법적 보존에서 유지되는 형식으로 모든 페이지를 변환해야 합니다.

규모는 모든 수동 접근 방식을 실패시킵니다. 브라우저 기반 PDF로 인쇄는 한 문서에만 작동합니다. 1만 건에는 솔루션이 아닙니다. 헤드리스 브라우저 스크립트는 잘못된 HTML, 누락된 자산 또는 인증 벽에 부딪힐 때까지 작동하며, 레거시 콘텐츠는 깨끗하지 않은 경우가 많습니다.

기존의 배치 변환 도구들은 구식 마크업에서도 유사한 문제를 겪고 있습니다: 2005년의 인라인 스타일, 비표준 테이블 레이아웃, 더 이상 해상되지 않는 경로로의 이미지 참조. 그들은 조용히 실패하거나 레이아웃이 깨진 PDF를 생성하거나 페이지별로 수동 개입을 필요로 합니다. 그 동안 IT 팀은 몇 달 전에 끝났어야 할 마이그레이션을 지원하기 위해 레거시 인프라를 무기한 가동할 수 없습니다.

출력물도 일관성이 있어야 합니다. 건강 기사를 보관하는 병원, 규제 준수를 위해 공시 페이지를 보존하는 금융 기관, 보관 아카이브를 구축하는 로펌, 이들 모두는 결과로 생성된 PDF가 동일한 시스템에서 나온 것처럼 보여야 하며, 단발성 브라우저 내보내기 모음처럼 보이지 않아야 합니다. 이 튜토리얼에서는 이 라이브러리가 프로젝트 워크플로를 어떻게 높일 수 있는지를 보여주는 IronPDF 예제를 안내해 드리겠습니다.

솔루션: IronPDF를 사용한 자동 HTML to PDF 배치 변환

Iron Software의 자사 IronPDF는 .NET 애플리케이션이 HTML 파일, HTML 문자열, 또는 라이브 URL을 자동으로 한 번의 실행으로 표준화된 PDF로 일괄 변환할 수 있게 합니다. 마이그레이션 스크립트는 원본에서 읽습니다: 오래된 서버가 오프라인 되기 전에 캡처할 HTML 파일의 디렉터리, HTML 블롭의 데이터베이스, 또는 URL 목록을 확보하여 각 페이지를 ChromePdfRenderer에 공급하고 출력을 아카이브 목적지로 작성합니다.

Chrome 기반 렌더링 엔진은 브라우저가 그랬듯 불규칙한 마크업, 인라인 스타일, 내장 자산을 처리하여 원본 HTML이 어떻게 작성되었든 시각적으로 신뢰할 수 있는 스냅샷을 생성합니다. 유지할 브라우저 자동화 해킹이 없으며, 비싼 5만 페이지 아카이브를 비경제적으로 만드는 문서 당 API 비용도 없습니다. 변환은 .NET 콘솔 애플리케이션 또는 백그라운드 서비스 내에서 수행되며, 하나의 NuGet 패키지로 외부 프로세스가 없습니다.

실제 작동 방식: C# PDF 문서 생성

1. 마이그레이션 스크립트가 원본 콘텐츠를 열거합니다

스크립트는 일반적으로 마이그레이션을 위해 구축된 콘솔 애플리케이션입니다 - 일회용 실행이거나 증분 콘텐츠 세트를 위한 반복 가능한 작업입니다. 디스크의 .html 파일 디렉토리, HTML 블롭과 메타데이터가 있는 데이터베이스 테이블(원본 URL, 작성 날짜, 콘텐츠 ID), 또는 오래된 서버가 오프라인 되기 전에 캡처할 라이브 웹 페이지의 평면 목록으로 원본을 열거하는 것으로 시작합니다.

데이터베이스 소스의 경우, 쿼리는 아카이브 매니페스트를 채울 HTML 콘텐츠와 메타데이터 모두를 반환합니다. URL 목록의 경우, 처리 순서는 우선순위별로 정렬할 수 있으며, 높은 트래픽 페이지 또는 법적으로 중요한 콘텐츠가 먼저 캡처됩니다.

2. 스타일시트 주입이 출력을 표준화합니다

레거시 HTML은 본질적으로 불규칙합니다. 같은 CMS의 다른 시대의 페이지는 서로 다른 기본 글꼴 크기, 여백 규칙 및 레이아웃 가정을 가질 수 있습니다. 렌더링 전에 스크립트는 선택적으로 각 HTML 문자열에 <style> 블록을 표준화하여 미리 첨부합니다 - 동일한 여백 설정, 일정한 본문 글꼴 및 고정된 페이지 너비로 설정하여, 원본의 스타일에 관계없이 모든 보관된 PDF 문서가 동일한 시각적 기준선을 공유하도록 합니다.

이 표준화 단계는 아카이브가 일관된 문서 컬렉션처럼 보이는 것과 무작위 브라우저 캡처 모음처럼 보이는 것 사이의 차이입니다.

3. ChromePdfRenderer가 각 페이지를 PDF 파일로 변환합니다

디스크의 HTML 파일 또는 데이터베이스에서 가져온 HTML 문자열의 경우, RenderHtmlAsPdf()가 변환을 처리합니다. BaseUrlPath 매개 변수는 원본 파일의 디렉토리에 대한 상대 이미지 및 스타일시트 참조를 해결하여 내장 자산을 보존합니다.

using IronPdf;

var renderer = new ChromePdfRenderer();

renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;

renderer.RenderingOptions.MarginTop = 20;

renderer.RenderingOptions.MarginBottom = 20;

string sourceDir = @"C:\LegacyContent\html";

string archiveDir = @"C:\Archive\pdf";

Directory.CreateDirectory(archiveDir);

foreach (string htmlFile in Directory.EnumerateFiles(sourceDir, "*.html"))
{
    string html = File.ReadAllText(htmlFile);
    PdfDocument pdf = renderer.RenderHtmlAsPdf(html, sourceDir);
    string outputPath = Path.Combine(archiveDir,
        Path.GetFileNameWithoutExtension(htmlFile) + ".pdf");

    pdf.SaveAs(outputPath);
    Console.WriteLine($"Archived: {outputPath}");
}
using IronPdf;

var renderer = new ChromePdfRenderer();

renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;

renderer.RenderingOptions.MarginTop = 20;

renderer.RenderingOptions.MarginBottom = 20;

string sourceDir = @"C:\LegacyContent\html";

string archiveDir = @"C:\Archive\pdf";

Directory.CreateDirectory(archiveDir);

foreach (string htmlFile in Directory.EnumerateFiles(sourceDir, "*.html"))
{
    string html = File.ReadAllText(htmlFile);
    PdfDocument pdf = renderer.RenderHtmlAsPdf(html, sourceDir);
    string outputPath = Path.Combine(archiveDir,
        Path.GetFileNameWithoutExtension(htmlFile) + ".pdf");

    pdf.SaveAs(outputPath);
    Console.WriteLine($"Archived: {outputPath}");
}
Imports IronPdf
Imports System.IO

Dim renderer As New ChromePdfRenderer()

renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4

renderer.RenderingOptions.MarginTop = 20

renderer.RenderingOptions.MarginBottom = 20

Dim sourceDir As String = "C:\LegacyContent\html"

Dim archiveDir As String = "C:\Archive\pdf"

Directory.CreateDirectory(archiveDir)

For Each htmlFile As String In Directory.EnumerateFiles(sourceDir, "*.html")
    Dim html As String = File.ReadAllText(htmlFile)
    Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(html, sourceDir)
    Dim outputPath As String = Path.Combine(archiveDir, Path.GetFileNameWithoutExtension(htmlFile) & ".pdf")

    pdf.SaveAs(outputPath)
    Console.WriteLine($"Archived: {outputPath}")
Next
$vbLabelText   $csharpLabel

HTML 파일을 PDF 형식으로 변환

출력 파일

예시 출력: HTML 파일 대 출력 PDF

IronPDF 예시 출력 전달해야 할 서버에서 여전히 캡처해야 하는 라이브 URL의 경우, RenderUrlAsPdf()가 각 요청을 처리합니다. 병렬 배치를 통해 큰 URL 세트 전반에 걸쳐 실행 시간을 관리할 수 있습니다.

using IronPdf;

var renderer = new ChromePdfRenderer();

int completed = 0, failed = 0;

await Parallel.ForEachAsync(urlList,
    new ParallelOptions { MaxDegreeOfParallelism = 4 },
    async (url, _) =>
    {
        try
        {
            PdfDocument pdf = renderer.RenderUrlAsPdf(url);
            string filename = Uri.EscapeDataString(url).Replace("%", "_") + ".pdf";
            pdf.SaveAs(Path.Combine(@"C:\Archive\pdf", filename));
            Interlocked.Increment(ref completed);
        }
        catch (Exception ex)
        {
            Interlocked.Increment(ref failed);
            Console.Error.WriteLine($"Failed: {url} — {ex.Message}");
        }
        Console.WriteLine($"Progress: {completed} completed, {failed} failed");
    });
using IronPdf;

var renderer = new ChromePdfRenderer();

int completed = 0, failed = 0;

await Parallel.ForEachAsync(urlList,
    new ParallelOptions { MaxDegreeOfParallelism = 4 },
    async (url, _) =>
    {
        try
        {
            PdfDocument pdf = renderer.RenderUrlAsPdf(url);
            string filename = Uri.EscapeDataString(url).Replace("%", "_") + ".pdf";
            pdf.SaveAs(Path.Combine(@"C:\Archive\pdf", filename));
            Interlocked.Increment(ref completed);
        }
        catch (Exception ex)
        {
            Interlocked.Increment(ref failed);
            Console.Error.WriteLine($"Failed: {url} — {ex.Message}");
        }
        Console.WriteLine($"Progress: {completed} completed, {failed} failed");
    });
Imports IronPdf
Imports System.IO
Imports System.Threading
Imports System.Threading.Tasks

Dim renderer As New ChromePdfRenderer()

Dim completed As Integer = 0
Dim failed As Integer = 0

Await Parallel.ForEachAsync(urlList,
    New ParallelOptions With {.MaxDegreeOfParallelism = 4},
    Async Function(url, _) As Task
        Try
            Dim pdf As PdfDocument = renderer.RenderUrlAsPdf(url)
            Dim filename As String = Uri.EscapeDataString(url).Replace("%", "_") & ".pdf"
            pdf.SaveAs(Path.Combine("C:\Archive\pdf", filename))
            Interlocked.Increment(completed)
        Catch ex As Exception
            Interlocked.Increment(failed)
            Console.Error.WriteLine($"Failed: {url} — {ex.Message}")
        End Try
        Console.WriteLine($"Progress: {completed} completed, {failed} failed")
    End Function)
$vbLabelText   $csharpLabel

URL에서 생성된 파일

URL에서 생성된 파일

예제 출력

URL을 PDF로 변환한 예시 출력 각 출력 PDF는 원본 사이트 계층 구조를 반영하는 폴더 구조에 저장되며, 매니페스트 파일은 원본 URL, 변환 타임스탬프 및 처리된 각 문서의 출력 경로를 기록합니다.

실제 이점

처리량. IronPDF는 각 페이지를 밀리세컨드 단위로 렌더합니다. 4개의 병렬 스레드로 10,000페이지 아카이브는 보통 몇 시간 안에 표준 서버 하드웨어에서 완료되며, 야간 배치 윈도우가 없고, 변환 실행 간 수동 인계도 없습니다.

시각적 정확성. Chromium 기반 렌더링은 테이블, CSS 레이아웃, 내장 이미지 및 인라인 스타일을 브라우저에서처럼 처리합니다. 아카이브된 PDF는 원본 페이지가 어떻게 보였는지를 그대로 나타내며, 단순화된 추정치가 아닙니다.

일정에 따른 중단. 아카이브 실행이 완료되고 매니페스트가 확인되면 레거시 서버, 데이터베이스 및 CMS 설치를 종료할 수 있습니다. 컨텐츠는 레거시 인프라에서 제공한 것이 아닌 영구적이고 자급자족하는 PDF 모음으로 존재합니다.

규제 준수. 불변의 PDF 스냅샷은 법적 보존 및 보존 요구를 충족합니다. IronPDF는 장기 보관 보존을 위한 PDF/A 출력을 지원하며, 하나의 렌더링 옵션이 결과를 규제된 문서 보존에 수용되는 ISO 표준 형식으로 변환합니다.

콘텐츠 품질 간 일관성. 렌더링 전에 표준화된 스타일시트를 주입하면 모든 아카이브 PDF가 동일한 여백, 글꼴 및 페이지 크기를 공유하도록 보장하며, 원본 HTML이 개발자가 표준을 따르며 작성하였든 Word에서 복사하여 붙여넣기 한 콘텐츠 작성자가 작성했든 상관없이 일관성을 제공합니다.

문서당 비용 없음. 변환은 프로세스 내에서 실행됩니다. 외부 변환 공급업체로의 API 호출이 없으며, 대용량 아카이브를 비경제적으로 만드는 가격 모델도 없습니다. 500 페이지 또는 50,000 페이지를 변환하는 데 드는 비용은 인프라 측면에서는 동일합니다.

마무리

마이그레이션 기한이 있는 콘텐츠 마이그레이션에는 수작업 변환 워크플로우나 복잡한 HTML을 처리하지 못하는 도구를 사용할 시간이 없습니다. 변환은 자동으로 실행되어야 하며, 대량으로 일관된 출력을 생성하고, 오래된 서버가 오프라인 되기 전에 완료되어야 합니다.

IronPDF로 구동하는 .NET 마이그레이션 스크립트는 전체 표면을 다룹니다. 원본 콘텐츠 열거, 스타일 표준화, Chromium을 통한 각 페이지 렌더링, 아카이브 목적지로 쓰기 및 검토를 위한 실패 로깅. IronPDF는 C#에서 HTML 문자열과 URL을 렌더링하고, 문서를 저장하고, 스트리밍하며, 조작하는 등 ironpdf.com에서 PDF 생성을 위한 전체 수명 주기를 처리합니다. 마이그레이션을 탐색하거나 파일럿 실행을 시작하는 경우, 무료 30일 체험을 통해 레거시 콘텐츠의 대표 샘플을 변환하고 전체 아카이브에 전념하기 전에 출력을 검증할 충분한 시간이 주어집니다.

Curtis Chau
기술 문서 작성자

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

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

아이언 서포트 팀

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