워크시트 설정 중 세 가지 항목군은 셀 값 자체와는 아무런 관련이 없지만, 파일이 코드 단을 벗어난 뒤의 동작 양상을 결정하는 매우 중요한 요소입니다. 시트 보호(Sheet protection)는 통합 문서를 전달받은 사용자가 편집할 수 있는 셀을 통제합니다. 페이지 설정(Page setup)은 용지 방향, 규격 및 여백을 결정합니다. 인쇄 설정(반복 인쇄 행, 인쇄 배율 및 수동 페이지 구분선)은 임의의 길이를 갖는 그리드가 종이에 인쇄되는 구조를 제어합니다. 이 세 가지는 일반 뷰어에서 단순 데이터만 볼 때는 감지되지 않으며, 잘못 구성되었을 때 실무 현장에서 조용히 레이아웃을 깨뜨리곤 합니다. Delphi 및 C++Builder용 네이티브 스프레드시트 라이브러리인 HotXLS는 .xls 및 .xlsx 포맷 전반에 걸쳐 이들의 제어 스펙을 노출하며, Excel 고유의 다소 직관적이지 않은 세세한 연동 규칙들까지도 완벽하게 지원합니다
이러한 특이 사항 중 첫 번째는 개발자가 생성된 시트를 처음 보호하려고 시도할 때 흔히 마주치는 함정입니다. 단순히 Protect를 호출하면, 심혈을 기울여 구성한 입력 영역을 포함하여 모든 셀의 편집 권한이 일제히 차단됩니다. 코드 수준에서 해당 열에 손을 대지 않았음에도 이런 현상이 발생하는 확실한 원인이 존재합니다
모든 셀은 기본적으로 잠금(Locked) 상태로 태어납니다
ECMA-376 표준은 잠금(locked) 설정을 시트 보호 자체의 속성이 아닌 개별 셀의 서식 레코드(Formatting record)의 일부로 규정하며 기본값은 true입니다. 시트 보호는 단지 잠금 플래그를 강제 활성화시키는 온/오프 스위치에 불과합니다. 따라서 전체 그리드는 생성되는 시점부터 잠금 플래그를 잠재적으로 보유하게 되며, Protect를 호출하는 순간 일제히 작동하게 됩니다. 이를 해결하는 정석은 연산 순서를 올바르게 잡는 것입니다: 레이아웃을 먼저 구축하고, 사용자가 입력해야 하는 범위를 명시적으로 잠금 해제(Unlock)한 뒤, 마지막에 시트를 보호하는 단계로 처리하십시오
Book := TXLSXWorkbook.Create;
try
Sheet := Book.Sheets.Add('Timesheet');
// ... 헤더 행, name 열 및 요율 수식이 여기에 작성됩니다 ...
Sheet.Range['B2:B50'].SetLocked(False); // 직원이 근무 시간을 기입할 영역
Sheet.Range['F2:F50'].SetFormulaHidden(True); // 요율 연산 수식을 비공개로 유지
Sheet.Protect('review-2026'); // 이제 잠금 플래그가 물리적으로 적용됩니다
Book.SaveAs('timesheet.xlsx');
finally
Book.Free;
end;
SetFormulaHidden은 자칫 간과하기 쉽지만 고유한 유용한 기능을 수행합니다: 시트 보호가 활성화되어 있는 동안, 셀에는 연산된 결과값이 정상 노출되지만 수식 입력줄(Formula bar)에는 수식 내용이 표시되지 않고 빈칸으로 유지됩니다. That 가치있는 점은 수식이 총량 셀을 클릭하는 수신자에게 청구 요율, 마진 폭 또는 가중치 계산 공식을 직접 노출하고 싶지 않을 때 필수적입니다. XLS 엔진에서도 동일한 제어 방식이 개별 범위 상의 IXLSRange.Locked 및 FormulaHidden 프로퍼티를 통해 제공됩니다. 또한 시트 상에 15가지의 Allow* 플래그(AllowSort, AllowAutoFilter, AllowFormatCells 등)가 탑재되어 있어, 보호 상태의 시트에서도 사용자가 필터링이나 정렬 기능을 정상 활용할 수 있도록 지원합니다
시트 보호 비밀번호의 실제 보안 수준
두 포맷 모두 시트 및 통합 문서 보호 비밀번호를 4자리 16진수 형태의 레거시 해시(Hash) 값으로 저장합니다. 16비트 정밀도 수준이므로 비밀번호 해제 툴이나 충돌 값을 찾아내는 로직이 널리 공유되어 있습니다. 따라서 시트 보호는 무단 수정이나 데이터 유실을 방지하는 안전벨트로 인식해야지, 강력한 정보 권한 통제 수단으로 오인해서는 안 됩니다. 이는 검토자가 실수로 요약 수식 셀을 지우는 현상을 차단하는 최적의 수단이지만, 대외비 성격의 데이터를 숨기기 위한 보안 수단으로는 부적절합니다
한 단계 상위 수준에서, XLSX 엔진의 ProtectWorkbook은 통합 문서의 구조를 잠금 설정하여 시트의 생성, 이름 변경, 삭제 및 순서 재조정 행위를 차단합니다. 시트 목록의 이름이나 순서가 파일 수신 측의 파싱 프로그램과 직결된 구조일 때 이를 적용하십시오. 시트명이 임의로 변경되면 피참조 열이 삭제되는 것만큼이나 데이터 정산 연산 오류를 쉽게 유발합니다. XLS 엔진 역시 통합 문서 수준의 TXLSWorkbook.Protect 및 개별 시트 단위의 Protect 호출 구조를 투영하고 있으며, 레거시 파일을 수정하기 전 보안 설정을 사전에 검사할 수 있도록 isProtected 프로퍼티도 함께 제공합니다
실제 데이터 기밀성을 지켜야 하는 강력한 요구 사항이 있다면 보안 메커니즘을 완전히 전환해야 합니다. SaveAsEncrypted는 AES 암호화 XLSX 출력 가이드에서 상세히 다루는 ECMA-376 표준 암호화 규격에 따른 AES 암호화 패키지를 생성하며, 레거시 XLS 엔진은 EncryptionPassword 및 Open의 비밀번호 오버로드를 통해 RC4 암호화된 .xls 파일을 읽고 씁니다. 이 차이는 매우 실무적입니다. 단순히 시트만 보호된 파일은 기입 데이터가 평문(Cleartext) 상태로 노출되어 압축 해제 툴로 셀 데이터 수치가 쉽게 파악되지만, 암호화된 패키지는 암호를 풀지 못하면 데이터 자체에 접근할 수 없습니다. 보안 감사 지침상의 '급여 정보 파일은 반드시 보호되어야 한다'는 규정은 사용 명칭과 무관하게 대개 이 암호화(Encryption) 조치를 의미합니다
페이지 설정은 출력 계약서의 일부입니다
인쇄 레이아웃은 모니터 상에서는 식별되지 않으므로, 테스트 단계에서 무시된 채 유실되기 쉬운 대표적인 영역입니다. 실무 담당자가 문서를 실제로 종이로 출력하거나 감사용 PDF로 내보내는 순간, 여백, 배율 및 인쇄 타이틀 반복 지정 기능은 즉각적인 기능적 요구 사항으로 대두됩니다. XLSX 엔진의 경우 이 설정들은 시트 인스턴스로부터 바로 구성됩니다
Sheet.PageLandscape := True;
Sheet.PaperSize := xlsxPaperA4;
Sheet.SetPageMargins(0.5, 0.5, 0.75, 0.75, 0.3, 0.3);
Sheet.CenterHeader := 'Monthly Timesheet';
Sheet.RightFooter := 'Page &P of &N';
Sheet.PrintArea := '$A$1:$F$60'; // 순수 주소만 사용: 여기에 시트 접두사를 쓰지 마십시오
Sheet.PrintTitleRows := '$1:$1'; // 이 헤더 행이 모든 인쇄 페이지 상단에 반복됩니다
Sheet.FitToWidth := 1;
Sheet.FitToHeight := 0; // 데이터 분량 증가에 따라 아래 방향으로 자동 확장
Sheet.PrintGridlines := False;
위 설정 중 두 줄은 흔히 빠지는 함정을 품고 있습니다. 헤더 및 푸터 문자열은 Excel 표준 서식 코드를 따릅니다: 현재 페이지는 &P, 총 페이지 수는 &N을 사용하며, 좌측/중앙/우측 배치를 조율하기 위해 &L, &C, &R 기호도 제공됩니다. 또 다른 함정은 PrintArea로, 순수 셀 범위 주소만 전달받도록 사양이 작성되어 있습니다. HotXLS는 파일 출력 시 시트 접두사를 자동으로 보강하므로, 개발자가 'Timesheet!$A$1:$F$60' 형식으로 시트명을 중복 기입하면 규격에 어긋나는 비정상적인 주소가 생성됩니다. 저수준 단계에서도 주의가 필요합니다: 인쇄 영역과 인쇄 타이틀은 내부적으로 _xlnm.Print_Area 및 _xlnm.Print_Titles 이름 정의로 기록되므로, DefinedNames를 통해 _xlnm.* 이름 개체를 수동으로 생성하지 마십시오. 두 제어 메커니즘이 동일 슬롯을 차지하기 위해 충돌합니다
대량의 데이터 분량을 소화하는 배율 설정
FitToWidth := 1과 FitToHeight := 0의 조합은 '인쇄 폭은 항상 한 페이지 넓이에 맞추고, 높이는 데이터 분량에 맞춰 유연하게 아래 방향으로 무한 확장한다'는 뜻이며, 출력 행의 크기가 가변적인 모든 실무 보고서의 표준 인쇄 공식입니다. 30여 행 수준의 소규모 샘플로 인쇄 설정을 튜닝해 두면, 실제 운영 단계의 600여 행짜리 대형 파일을 기입했을 때 출력 글자 크기가 판독 불가 수준으로 작아지거나 표가 페이지 수십 장으로 어지럽게 잘려 출력되게 됩니다. 인쇄 폭을 고정하고 높이를 유연하게 설정하되, PrintTitleRows를 통해 헤더를 상시 노출하여 17페이지째 결과도 단독 판독할 수 있도록 구성하십시오
수동 페이지 구분선 지정(Page break) 역시 다른 연산들과 동일한 생성 시퀀스 규칙을 따릅니다. AddRowBreak(BeforeRow)는 구역 구분점 앞에 새 인쇄 페이지를 인위적으로 밀어 넣지만, 데이터 생성기가 재구동되어 행의 고정 주소가 밀려나면 이 수동 구분선이 엉뚱하게 표 중간을 자르고 들어오게 됩니다. 따라서 ClearAllPageBreaks를 먼저 호출해 기존 잔여 구분선들을 청소한 뒤, 이전 기록에 의존하는 대신 신규 데이터 크기에 맞춰 다시 기입하십시오. XLS 엔진에서도 Sheet.PageSetup(방향, 규격, 여백, 헤더/푸터 문자열, 페이지 맞춤) 프로퍼티 및 RepeatRows, RepeatColumns 등의 이름으로 관련 제어 기능이 동등하게 제공됩니다
최종 전달 전에 먼저 실행해 보는 셀프 검증
시트 보호 및 인쇄 레이아웃 버그는 수동으로 체크하기에 매우 단순하지만, 대개 검증 단계를 생략하여 고객 전달 후에나 발견되곤 합니다. 통합 문서 생성 완료 후 Excel로 열어 단 90초만 검증에 투자해 보십시오. 입력 셀에 값을 쳐서 기록되는지 확인하고, 수식 보호 셀에 입력할 때 정상적으로 보호 경고 문구가 뜨는지 체크하며, 수식 숨김 셀의 수식줄이 실제로 빈칸으로 남아 있는지 검증하십시오. 또한 30행 남짓의 샘플 대신 실 데이터 분량을 채운 상태에서 인쇄 미리보기(Print Preview)를 실행해 인쇄 페이지 수, 반복 헤더 배치 상태 및 푸터의 일련번호 등을 판독하십시오. 미리보기 작업은 모니터 상에서는 포착되지 않는 인쇄 배율 설정 등의 정밀 레이아웃 상태를 직접 실체화하여 체크해 주는 최상의 수단입니다
사용자 경험을 다듬는 한 가지 최종 설정을 확인해 보겠습니다. FreezePane(ACol, ARow)는 사용자가 큰 표를 스크롤할 때 상단 헤더 영역이 화면에서 유실되지 않도록 고정하는 틀 고정(Freeze pane) 기능입니다. 이는 인쇄 사양이 아닌 순수 화면 제어 기능이지만 보고서의 완성도를 획기적으로 높여 줍니다. 또한 디자이너가 사전에 튜닝해 둔 기본 서식을 재사용하는 템플릿 기반 보고서 생성 프로세스를 준수한다면 이 인쇄 레이아웃 사양들이 템플릿 파일 내에 이미 정교하게 보존되므로, 프로그램은 데이터를 붓고 시트 보호를 재적용하는 마감 연산에만 집중할 수 있습니다
HotXLS는 Delphi 및 C++Builder용 네이티브 Object Pascal 스프레드시트 라이브러리입니다; 시트 보호 및 인쇄 페이지 설정과 관련한 전체 API 레퍼런스는 HotXLS 컴포넌트 제품 상세 페이지에서 제공됩니다