이 페이지에는 자동 번역된 텍스트가 포함될 수 있습니다.
.NET PDF 생성기
Docotic.Pdf를 사용하면 페이지, 컨테이너, 텍스트 영역, 이미지, 링크, 머리글, 바닥글, 표, 목록 등과 같은 구조적 요소를 조합하여 PDF 문서를 생성할 수 있습니다. 이러한 요소들은 Docotic.Pdf용 무료 Layout 추가 기능에서 제공하는 고급 Layout API를 통해 이용할 수 있습니다. 또한 이 API는 재사용 가능한 사용자 지정 구성 요소도 지원합니다.

Layout API를 사용하면 C# 또는 VB.NET 코드로 문서를 완벽하게 정의할 수 있으며, 이는 매우 직관적인 접근 방식을 제공합니다. 이러한 설명에 따르면, 이 추가 기능에서 제공하는 PDF 생성기는 단순한 페이지부터 고도로 구조화된 PDF 보고서에 이르기까지, 임의로 복잡한 레이아웃의 문서를 생성할 수 있습니다.
PDF 생성 기본 사항
Layout API를 사용하여 PDF 문서를 생성하려면 무료 Layout 추가 기능이 필요합니다. 핵심 라이브러리와 추가 기능을 사용하려면 라이선스 키도 필요합니다. 무료 평가판 키 또는 구매한 키를 사용할 수 있습니다.
추가 기능을 설치하세요
권장되는 방법은 NuGet에서 추가 기능을 설치하는 것입니다.
Install-Package BitMiracle.Docotic.Pdf.Layout
패키지 관리자가 종속성을 자동으로 처리합니다.
추가 기능을 수동으로 설치하려면 먼저 Docotic.Pdf 바이너리가 포함된 ZIP 아카이브를 다운로드하십시오. 아카이브의 압축을 풀고 다음 DLL에 대한 참조를 추가하십시오.
BitMiracle.Docotic.Pdf.dllLayout add-on하위 폴더에 있는BitMiracle.Docotic.Pdf.Layout.dll
라이선스 키를 받으세요
라이브러리를 사용해 보려면 Docotic.Pdf 다운로드 페이지에서 양식을 작성하여 무료 기간 한정 라이선스 키를 요청하세요. 이미 라이선스를 구매하셨다면 구매 후 제공된 코드를 사용하세요.
Layout 애드온은 무료이며 추가 라이선스가 필요하지 않습니다. 기존에 보유하고 있는 Docotic.Pdf 라이선스로 Layout API를 사용할 수 있습니다.
안녕하세요, 세상아! Layout API를 사용해 보세요
다음은 API를 사용하여 "Hello, world!"라는 고전적인 문구가 포함된 PDF를 생성하는 샘플 코드입니다.
BitMiracle.Docotic.LicenseManager.AddLicenseData("PUT-LICENSE-HERE");
PdfDocumentBuilder.Create().Generate("hello.pdf", doc => doc.Pages(pages =>
{
pages.Content().Text("Hello, world!");
}));
이 코드는 텍스트가 왼쪽 상단에 있는 단일 페이지 PDF를 생성합니다.
코드 샘플 이해하기
이 예제는 먼저 라이선스 키를 추가하는 것으로 시작합니다. 라이선스가 없으면 Docotic.Pdf 라이브러리는 아무것도 생성하지 않습니다. PDF 생성 코드는 다음 줄부터 시작됩니다.
이 코드는 정적 PdfDocumentBuilder.Create() 메서드를 호출하여 문서 빌더 인스턴스를 생성합니다.
Generate 메서드 호출은 PDF 생성 프로세스를 시작합니다. 이 메서드는 생성할 파일 이름과
Action<Document> 형식의 델리게이트라는 두 개의 매개변수를 받습니다. 애드온은 Generate 호출
결과로 hello.pdf를 생성합니다.
PDF의 레이아웃을 결정하기 위해 문서 빌더는 Document 인스턴스를 사용하여 델리게이트를 호출합니다.
델리게이트 코드는 문서 내용을 구성합니다. 이 예제에서 델리게이트는 Pages 메서드를 사용하여 문서
페이지 레이아웃을 정의하는 또 다른 델리게이트를 빌더에 제공합니다.
빌더는 Pages 메서드에 제공된 델리게이트를 PageLayout 인스턴스와 함께 호출합니다. 이 인스턴스는
문서의 하나 이상의 페이지를 나타냅니다. 페이지 수는 추가되는 콘텐츠에 따라 달라집니다.
페이지 델리게이트는 Content 메서드를 호출하여 페이지의 기본 콘텐츠를 담는 레이아웃 컨테이너에
접근합니다. 컨테이너의 Text 메서드를 순차적으로 호출하면 샘플 텍스트가 페이지에 추가됩니다.
레이아웃 컨테이너의 작동 방식에 대한 자세한 설명은 레이아웃 컨테이너 가이드를
참조하세요.
문서 빌더는 기본 콘텐츠 레이아웃 컨테이너에 추가된 모든 데이터를 담는 데 필요한 페이지 수만큼 콘텐츠를 자동으로 분할합니다. 이 예제에서는 한 페이지로 충분하므로 출력 결과는 정확히 한 페이지입니다.
기본 샘플 외의 일반적인 작업
샘플 코드는 먼저 PdfDocumentBuilder 인스턴스를 생성한 다음 Generate 메서드를 호출하여 PDF를
생성합니다. PDF 생성을 시작하기 전에 빌더를 구성할 수 있습니다.
예를 들어, 빌더에 암호화 핸들러를 제공하여 암호화된 PDF를 생성할 수 있습니다. 또한 생성된 문서에 포함할 메타데이터를 빌더에 지정할 수도 있습니다. 빌더 사용자 지정 방법에 대한 자세한 내용은 별도의 문서를 참조하십시오.
샘플 코드는 기본 콘텐츠 슬롯의 레이아웃 컨테이너만 사용하지만, 다른 콘텐츠 슬롯도 사용할 수
있습니다. 콘텐츠 슬롯에 접근하기 위한 PageLayout 메서드 전체 목록은 다음과 같습니다.
Background()- 다른 콘텐츠로 가려지는 배경 레이어를 반환합니다.Header()- 모든 페이지에 공통으로 적용되는 헤더를 반환합니다.Content()- 메인 페이지 콘텐츠 슬롯을 반환합니다.Footer()- 모든 페이지에 공통으로 적용되는 바닥글을 반환합니다.Foreground()- 다른 콘텐츠 위에 나타나는 전경 레이어를 반환합니다.
메인 콘텐츠 슬롯의 내용만 생성된 PDF의 페이지 수에 영향을 미칩니다. 문서 빌더는 Content()에서
제공하는 슬롯을 제외한 모든 슬롯의 내용을 모든 페이지에 반복해서 표시합니다. 콘텐츠 슬롯에 대한
자세한 내용은 페이지 레이아웃 문서를 참조하세요.
많은 문서에서 페이지마다 다른 레이아웃을 사용합니다. 예를 들어 첫 페이지는 표지 스타일 디자인을
사용하고, 이후 페이지는 더 간단한 레이아웃을 사용할 수 있습니다. 일부 문서는 표를 위한 특수
페이지를 포함하거나 섹션에 따라 다른 배경을 적용하기도 합니다. Docotic.Pdf와 Layout7 추가 기능을
사용하여 이러한 문서를 생성하려면 Document.Pages 메서드를 여러 번 호출하세요. 샘플 저장소에서
작동 예제를 찾을 수 있습니다.
코드 정리하기
예제처럼 짧은 코드의 경우, 함수 호출을 연결하거나 람다식을 중첩해서 사용하는 것이 괜찮습니다. 하지만 코드가 커질수록 코드를 여러 개의 메서드로 분리하는 것이 더 편리해집니다. 이렇게 하면 코드를 읽기 쉽고 유지보수하기도 간편해집니다.
아래는 예제 코드인 "Hello, world!"를 메서드로 분리했을 때의 모습입니다.
public void GeneratePdf()
{
BitMiracle.Docotic.LicenseManager.AddLicenseData("PUT-LICENSE-HERE");
PdfDocumentBuilder.Create().Generate("hello.pdf", BuildDocument);
}
private void BuildDocument(Document doc)
{
doc.Pages(BuildPages);
}
private void BuildPages(PageLayout pages)
{
pages.Content().Text("Hello, world!");
}
Docotic.Pdf Layout API를 사용하여 PDF를 생성하는 이유는 무엇일까요?
Layout API는 개발자 친화적인 최신 방식으로, PDF 형식의 내부 구조를 이해할 필요 없이 구성 가능한 빌딩 블록을 사용하여 PDF를 생성할 수 있습니다. 이 API는 높은 성능과 예측 가능한 동작으로 PDF 레이아웃을 구성하며, 대용량 문서 생성 시나리오에 적합합니다.
이 API는 Docotic.Pdf와 무료 Layout 추가 기능을 함께 사용할 때 제공됩니다. Docotic.Pdf와 Layout 추가 기능은 모두 안전하지 않은 코드 블록이 없는 100% 관리 코드 DLL입니다. Layout API는 브라우저나 Skia 바이너리와 같은 타사 외부 종속성 없이 구현되어 배포 및 유지 관리가 용이한 경량의 저부하 솔루션입니다.
API 개요
Layout API는 유려하고 사용하기 편리한 API입니다. 유연한 레이아웃 요소를 사용하여 문서 레이아웃을 코드로 완벽하게 정의할 수 있으며, 문서 생성기는 콘텐츠를 자연스럽게 배치하고 자동으로 페이지를 매겨 PDF로 렌더링합니다.
Layout 애드온은 선언적이고 흐름 기반의 레이아웃 시스템을 사용합니다. 레이아웃 요소에는 목록, 열, 행, 표, 이미지, 텍스트 스팬, 머리글 및 바닥글, 컨테이너 등이 포함됩니다. 요소를 정확한 좌표에 수동으로 배치하는 대신, 요소의 동작 방식을 정의하기만 하면 됩니다. 그러면 문서 빌더가 최종 레이아웃을 계산하고 PDF를 생성합니다.
흐름 기반 레이아웃 시스템은 페이지 크기와 콘텐츠에 따라 레이아웃이 자동으로 조정되도록 합니다. 이 시스템 덕분에 Layout 애드온은 복잡하고 구조화된 규칙 기반 레이아웃에 탁월합니다. 다양한 유형의 컨테이너를 중첩하고 가독성을 유지하면서 정교한 구조를 구축할 수 있습니다.
Layout API를 사용할 때는 대부분의 호출을 연결하여 사용할 수 있습니다. 따라서 기존 API보다 더 간결하고 표현력이 풍부한 코드를 작성할 수 있습니다. 단, 호출 순서는 중요합니다. 모든 것이 강력한 타입 시스템을 지원하여 컴파일 타임 안전성을 제공하고 코드 리팩토링을 용이하게 합니다. 또한 Layout API를 사용하는 코드를 단위 테스트할 수 있습니다.
레이아웃 구현을 더욱 간결하게 하려면 API에 자체 메서드를 추가하고 깔끔하고 표현력 있는 DSL(도메인 특화 언어)을 구축할 수 있습니다.
위치 지정 및 DSL 생성에 대한 자세한 내용은 컨테이너의 크기, 위치, 정렬 및 렌더링 동작을 제어하는 방법을 설명하는 문서를 참조하십시오.
.NET 버전 및 플랫폼 지원
Layout API는 .NET Standard 2.1 이상 프레임워크를 대상으로 하는 프로젝트에서 사용할 수 있습니다. 즉, Layout 애드온은 .NET 5부터 .NET 10까지 호환됩니다. 또한 .NET Core 3.0 이상도 지원합니다.
Layout API를 사용하면 ASP.NET Core, MAUI 앱, Unity, Xamarin 및 콘솔 애플리케이션에서 PDF를 생성할 수 있습니다. Docotic.Pdf는 Layout 애드온을 통해 Windows, macOS 및 Linux에서 PDF를 생성할 수 있습니다.
클라우드 플랫폼 및 도커 이미지
Docotic.Pdf는 Layout7 애드온과 함께 Azure 및 AWS 클라우드 환경(서버리스 환경 포함)에서 실행할 수 있습니다. 이 라이브러리와 애드온은 동적 하드웨어 변경, 자동 확장 및 기타 클라우드 네이티브 런타임 기능을 완벽하게 지원합니다.
대부분의 클라우드 시나리오에서는 무제한 라이선스가 필요합니다. 라이선스 FAQ에서 클라우드 애플리케이션에 적합한 라이선스를 선택하는 방법을 확인하세요.
Layout API는 Docker 컨테이너에서 바로 작동합니다. 컨테이너 내에서 라이브러리와 Layout 애드온을 실행할 때 PDF를 생성하기 위한 특별한 구성은 필요하지 않습니다.
PDF 파일에 텍스트 추가하기
텍스트는 모든 PDF 문서의 기본 요소입니다.
LayoutContainer 클래스의 Text 메서드를 사용하여
콘텐츠 슬롯에 텍스트를 추가할 수 있습니다.

