Office가 설치되지 않은 환경에서 Delphi 또는 C++Builder를 사용하여 Excel 워크시트를 PDF로 내보내려면 HotXLS 워크시트 또는 통합 문서(Workbook)에서 SaveAsPDF를 호출하십시오. HotXLS는 네이티브 VCL Excel 컴포넌트이며, 워크시트-PDF 내보내기 기능은 시트의 사용된 범위(Used range)를 독립형 PDF 1.4 파일로 렌더링하고 Excel 열 너비와 셀 표시 텍스트를 A4 페이지에 매핑하여 자동으로 다중 페이지 페이지 매김을 수행합니다. 이 렌더링 과정에는 Excel 프로그램, 프린터 드라이버 및 외부 DLL이 전혀 개입하지 않습니다
HotXLS는 PDF를 픽셀 단위로 완벽하게 렌더링하는 이미지 엔진이 아닌, CSV, TSV 및 HTML 내보내기 경로의 동반자인 데이터 프레젠테이션 포맷으로 취급합니다. 즉, 내보내기 시 그리드에서 확인되는 데이터 값, 열 비율, 셀 주변의 격자선 등 표 형식의 내용과 레이아웃을 충실히 재현합니다. 이러한 관점은 사전의 현실적인 기대치를 설정하는 데 유용하며, 이 문서의 나머지 부분은 바로 그 한계선이 어디인지 명확하게 설명합니다
Office 없이 Delphi에서 Excel을 PDF로 어떻게 변환하나요?
가장 간단한 방법은 단 한 번의 호출입니다. TXLSWorksheet는 SaveAsPDF(FileName) 및 SaveAsPDF(Stream)을 노출하며, TXLSWorkbook은 활성 시트로 요청을 전달하는 동일한 두 가지 오버로드를 노출합니다. 각각 성공 시 1, 실패 시 -1인 Integer 값을 반환하므로, 사용자 코드에서 번거로운 예외 처리(Exception handling) 구조를 짜지 않고도 반환 값에 따라 깔끔하게 분기 처리를 수행할 수 있습니다
uses
lxHandle;
var
Book: TXLSWorkbook;
begin
Book := TXLSWorkbook.Create;
try
Book.Open('sales-june.xlsx');
// 활성 시트의 사용된 범위를 report.pdf 파일로 즉시 렌더링합니다.
if Book.SaveAsPDF('report.pdf') = 1 then
Writeln('PDF written');
finally
Book.Free;
end;
end;
워크시트에서 SaveAsPDF를 호출하면 HotXLS는 해당 시트에서 데이터가 존재하는 모든 셀들의 바운딩 박스 영역인 UsedRange를 내보냅니다. 통합 문서 오버로드는 단지 활성 시트로 요청을 위임해 주는 편의 기능이므로, 다중 시트 보고서의 경우 필요한 시트들을 루프(Loop)로 돌리거나 호출 전 활성 시트를 선택해야 합니다. 모든 탭을 한 번에 병합하여 단일 PDF 파일로 출력하는 '통합 문서 전체 내보내기' 모드는 지원하지 않으며, 각 호출은 하나의 시트 또는 지정한 하나의 범위를 렌더링합니다
HotXLS가 사용된 범위를 어떻게 PDF 페이지로 변환하나요?
HotXLS는 사용된 범위를 셀 단위로 순회하여 페이지가 구분되는 그리드로 배치합니다. 열의 기하학적 형태는 Excel 구조를 직접 투영합니다: 각 열 너비가 Excel 너비 단위에서 인쇄 단위인 포인트(Point)로 정밀 변환되며, 최소 하한값(Floor)이 기입되어 열 너비가 아예 0으로 짜부라지는 현상을 예방합니다. 열들의 총합 너비가 사용 가능한 페이지 폭보다 넓으면 HotXLS는 이들을 동일 비율로 전체 축소하여 폭에 맞춥니다. 반대로 폭이 페이지 내에 이미 안착하는 경우 억지로 강제 배율을 높여 늘리는 대신 원래 지정된 열 너비를 유지합니다
행들은 아래 방향으로 순차적으로 배치되다가 하단 여백 한계선을 넘기 직전 자동으로 다음 페이지로 페이지 구분 처리되므로, 개발자가 페이지 바운딩 계산을 일일이 하지 않고도 1,000행에 달하는 대용량 시트가 안전하게 자동으로 페이징 정산됩니다. 모든 셀은 숫자 포맷이 정밀 적용된 최종 텍스트 형태인 FormattedText를 출력하므로 날짜 서식이나 천 단위 쉼표, 화폐 통화 기호 등이 Excel 화면과 동일한 형식으로 온전히 인쇄됩니다. 셀 너비를 초과하여 길게 적힌 텍스트는 이웃 셀을 덮어쓰는 대신 셀 크기에 맞춰 깔끔하게 클리핑(Clipped) 처리됩니다
인쇄 방향, 여백 및 글꼴 크기 제어
기본 레이아웃 외에 정밀한 설정이 필요하다면 내보내기 개체를 직접 제어하십시오. TXLSPDFExport는 단일 행 편의 함수 이면에서 실 구동을 담당하는 클래스이며, 세 가지 핵심 프로퍼티를 노출합니다: Orientation(기본값은 세로인 xlsPdfPortrait이며, 가로 방향의 xlsPdfLandscape도 제공), Margin(포인트 단위, 기본값 40), FontSize(포인트 단위, 기본값 9). SaveAsPDF를 실행하기 전 이 프로퍼티들을 지정하면 문서 전체에 일괄 적용됩니다
uses
lxHandle, lxPDF;
var
Book: TXLSWorkbook;
Exporter: TXLSPDFExport;
begin
Book := TXLSWorkbook.Create;
try
Book.Open('wide-ledger.xlsx');
Exporter := TXLSPDFExport.Create;
try
Exporter.Orientation := xlsPdfLandscape; // 가로가 넓은 시트를 페이지 폭에 맞춥니다
Exporter.Margin := 28; // 포인트 단위의 더 좁은 페이지 여백
Exporter.FontSize := 8; // 더 조밀한 행 간격
Exporter.SaveAsPDF(Book.ActiveSheet, 'ledger.pdf');
finally
Exporter.Free;
end;
finally
Book.Free;
end;
end;
또한 TXLSPDFExport는 SaveAsPDF(Range: IXLSRange; ...)를 통해 워크시트 전체가 아닌 특정 셀 범위를 타겟으로 삼을 수 있습니다. 이는 시트 내에 각종 임시 계산용 잔여 데이터들이 복잡하게 얽혀 있을 때 순수 최종 요약 블록만 깔끔하게 파일로 인쇄해 내는 데 유용합니다. 이 범위 지정 오버로드는 시트 편의 헬퍼가 내부적으로 호출하는 것과 동일한 구조이므로, 사용 영역 전체를 넘기든 일부분만 지정하든 동일하게 정확한 레이아웃 배율과 페이징 처리가 작동합니다
var
Book: TXLSWorkbook;
Exporter: TXLSPDFExport;
Summary: IXLSRange;
begin
Book := TXLSWorkbook.Create;
try
Book.Open('quarter.xlsx');
// 옆의 임시 계산용 열들을 제외하고 순수 요약 블록만 내보냅니다.
Summary := Book.Sheets[1].Range['A1', 'F20'];
Exporter := TXLSPDFExport.Create;
try
Exporter.SaveAsPDF(Summary, 'summary.pdf');
finally
Exporter.Free;
end;
finally
Book.Free;
end;
end;
왜 HotXLS는 글꼴을 문서에 임베딩하지 않나요: Helvetica와 WinAnsi의 트레이드오프
HotXLS는 PDF 표준에 사전 정의된 내장 Helvetica 글꼴 및 WinAnsiEncoding 규격을 따르는데, 이는 외부 의존성을 없애기 위한(Zero-dependency) 설계상의 선택이지만 동시에 물리적인 성능 한계점도 지닙니다. Helvetica는 모든 표준 PDF 리더 프로그램에 기본 내장되어 탑재되는 14대 표준 폰트에 해당하므로, 내보내기 모듈은 파일 내에 무거운 글꼴 파일 데이터 자체를 임베딩하지 않습니다: 이 덕분에 출력 파일 크기가 매우 컴팩트하고 라이선스 분쟁이나 부속 폰트 배포 오류가 차단됩니다. 다만 이 선택으로 인해 페이지에 표현할 수 있는 문자 코드 영역에 한계가 가해집니다
WinAnsiEncoding은 Windows-1252 문자 셋 범위에 준하므로, 라틴 문자, 일반적인 구두점 및 표준 서유럽 액센트 기호들이 정상 렌더링되며, HotXLS는 몇몇 타이포그래피 문자, 곡선 따옴표, en/em 대시 및 유로화 기호 등을 해당 CP1252 영역에 맞춰 처리해 냅니다. 그러나 이 영역을 초과하는 문자군, 즉 한글/한자/일어(CJK) 문자, 키릴 문자, 그리스 문자 및 아랍 문자 등은 인쇄 페이지 상에서 물음표(?) 기호로 치환되어 깨지게 됩니다. 워크시트가 한글 등 비라틴계 폰트 영역을 주로 취급한다면 본 간이 내보내기 모듈은 부적합하며, 본격적인 글꼴 인코딩을 제어하는 전문 PDF 렌더링 엔진을 활용해야 합니다
워크시트-PDF 내보내기 기능의 한계 구역
HotXLS는 시트의 상세한 비주얼 서식이 아닌 핵심 데이터 구조와 정산 레이아웃을 렌더링합니다. 셀 채우기 색상, 세세한 테두리 선 종류, 셀마다 다른 폰트 글꼴 및 개별 폰트 색상, 내장 차트 및 그래픽 이미지 등은 렌더링 적용 대상에서 제외되며, 획일적인 얇은 실선 테두리로 둘러싸인 정형 텍스트 그리드를 결과물로 획득하게 됩니다. 이는 HTML 및 RTF 내보내기 엔진과 동일한 기능 규격이며, 디자인 테마가 아닌 기입된 데이터의 정보 가치가 핵심인 정형 보고서나 장부 정산 결과물을 백엔드에서 신속하게 저장해 내는 데 최적화된 설계입니다
디자인 일관성 및 브랜딩 서식이 강력하게 요구되는 문서를 생성해야 한다면, 대개 정교하게 사전에 다듬어진 스프레딧 템플릿 파일 상에 수치를 붓는 패턴이 정석이며, 이는 템플릿 기반 보고서 생성 워크플로우 가이드에서 상세하게 소개합니다. 또한 이 모든 과정에 COM 라이브러리나 런타임 Excel 프로세스가 일절 개입하지 않으므로, 백엔드 서버에 라이선스 설치나 성능 저하 요인 없이 바로 배포할 수 있는 HotXLS 공통의 무의존성 자동화 아키텍처를 고스란히 계승합니다
바이트 단위로 정확히 계산되는 독립형 PDF 파일 구조
HotXLS는 저수준 단에서 PDF의 물리 파일 구조를 직접 조립하며 크로스 레퍼런스(Cross-reference) 테이블을 바이트 단위의 정확한 오프셋 주소로 연산합니다. 이 덕분에 생성된 결과물이 모든 리더 프로그램에서 표준 위반 에러 없이 깨끗하게 열립니다. 엔진은 개별 PDF 개체들을 직렬화하여 출력 파일 스트림에 쓸 때마다, 각 개체의 시작 바이트 오프셋 주소를 사전에 기록하고 바이트 기입량만큼 인덱스 포인터를 정밀 갱신하여, 파일 후미의 xref 테이블이 개체 시작점을 정확히 저격하고 startxref가 해당 테이블의 개시 주소를 명확하게 지시하도록 조율합니다. 이 오프셋 주소 중 단 1바이트만 어긋나도 PDF 표준 규격에 위배되어 리더기에서 파싱 실패 처리를 유도하므로, 스트림 오프셋에 대한 바이트 단위의 수학적 연산은 이 내보내기 엔진의 신뢰성을 지탱하는 뼈대와 같습니다
이 물리 규칙으로 인해 반드시 준수해야 하는 제어 시퀀스 제약이 발생합니다. 페이지 목록을 관리하는 Pages 노드는 항상 파일 서두의 1번 개체로 기록되어야 하지만, 파일 끝까지 렌더링이 완료되기 전에는 하위 페이지의 총 개수를 미리 확정할 수 없습니다. 따라서 HotXLS는 이 영역을 플레이스홀더(Placeholder) 상태로 우선 확보해 둔 뒤 전체 연산이 끝나는 마지막 단계에 비중 값을 역추적하여 덮어쓰고, 이후 오프셋 테이블 계산에 돌입하여 정밀 주소를 도출합니다. 오프셋이 한번 획정되어 xref에 대입되는 순간 개체 데이터의 크기는 물리적으로 빙결되어야 합니다: 주소 계산 완료 후 단 1바이트만 밀려나도 후속 오프셋 주소들이 도미노처럼 망가져 파일 테이블 전체가 깨지기 때문입니다. 이 세밀한 연산 통제 규율 덕분에 외부 PDF 라이브러리 탑재 없이도 완벽한 표준 규격의 PDF 1.4 파일을 생성할 수 있습니다
여기에 소개된 SaveAsPDF 메서드 및 TXLSPDFExport 클래스는 CSV, HTML 및 RTF 내보내기 모듈과 함께 Delphi 및 C++Builder용 표준 HotXLS Delphi Excel 컴포넌트와 함께 제공됩니다