텍스트 범위
"Hello, world" 예제에서는 LayoutContainer.Text(string) 오버로드를 사용하여 페이지의 기본 콘텐츠에
텍스트를 추가했습니다. 이제 Text 메서드의 다른 오버로드를 살펴보겠습니다.
public static void GenerateTextPdf()
{
PdfDocumentBuilder.Create().Generate("text-spans.pdf", doc => doc.Pages(pages =>
{
pages.Content().Text(AddTextSpans);
}));
}
private static void AddTextSpans(TextContainer text)
{
text.Line("About VB.NET")
.Style(t => t.Strong);
text.Span("VB.NET is a multi-paradigm, object-oriented language ");
text.Span("that runs on .NET, Mono, and the ");
text.Hyperlink(
".NET Framework",
new Uri("https://dotnet.microsoft.com/download/dotnet-framework"));
text.Line(".");
text.Span("Released by Microsoft in 2002, ");
text.Line("it continues the lineage of the original Visual Basic language.");
}
이 코드는 TextContainer 클래스의 Span 및 Line 메서드를 사용하여 현재 줄에 텍스트를
추가합니다. Line 메서드는 현재 줄을 자동으로 완성하는 기능도 제공합니다. 또한, 샘플 코드는
Hyperlink 메서드를 사용하여 특정 텍스트 영역에 외부 리소스 링크를 연결합니다.
샘플 코드에서 Style 메서드를 사용하여 첫 번째 줄에 강력한 서식을 적용하는 것을 확인해 보세요.
이제 텍스트 스타일의 개념을 좀 더 자세히 살펴보겠습니다.
텍스트 스타일
텍스트 스타일을 사용하면 텍스트의 모양을 사용자 지정할 수 있습니다.
TextStyle 클래스는 글꼴 크기, 자간, 색상 및 기타 텍스트
속성을 변경하는 메서드를 제공합니다. TextStyle 객체는 불변 객체이므로 각 메서드 호출 시 새로운
스타일 인스턴스가 생성됩니다. 텍스트 스타일은 다양한 레이아웃 레벨에 적용할 수 있습니다.
PdfDocumentBuilder.Create().Generate("text-styles.pdf", doc =>
{
doc.Pages(pages =>
{
pages.TextStyle(TextStyle.Parent.FontSize(30));
pages.Content()
.TextStyle(TextStyle.Parent.FontColor(new PdfRgbColor(0, 0, 255)))
.Text(text =>
{
text.Span("Hello,");
text.Span("World!")
.Style(TextStyle.Parent.Underline());
});
});
});
TextStyle.Parent 속성은 모든 텍스트 속성이 정의되지 않은 특수한 스타일을 반환합니다. 위 예제
코드는 30포인트 글꼴 크기로 "Hello, World!"를 파란색으로 표시하고 두 번째 단어에 밑줄을 긋습니다.
이러한 결과는 다음과 같은 코드 동작 때문입니다.
- 페이지 수준에서 글꼴 크기를 30포인트로 설정합니다.
- 기본 콘텐츠 슬롯의 텍스트 색상을 파란색으로 설정합니다.
- 마지막 텍스트 영역에 밑줄 스타일을 적용합니다.
이후의 각 스타일은 TextStyle.Parent 속성을 통해 이전 스타일을 상속합니다.
TextStyle 클래스의 메서드를 사용하면 텍스트 방향을 오른쪽에서 왼쪽으로 변경하는 등의 작업을
수행할 수 있습니다. 텍스트 스타일 상속을 사용하는 다른 예제는 샘플 저장소를
참조하세요.
타이포그래피
TextStyle 클래스는 연결된 글꼴을 제외한 모든 텍스트 속성을 사용자 지정할 수 있도록 지원합니다.
기본 글꼴을 변경하려면 Document.TextStyleWithFont 메서드를 사용하여 특정 글꼴을 기반으로 하는
텍스트 스타일을 만들 수 있습니다. 운영 체제에 설치된 글꼴을 사용하거나 파일 또는 스트림에서 글꼴을
로드할 수 있습니다.
글꼴 기반 스타일을 만든 후에는 추가적인 선택적 속성을 적용하고 결과 스타일을 텍스트 영역에 사용할 수 있습니다. 이 C# 예제는 시스템 글꼴을 사용하는 방법을 보여줍니다.
PdfDocumentBuilder.Create().Generate("text-style-with-font.pdf", doc =>
{
var font = SystemFont.Family("Calibri");
var style = doc.TextStyleWithFont(font).FontSize(30);
doc.Pages(pages =>
{
pages.Content().Text(text =>
{
text.Span("Hello,");
text.Span("World!")
.Style(style);
});
});
});
TextStyleWithFont 메서드는 생성된 문서에 글꼴을 포함하는 방식을 지정하는 선택적 매개변수를
제공합니다. 기본적으로 라이브러리는 다음과 같이 동작합니다.
- TrueType/OpenType 글꼴의 경우 사용된 글리프를 포함합니다.
- Type1 및 CFF 글꼴의 경우 모든 글리프를 포함합니다.
- 내장 PDF 글꼴(Base14 글꼴)의 경우 글리프를 포함하지 않습니다.
이러한 기본 설정 때문에 TrueType 및 OpenType 글꼴을 사용하는 문서는 글꼴 크기가 크더라도 크기가 작을 수 있습니다. 사용자 지정 글꼴 로더, 대체 글꼴, 누락된 글리프 처리기를 지정할 수도 있습니다. PDF 문서에서 글꼴을 관리하는 방법에 대한 자세한 내용은 예제 저장소의 샘플 코드를 참조하세요.
Layout API는 미리 정의된 스타일 모음을 제공하며, 이러한 스타일은 Typography 클래스를 통해 액세스하고 수정할 수 있습니다.
PdfDocumentBuilder.Create().Generate("typography.pdf", doc =>
{
doc.Typography(t =>
{
var fontsPath = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
var arialFont = new FileInfo(Path.Combine(fontsPath, "arial.ttf"));
t.Document = doc.TextStyleWithFont(arialFont);
t.Header = t.Parent.FontSize(20).FontColor(new PdfGrayColor(20));
t.Footer = t.Footnote;
});
doc.Pages(pages =>
{
pages.Header().AlignCenter().Text("Header");
pages.Content().Text(t =>
{
t.Line("Title").Style(t => t.Title);
t.Line("Heading 1").Style(t => t.Heading1);
t.Line("Regular");
});
pages.Footer()
.Height(20)
.AlignCenter()
.Text(t => t.CurrentPageNumber());
});
});
미리 정의된 스타일을 재정의하려면 문서 전체에 대한 타이포그래피를 구성하는 것이 좋습니다. 하지만 이는 필수 사항은 아니며, 텍스트 영역별로 스타일을 적용할 수도 있습니다.
Typography 클래스를 사용하면 텍스트 스타일 참조를 변수에 저장할 필요가 없습니다. 대신
Document.Typography 메서드를 사용하여 필요한 스타일을 등록하고, 나중에 Typography 객체의 속성을
통해 해당 스타일에 접근할 수 있습니다. PDF 문서를 생성할 때 미리 정의된 스타일과 사용자 지정
스타일을 사용하는 방법은 타이포그래피 샘플을 참조하십시오.
머리글과 바닥글 작업하기
보고서나 송장과 같은 실제 PDF 문서에는 머리글과 바닥글이 포함되는 경우가 많습니다. 이 섹션에서는 PDF에 머리글과 바닥글을 추가하는 방법을 보여줍니다.
public static void GeneratePdfWithHeaderAndFooter()
{
PdfDocumentBuilder.Create()
.Generate("header-footer.pdf", doc => doc.Pages(pages =>
{
pages.Size(PdfPaperSize.A6).Margin(10);
BuildPagesHeader(pages.Header());
BuildPagesFooter(pages.Footer());
pages.Content().Text("Hello, world!");
}));
}
public static void BuildPagesHeader(LayoutContainer header)
{
header.TextStyle(TextStyle.Parent.FontSize(8))
.AlignRight()
.Text(t =>
{
t.Line($"Created by: {Environment.UserName}");
t.Line($"Date: {DateTime.Now}");
});
}
public static void BuildPagesFooter(LayoutContainer footer)
{
footer.AlignRight().Text(text =>
{
text.Style(t => t.Parent.FontColor(new PdfRgbColor(255, 0, 0)));
text.CurrentPageNumber();
text.Span(" / ");
text.PageCount();
});
}
BuildPagesHeader 메서드는 헤더 텍스트의 글꼴 크기를 작게 설정합니다. 헤더 내용은 두 줄로
구성되며, 한 줄에는 현재 사용자의 이름이, 다른 한 줄에는 현재 날짜가 표시됩니다. 텍스트는 오른쪽
정렬됩니다.
코드에서 헤더의 크기를 명시적으로 지정하지 않았다는 점에 유의하십시오. 헤더는 왼쪽 및 오른쪽 여백을 제외한 전체 페이지 너비를 차지하며, 높이는 텍스트 줄의 높이에 따라 결정됩니다.
BuildPagesFooter 메서드는 PDF 바닥글에 현재 페이지 번호를 표시하는 방법을 보여줍니다.
라이브러리는 현재 페이지 번호와 전체 페이지 수를 자동으로 계산합니다. 이러한 값은
TextContainer 객체의 CurrentPageNumber 및
PageCount 메서드를 사용하여 접근할 수 있습니다.
Layout API는 페이지 번호 서식 지정 기능도 제공합니다. 예를 들어 다음과 같이 16진수 페이지 번호를 표시할 수 있습니다.
text.CurrentPageNumber().Format(p => "0x" + p?.ToString("x2"));
저희 샘플 저장소에는 PDF에 머리글과 바닥글을 추가하는 또 다른 예제가 있습니다. 해당 예제에서는 페이지 번호를 로마 숫자로 표시합니다.
이미지 삽입
"한 장의 그림이 많은 말을 대신할 수 있다"는 말이 있죠. 견적서나 영수증에 회사 로고나 중요한 이미지를 넣는 경우가 종종 있습니다. 이 예시에서는 간단하고 보기 좋은 이미지를 사용하겠습니다.
이미지를 사용하려면 먼저 문서에 이미지를 추가해야 합니다. 라이브러리는 파일이나 스트림에서 이미지를 불러올 수 있습니다. PNG, JPEG, JPEG 2000, BMP, GIF, TIFF와 같은 래스터 형식만 지원합니다.
Image 객체를 얻으면 하나 이상의 레이아웃 컨테이너의 Image 메서드를 호출하여 해당 컨테이너의
콘텐츠로 설정할 수 있습니다. 이미지를 확대/축소, 회전, 패딩 추가 및 배치하는 것은 다른 콘텐츠와
마찬가지로 가능합니다.
PdfDocumentBuilder.Create().Generate("image-with-text.pdf", doc =>
{
var imageFile = new FileInfo("red-flowers-at-butterfly-world.jpg");
var image = doc.Image(imageFile);
doc.Pages(pages =>
{
pages.Size(PdfPaperSize.A6);
pages.Content().Column(c =>
{
c.Spacing(20);
c.Item()
.AlignCenter()
.Text("Hello, world!")
.FontSize(20);
c.Item()
.AlignCenter()
.MaxWidth(200)
.Image(image);
});
});
});
샘플 코드는 기본 콘텐츠 슬롯에 텍스트와 이미지를 모두 사용합니다. 하지만 레이아웃 컨테이너는 텍스트만 또는 이미지만 포함할 수 있습니다. 페이지의 기본 콘텐츠 슬롯에 텍스트와 이미지를 모두 포함하려면 복합 컨테이너가 필요합니다.
저는 Column 컨테이너를 사용하여 텍스트와 이미지를 세로로 나란히 배치합니다. Column 컨테이너의
Item 메서드는 하위 컨테이너를 제공합니다. Item 메서드를 한 번 호출하면 텍스트를 위한 컨테이너가
생성되고, 다른 한 번 호출하면 이미지를 위한 컨테이너가 생성됩니다. 이렇게 생성된 복합 컨테이너와 그
하위 컨테이너들이 메인 콘텐츠가 됩니다.
샘플 코드를 실행하려면 샘플 저장소에서 꽃 이미지 파일을 다운로드하여 앱의 작업 디렉터리에 놓으세요.
온라인 이미지
이미지 파일이 아닌 이미지 URL만 있는 경우, 이미지를 메모리 스트림으로 다운로드한 다음 해당
스트림에서 Image 객체를 생성합니다. 다음 예는 Layout API를 사용하여 온라인 이미지를 사용하는
방법을 보여줍니다.
public static async Task AddImageWithTextFromUrl()
{
using var http = new HttpClient();
using var stream = await http.GetStreamAsync("url/to/image");
var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream);
memoryStream.Position = 0;
PdfDocumentBuilder.Create().Generate("online-image-with-text.pdf", doc =>
{
var image = doc.Image(memoryStream);
doc.Pages(pages =>
{
pages.Size(PdfPaperSize.A6);
pages.Content().Column(c =>
{
c.Spacing(20);
c.Item()
.AlignCenter()
.Text("Hello, world!")
.FontSize(20);
c.Item()
.AlignCenter()
.MaxWidth(200)
.Image(image);
});
});
});
}
이 메서드는 비동기 작업(URL에서 이미지 다운로드)을 수행하므로 void가 아닌 async Task로
선언됩니다. 호출자는 PDF 생성이 올바르게 완료되도록 await를 사용해야 합니다. 여러분의 코드에서
유사한 메서드가 값을 반환하는 경우, async Task<TResult>로 선언하면 됩니다.
목록 만들기
리스트란 무엇일까요? 리스트는 번호가 매겨진 항목들이 아래로 나열된 그룹이라고 생각하면 됩니다. Layout API는 리스트를 위한 특별한 컨테이너 유형을 제공하지 않지만, 다른 복합 컨테이너를 사용하면 쉽게 구현할 수 있습니다.
var dayNames = DateTimeFormatInfo.InvariantInfo.DayNames;
var dayNamesSpain = DateTimeFormatInfo.GetInstance(new CultureInfo("es-ES")).DayNames;
PdfDocumentBuilder.Create().Generate("list.pdf", doc => doc.Pages(pages =>
{
pages.Size(PdfPaperSize.A6);
pages.Content().Column(column =>
{
for (int i = 0; i < dayNames.Length; i++)
{
column.Item().Row(row =>
{
row.Spacing(5);
row.AutoItem().Text($"{i + 1}.");
row.RelativeItem().Text(t =>
{
t.Line(dayNames[i]);
t.Line($"In Spain they call it {dayNamesSpain[i]}");
});
});
}
});
}));
이 예제 코드는 목록을 여러 행으로 구성된 열 형태로 생성합니다. 각 행에는 두 개의 항목이 포함되는데, 첫 번째 행(왼쪽)에는 항목 번호가, 두 번째 행(오른쪽)에는 항목 설명이 표시됩니다. 코드는 각 행의 항목 간 간격을 명시적으로 설정합니다.
항목을 정렬하려면 Row 컨테이너에 각 항목의 크기를 명시적으로 지정하거나 계산해야 합니다. 이
예제에서는 AutoItem 및 RelativeItem 메서드를 사용합니다. 결과적으로 행 컨테이너는 첫 번째
항목에 필요한 너비를 계산한 다음 남은 너비를 두 번째 항목에 사용합니다.
이러한 방식을 사용하고 필요에 따라 행의 모양을 조정하면 문서 레이아웃과 스타일에 가장 적합한 목록을 만들 수 있습니다.
건축용 테이블
많은 PDF 문서에는 표가 포함되어 있는데, 이는 표가 데이터의 명확성과 구성 방식을 개선하기 때문에 당연한 일입니다. 이 섹션에서는 Layout API를 사용하여 PDF에 표를 만드는 방법을 보여줍니다.
public static void AddTable()
{
PdfDocumentBuilder.Create().Generate("table.pdf", doc => doc.Pages(pages =>
{
pages.Size(PdfPaperSize.A6);
var color = new PdfGrayColor(75);
pages.Content().Padding(20).Table(t =>
{
t.Columns(c =>
{
c.RelativeColumn(4);
c.RelativeColumn(1);
c.RelativeColumn(4);
});
t.Header(h =>
{
h.Cell().Background(color).Text("Month");
h.Cell().Background(color).Text("Days");
h.Cell().Background(color).Text("First Day");
});
var year = DateTime.Now.Year;
for (int yearDiff = 0; yearDiff < 4; yearDiff++)
{
for (int i = 11; i >= 0; i--)
{
var stats = GetMonthStats(year - yearDiff, i);
t.Cell().Text(stats.Item1);
t.Cell().Text(stats.Item2);
t.Cell().Text(stats.Item3);
}
}
});
}));
}
private static (string, string, string) GetMonthStats(int year, int monthIndex)
{
return (
$"{DateTimeFormatInfo.InvariantInfo.MonthNames[monthIndex]} {year}",
DateTime.DaysInMonth(year, monthIndex + 1).ToString(),
new DateTime(year, monthIndex + 1, 1).DayOfWeek.ToString()
);
}
이 예제 코드는 현재 연도와 지난 3년간의 각 월에 대한 기본 정보를 표시하는 간단한 표를 생성합니다. 코드는 상대적인 너비를 가진 세 개의 열을 정의합니다. 가장 왼쪽과 가장 오른쪽 열은 가운데 열보다 네 배 넓습니다.
또한, 헤더 셀을 추가하고 각 셀의 텍스트와 배경색을 지정하여 표 헤더를 정의합니다. 표가 한 페이지에 맞지 않을 경우, 헤더는 표가 차지하는 모든 페이지에 반복됩니다. 이 동작은 예제 코드로 생성된 PDF에서 확인할 수 있습니다.
행을 구성하기 위해 두 개의 간단한 반복문이 사용됩니다. 바깥쪽 반복문은 연도를 순회하고, 안쪽 반복문은 월을 역순으로 순회합니다. 안쪽 반복문은 각 월에 대한 정보를 가져온 다음 세 개의 셀을 추가하여 한 행을 구성합니다.
더 자세한 내용은 Table 컨테이너의 기능을 심층적으로 설명하는 문서를 참조하십시오.
내부 PDF 링크 생성
PDF 문서는 독자가 동일한 파일 내의 다른 위치로 이동할 수 있도록 내부 링크를 지원합니다. PDF 뷰어에서 이러한 링크는 클릭 가능한 텍스트 또는 이미지 요소로 표시됩니다. 하이퍼링크와 유사하게 작동하지만, 외부 웹사이트를 가리키는 대신 문서 내부에서 이동합니다.

많은 PDF 문서에서는 책갈피나 목차와 같은 내부 링크를 사용하여 독자가 섹션 간에 빠르게 이동할 수 있도록 합니다. Layout API를 사용하여 문서 섹션에 링크를 추가하는 방법은 다음과 같습니다.
PdfDocumentBuilder.Create().Generate("link.pdf", doc =>
{
doc.Pages(pages =>
{
pages.Content().Column(c =>
{
const string SectionName = "Chapter 1";
c.Item().SectionLink(SectionName).Text("Link");
c.Item().PageBreak();
c.Item().Section(SectionName).Text("Target");
});
});
});
이 예제 코드는 첫 페이지의 텍스트를 지정된 이름의 섹션으로 연결하는 링크로 만듭니다. 이를 위해
텍스트가 포함된 레이아웃 컨테이너에서 SectionLink 메서드를 호출합니다. 이 시점에서 해당 섹션은
존재할 수도 있고 존재하지 않을 수도 있습니다. 링크가 생성되면 PDF 뷰어에서 텍스트를 클릭할 수 있게
됩니다.
그런 다음 코드는 두 번째 페이지의 텍스트를 동일한 이름의 섹션 시작 부분으로 지정합니다. 해당
텍스트의 모양과 동작은 변경되지 않지만, 첫 페이지 링크의 대상이 됩니다. 이는 해당 레이아웃
컨테이너에서 Section 메서드를 호출하여 수행됩니다.
이 예제에서는 링크와 대상 모두 텍스트 스팬이지만, 이미지 컨테이너, 테이블 컨테이너 또는 직접 생성한 컨테이너 등 어떤 레이아웃 컨테이너에도 섹션과 링크를 만들 수 있습니다.
PDF 목차를 만드는 방법에 대한 예제는 샘플 저장소를 참조하세요.
복잡한 PDF 레이아웃 디자인하기
Layout API는 다양한 레이아웃 컨테이너를 제공하여, 이를 조합하여 매우 복잡한 PDF 문서를 생성할 수 있습니다. 또한, 사용자 정의 컴포넌트를 추가하여 API를 확장할 수도 있습니다.
이 페이지의 예제는 의도적으로 간단하게 구성되어 있으며, 핵심 개념에 집중하고 세부적인 내용에 얽매이지 않도록 직관적인 문서를 생성하는 데 초점을 맞추고 있습니다. 다양한 컨테이너를 조합하여 더욱 복잡한 PDF를 생성하는 방법을 살펴보려면 GitHub의 샘플 저장소에서 해당 예제를 참조하세요.
내장 컨테이너 외에도 사용자 정의 레이아웃 컴포넌트를 정의하고 사용할 수 있습니다. 이러한 컴포넌트는 데이터와 레이아웃 로직을 하나의 클래스에 캡슐화하려는 경우 특히 유용합니다. 모든 것을 한 곳에 유지함으로써 컴포넌트를 더 쉽게 이해하고 수정하고 재사용할 수 있으며, 복잡한 레이아웃을 유연하게 처리할 수 있습니다.
사용자 정의 레이아웃 컴포넌트를 생성하려면 클래스에서 ILayoutComponent 인터페이스를 구현하세요.
PDF를 생성할 때 라이브러리는 해당 인터페이스의 Compose 메서드를 호출하고 LayoutContext 객체를
반환합니다. 이 객체를 사용하여 레이아웃 요소를 생성하고 생성 중인 문서에 대한 정보에 접근할 수
있습니다.
레이아웃에 사용자 지정 레이아웃 구성 요소를 추가하려면 LayoutContainer 클래스의 Component
메서드를 호출합니다. 크기 및 위치 지정 측면에서 사용자 지정 구성 요소는 텍스트나 이미지와 동일하게
동작합니다.
ILayoutComponent 인터페이스를 사용하여 사용자 지정 구성 요소를 구현하는 예제는 레이아웃 구성
요소 샘플을 참조하십시오.
PDF를 만드는 다른 방법
Docotic.Pdf는 다양한 시나리오에 적합한 여러 가지 PDF 생성 방법을 제공합니다. 이 섹션에서는 Layout API를 사용해야 하는 경우와 다른 접근 방식이 더 적합한 경우를 설명합니다.
Layout API를 언제 사용하는 것이 더 좋을까요?
Docotic.Pdf Layout API는 구조화된 레이아웃을 기반으로 PDF를 생성하는 강력한 도구입니다. 텍스트, 이미지, 컨테이너, 테이블을 조합하여 임의로 복잡하고 중첩된 구조의 문서를 만들 수 있습니다. 생성 과정은 빠르고 메모리 사용량도 적절하며 예측 가능한 동작을 보입니다.
Docotic.Pdf와 Layout 애드온은 가볍고 완벽하게 독립 실행형으로 구성되어 있습니다. 이 API는 PDF 생성에 외부 라이브러리나 브라우저를 필요로 하지 않습니다. 따라서 .NET 마이크로서비스, 클라우드 애플리케이션(특히 서버리스 애플리케이션), 그리고 메모리 사용량이 중요한 환경에 적합합니다.
문서 레이아웃이 코드로 정의되므로 모든 부분을 단위 테스트할 수 있습니다. 레이아웃 로직은 다른 코드처럼 재사용할 수 있으며, 데이터와 레이아웃 동작 모두를 사용자 지정 구성 요소로 캡슐화할 수 있습니다.
Layout API의 대안
별도의 문서에서 Docotic.Pdf를 포함한 모든 PDF 생성 방법을 자세히 비교합니다. 아래는 가장 일반적으로 사용되는 몇 가지 대안입니다.
-
HTML을 PDF로 변환
기존 HTML/CSS 템플릿을 재사용합니다. 팀에서 이미 HTML/CSS로 문서를 작성하고 해당 문서의 PDF 버전이 필요한 경우 HTML-to-PDF 방식을 선택하세요. -
저수준 PDF 생성
라이브러리에서 PDF 구조 및 콘텐츠에 대한 최대 제어 기능을 제공합니다. 픽셀 단위 위치 지정이나 복잡한 벡터 그래픽이 필요한 경우에 선택하십시오. 이 방식은 성능이 중요한 시나리오나 최소한의 용량이 요구되는 경우에 권장됩니다. -
템플릿 기반 PDF 생성
문서 디자인이나 요소 배치 없이 빠르고 예측 가능한 방식으로 문서를 채울 수 있습니다. 승인되었거나 규정 준수 관리가 되는 템플릿과 같이 미리 정의된 PDF 구조가 있고 텍스트 필드 변경, 자리 표시자 교체, 관련 문서 첨부 등의 작업만 필요한 경우에 이 기능을 선택하십시오. -
PDF 병합 및 구성
기존 파일들을 조합하여 PDF를 만들 수 있습니다. 이미지, 스캔한 페이지 또는 다른 PDF 파일들을 하나의 파일로 병합해야 할 때 이 옵션을 선택하세요.
다른 PDF 생성 솔루션과의 비교
이 섹션에는 두 개의 비교표가 있습니다. 하나는 주요 내용을 요약한 표이고, 다른 하나는 Layout 추가 기능이 포함된 Docotic.Pdf가 다른 인기 있는 PDF 생성 솔루션과 어떻게 다른지 자세하고 체계적인 정보를 제공하는 표입니다.
주요 비교 요점
PDF를 생성하는 데 사용할 수 있는 다양한 옵션이 있으며, 무료 옵션도 있습니다. 하지만 문서 서명, 암호화 또는 병합과 같은 기능은 도구마다 다르기 때문에 사용자의 요구 사항에 실제로 적합한 도구를 선택하는 데 제약이 있을 수 있습니다.
| 해결책 | 사용 시점 | 가장 적합한 대상 |
|---|---|---|
| Layout 추가 기능이 포함된 Docotic.Pdf | 고품질, 고성능 레이아웃 엔진을 원할 때, 최적화된 PDF를 생성하고 서명, 암호화 및 다양한 플랫폼에서의 PDF 편집을 위한 고급 기능을 제공하는 솔루션을 찾고 있다면 이 엔진이 적합합니다 | 고품질의 송장, 보고서, 명세서 및 유사 문서를 생성하고 개발자 경험을 극대화합니다. 기업 수준의 PDF 처리 및 전문적인 지원이 필요한 경우에 이상적입니다 |
| PDFsharp + MigraDoc | 기본적인 PDF 생성을 위한 무료 MIT 라이선스 라이브러리를 원하지만 디지털 서명이나 최신 암호화 알고리즘이 필요하지 않은 경우에 적합합니다 | 오픈소스 프로젝트 또는 예산 제약이 있는 프로젝트에서 간단한 문서 작성 |
| QuestPDF | 편집, 서명 또는 암호화 기능이 필요 없고 PDF 생성만을 위한 최신 레이아웃 엔진이 필요할 때 적합합니다 | MIT 라이선스 또는 저렴한 상업용 라이선스로 고품질 PDF를 생성할 수 있으며, 단 생성 기능 이외의 모든 기능은 다른 곳에서 처리해야 합니다 |
| iText | PDF 생성 및 처리를 위한 완성도 높고 기능이 풍부한 PDF 툴킷이 필요하고, AGPL/GPLv3 라이선스 하에 솔루션을 오픈소스로 공개하거나 고가의 상용 라이선스를 구매할 의향이 있다면 이 툴킷이 적합합니다 | 이미 iText API에 익숙한 팀들은 해당 API의 가파른 학습 곡선으로 인한 영향을 받지 않습니다 |
상세 비교
표를 검토하여 더 넓은 맥락을 이해하고 스스로 결론을 내리십시오.
| Docotic.Pdf (Layout 포함) | PDFsharp + MigraDoc | QuestPDF | iText | |
|---|---|---|---|---|
| PDF 기능 | 모든 기능을 갖춘 PDF 라이브러리 | PDF 생성 및 제한적 편집 | PDF 생성 전용 | 다양한 PDF 기능 |
| 모델 렌더링 | 현대적이고 선언적이며 유지 모드 레이아웃 엔진 | 박스 기반 레이아웃 엔진 | 현대적이고 선언적이며 유지 모드 레이아웃 엔진 | 박스 기반 레이아웃 엔진 + 렌더러 트리 |
| API 종류 | 플루언트 API | 명령형 API | 플루언트 API | 명령형 API |
| 개발자 경험 | 훌륭합니다. API는 깔끔하고 현대적이며 직관적입니다 | 좋습니다. API 설계는 관례적입니다 | 훌륭합니다. API는 깔끔하고 현대적이며 직관적입니다 | 만족스럽습니다. API가 장황하고 지나치게 복잡합니다 |
| 글꼴 부분집합 | 지원됨; 기본적으로 사용되는 글리프만 포함됩니다 | 지원되지 않습니다. 불필요하게 큰 PDF 파일이 생성될 수 있습니다 | 지원됨; 기본적으로 사용되는 글리프만 포함됩니다 | 지원됨; 기본적으로 사용되는 글리프만 포함됩니다 |
| 오른쪽에서 왼쪽으로(RTL) 읽는 방향 | 지원됨 | 지원되지 않음 | 지원됨 | 지원됨 |
| 디지털 서명 | LTV 및 외부 서명을 포함한 지원됨 | 지원되지 않음 | 지원되지 않음 | LTV 및 외부 서명을 포함한 모든 기능이 지원됩니다 |
| 암호화/권한 | 완벽하게 지원됨 | RC4 암호화만 지원하며, AES 또는 인증서는 지원하지 않습니다 | 지원되지 않음 | 전폭적인 지원 |
| 외부 종속성 | 없음 | 없음 | SkiaSharp / Skia 기반 구성 요소 | 없음 |
| 지원하다 | 잠재 고객 및 기존 고객을 위한 전문적인 지원; 최고급 라이선스에 대한 우선 지원 | 커뮤니티 지원이 제공되며, 전문가 지원은 별도로 구매하실 수 있습니다 | GitHub를 통한 커뮤니티 지원 | AGPL 버전은 커뮤니티 지원, 상업용 라이선스 소지자는 전문가 지원을 제공합니다 |
| 특허 | 적격 사용 사례에 한해 무료 라이선스를 사용하여 상업적으로 사용할 수 있습니다 | MIT | 개인 및 소규모 기업을 위한 MIT 프로그램이며, 대기업의 경우 상업용 라이선스가 필요합니다 | 오픈소스 사용에는 AGPL이 적용되고, 독점 프로젝트에는 고가의 상업용 라이선스가 적용됩니다 |
| 개발자 라이선스 | 모든 라이선스를 보유한 무제한 개발자 | 모든 라이선스를 보유한 무제한 개발자 | MIT 플랜은 개발자 무제한, Professional 플랜은 개발자 10명, Enterprise 플랜은 개발자 무제한 이용 가능 | AGPL 버전은 개발자 수에 제한이 없으며, 상업용 라이선스는 개발자별 라이선스 방식으로 제공됩니다 |
결론
Docotic.Pdf는 Layout 애드온과 함께 C# 및 VB.NET 환경에서 최신 고성능 고품질 PDF 생성 솔루션을 제공합니다. 이 라이브러리는 보고서, 명세서, 송장 등 다양한 문서를 생성할 수 있으며, 직관적이고 사용하기 쉬운 API를 통해 탁월한 개발자 경험을 제공합니다. Bit Miracle은 Docotic.Pdf 및 애드온에 대한 전문적인 지원을 제공합니다.
다른 PDF 생성 솔루션과 달리 Docotic.Pdf는 모든 기능을 갖춘 PDF API입니다. 생성된 PDF에 디지털 서명(LTV 서명 포함)을 추가할 수 있으며, USB 토큰이나 스마트 카드와 같은 보안하드웨어에 저장된 인증서를 사용할 수 있습니다. 또한 Microsoft Azure Key Vault 및 AWS Key Management Service(KMS)와 같은 클라우드 기반 HSM(하드웨어 보안 모듈)도 지원합니다.
Docotic.Pdf를 사용하면 생성된 PDF에 스프레드시트나 음성 메모와 같은 보조 문서를 첨부할 수 있습니다. 웹 페이지나 유사한 인터페이스에 문서를 표시하려면 문서의 하나 이상의 페이지에서 썸네일 이미지를 만들 수 있습니다.
다음 단계:
- 레이아웃 API의 코드 샘플을 살펴보세요.
- 구성 가능한 빌딩 블록을 사용한 PDF 생성 방식과 다른 PDF 생성 방식을 비교해 보세요.
- 질문, 의견 또는 예외 상황이 있으면 문의하기를 이용하세요.