스프레드시트는 정체성의 층을 둘 지니고 있습니다. 셀 격자가 있고, 그 곁을 함께 타고 가는 문서 메타데이터가 있습니다. 제목, 작성자, 회사, 키워드, 시각 기록입니다. Excel은 그 두 번째 층을 격자에 결코 보여 주지 않지만, Windows 검색이 색인하는 층이 그것이고, SharePoint가 문서 제목을 붙이려고 읽는 층이 그것이며, 기록 관리 시스템이 분류 기준으로 삼는 층이 그것입니다. 생성된 통합 문서가 자기가 지어져 나온 템플릿에서 Author와 Title을 물려받으면, 하류의 모든 시스템이 고객 명세서 사천 장의 작성자로 템플릿 설계자를 기록합니다. 그 메타데이터는 어디에서도 옳지 않은데 어디에서나 참조됩니다
HotXLS는 이 층을 두 엔진 모두에서 평범한 통합 문서 수준 속성으로 드러냅니다. .xls를 위한 BIFF 파사드와 .xlsx를 위한 OOXML 파사드입니다. 파일을 연 뒤에 필드를 읽고, 저장하기 전에 필드를 씁니다. 값이 어느 물리적 컨테이너에 떨어질지는 라이브러리가 정합니다. 생성기를 쓰기 전에 알아 둘 값어치가 있는 것은 각 형식이 실제로 어느 필드를 지원하는지, 그 필드가 물리적으로 어디에 사는지, 그리고 .xlsx가 메타데이터를 하나라도 기록할지를 지배하는 하나의 관문 규칙입니다
두 형식, 두 저장 모델
스프레드시트 라이브러리가 메타데이터 구현을 둘 필요로 하는 이유, 그리고 절반만 만들어진 도구가 한 형식은 제대로 찍고 다른 형식은 잊어버리는 이유는, .xls와 .xlsx가 속성을 서로 무관한 자리에 간직하기 때문입니다. BIFF 통합 문서는 속성을 OLE 복합 파일 스트림에 쓰는데, 주로 Excel 자체보다 오래된 SummaryInformation 속성 집합이며, 파일을 마지막으로 저장한 사람의 이름을 담는 스트림 안 WRITEACCESS 레코드가 그 곁에 있습니다. OOXML 통합 문서는 속성을 zip 패키지 안의 XML 파트로 간직하며 목적에 따라 나눕니다. ECMA-376 Part 1에 따라 docProps/core.xml이 Dublin Core 필드(제목, 작성자, 주제, 키워드, 날짜)를 담고 docProps/app.xml이 회사와 생성 응용 프로그램 같은 응용 프로그램 수준 필드를 담습니다
HotXLS는 그 두 저장 모델을 통합 문서 객체의 직접 속성으로 납작하게 폅니다. 속성 집합 스트림을 열거나 XML 파트를 손으로 고칠 일이 결코 없습니다. 통합 문서에 문자열과 날짜를 대입하면, 어느 형식으로 저장하든 그에 맞는 컨테이너가 실체로 나타납니다
업무 기록에서 가져와 생성된 통합 문서에 찍기
XLSX 쪽에서 TXLSXWorkbook은 Title, Subject, Author, Keywords, Description, Category, LastModifiedBy, Company, Application, AppVersion을 문자열로 드러내고, 여기에 0이 설정되지 않음을 뜻하는 TDateTime 값 Created와 Modified가 더해집니다. 상속의 구멍을 막는 규칙은 한 문장입니다. 실행할 때마다 모든 필드를 대입하되, 템플릿이 어쩌다 지니고 있던 것을 믿는 대신 업무 기록에서 값을 가져오십시오
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
if Book.Open('statement-template.xlsx') <> 1 then
raise Exception.Create('Template not available');
// 모든 필드를 덮어씁니다. 손대지 않고 남긴 것은 무엇이든
// 템플릿을 설계한 사람에게서 물려받습니다.
Book.Title := 'Account Statement 2026-06 / ACME Corp';
Book.Subject := 'Monthly account statement';
Book.Author := 'Billing Service 4.2';
Book.LastModifiedBy := 'Billing Service 4.2';
Book.Company := 'Northwind Financial';
Book.Category := 'Customer Delivery';
Book.Keywords := 'statement;billing;2026-06;acct-10024';
Book.Description := 'Generated document - manual edits are not retained';
Book.Created := Now;
Book.Modified := Now;
Book.SaveAs('statement-10024.xlsx');
finally
Book.Free;
end;
end;
Keywords 필드는 보통 받는 것보다 더 많은 생각에 보답합니다. 검색 기반 시설이 그것을 글자 그대로 색인하는데 Windows 검색도, SharePoint도, 대부분의 DMS 제품도 그렇습니다. 그래서 계좌 번호와 기간을 담은 세미콜론 구분 관례 하나면 전달된 모든 통합 문서가 데이터베이스를 오가지 않고도 찾을 수 있는 기록이 됩니다. 바로 그 도달 범위가 함정이기도 합니다. 속성은 파일의 모든 사본을 따라다니며 그것을 쓴 시스템의 접근 통제를 한참 넘어서 가므로, 개인 정보는 거기에 속하지 않습니다
시각 기록 짝은 습관에 맡기지 말고 정책으로 못박아 둘 만한 의미를 지닙니다. Created는 여러분의 파이프라인이 문서를 생성한 순간을 표시하고 그대로 얼어붙어 있어야 합니다. Modified는 받는 사람이 파일을 저장할 때마다 Excel이 갱신하는 필드이므로, 전달 뒤에 둘이 벌어져 있다는 것은 하류의 누군가가 통합 문서를 고쳤다는 적극적 증거이고, 전달된 스프레드시트가 정말 누구의 숫자를 담고 있는지를 둘러싼 다툼을 여럿 정리해 줍니다. 함정 하나가 설정되지 않은 상태에 숨어 있습니다. 그것은 예외도 null도 아닌 글자 그대로의 값 0이므로, 감사 코드는 0을 명시적으로 검사해야 합니다. 그 방어 없이 설정되지 않은 TDateTime을 서식화하면 로그가 자신만만하게 틀린 1899년 12월 날짜로 채워집니다
DocPropsTouched: docProps 없이 출하되는 통합 문서
읽기 전용 플래그인 DocPropsTouched가 XLSX 속성 기록기의 관문입니다. 속성이 한 번도 대입되지 않은 통합 문서는 docProps 파트를 전혀 만들어 내지 않습니다. HotXLS는 빈 메타데이터 뼈대를 쓰기를 사양합니다. 그 동작은 깔끔하고, 설계에 반영할 값어치가 있는 결과가 둘 딸려 옵니다
소비하는 쪽의 접수 코드는 모든 패키지에 core.xml이 있으리라고 가정해서는 안 됩니다. 그것을 굳게 요구하는 도구는 완벽하게 유효한 최소 파일을 거부하게 됩니다. 그리고 여러분의 준수 태세가 나가는 모든 문서에 최소한 생성기 신원은 담기라고 요구한다면, 그 요구는 형식의 성질이 아니라 코드가 됩니다. 저장 경로에서 Application과 Author를 조건 없이 대입하십시오. 손대지 않은 통합 문서는 명세상 완전히 합법이면서 여러분의 정책은 조용히 어기기 때문입니다
예전 XLS 표면과 Comments 함정
BIFF 파사드는 더 오래되고 더 작은 필드 집합을 지니고 있습니다. Title, Subject, Author, Keywords, Comments, Company, Manager에, UserName의 별칭인 LastSavedBy가 더해지는데, 이것은 다른 사용자가 파일을 잠갔을 때 Excel이 보여 주는 WRITEACCESS 레코드를 씁니다
var
Legacy: IXLSWorkbook; // 참조 계수 인터페이스: 수동 Free 불필요
begin
Legacy := TXLSWorkbook.Create;
if Legacy.Open('archive-1999.xls') <= 0 then
raise Exception.Create('Cannot open archive file');
Legacy.Title := 'FY1999 ledger (migrated copy)';
Legacy.Author := 'Archive Migration Batch';
Legacy.Company := 'Northwind Financial';
Legacy.Comments := 'Migrated 2026-06-11; source retained in cold storage';
Legacy.LastSavedBy := 'migration-svc'; // BIFF WRITEACCESS 레코드
Legacy.SaveAs('archive-1999-stamped.xls');
end;
이름 충돌 하나가 되풀이되는 혼란을 부릅니다. 여기서 문서 수준 Comments 속성은 파일의 속성 대화 상자에 보이는 자유 텍스트 비고입니다. 완전히 별개의 API로 범위에 붙는 그리기 계층 객체인 셀 메모와는 아무 상관이 없습니다. 어느 쪽을 뜻하는지 확인하지 않고 "우리는 이미 Comments를 쓴다"를 받아들이는 코드 검토는 엉뚱한 기능에 대한 주장을 받아들인 것이고, 그런 일은 이름이 같다는 사실이 시사하는 것보다 더 자주 일어납니다. 둘은 네 글자를 나누어 가질 뿐 저장소는 한 바이트도 나누지 않습니다
접수 시점에 메타데이터 읽기, 그리고 탐색의 빈틈
읽기는 대칭입니다. Open 뒤에는 같은 속성이 파일에서 채워진 채로 돌아오므로, 들어오는 통합 문서의 메타데이터 감사가 짧은 루프가 됩니다
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
if Book.Open(FileName) = 1 then
begin
Writeln(Format('%s | title="%s" author="%s" created=%s',
[ExtractFileName(FileName), Book.Title, Book.Author,
FormatDateTime('yyyy-mm-dd', Book.Created)]));
if Book.Created = 0 then
Writeln(' no creation date recorded');
end;
finally
Book.Free;
end;
end;
그러면서 한 가지 한계를 감안해 계획하십시오. 속성만 보는 탐색기는 없습니다. GetSheetNames는 통합 문서를 적재하지 않고 시트를 나열할 수 있지만, Title이나 Author를 읽으려면 온전한 Open이 필요하므로, 큰 보관소를 가로지르는 메타데이터 분류는 파일마다 전체 구문 분석 비용을 치릅니다. BIFF 쪽에서는 읽기 전용 감사에 한해 열기 전에 _DisableGraphics를 true로 두어 그 비용을 깎을 수 있는데, 그리기 계층을 대놓고 건너뜁니다. 속성과 셀 통계만 읽는 루프에는 들어맞고, 같은 인스턴스가 저장할 수도 있는 순간 정확히 틀린 선택이 됩니다. 건너뛴 그리기 내용이 떨어져 나가기 때문입니다. 시트 구조만으로 대상을 미리 걸러 낼 수 있을 때, 단일 시트 내보내기가 건너뛰기에 뻔한 예인데, 시트 나열과 가벼운 검사를 다룬 글의 값싼 기법이 비싼 단계에 닿는 파일 수를 줄여 줍니다. 그리고 수천 개 출력을 검사하는 것이 아니라 써 내는 대량 찍기 작업에서는, 배치 작업을 위한 스트리밍 쓰기 글의 쓰기 쪽 처리량 패턴이 그대로 옮겨 옵니다. 속성 대입은 저장 시간에 잴 만한 것을 아무것도 더하지 않기 때문입니다
형식을 건너기와 새는 것 막기
속성은 하나의 파사드 안에서는 말끔히 왕복합니다. .xlsx를 열고 고치고 저장하면 그 집합이 온전히 돌아옵니다. 형식을 건널 때 동등하리라는 가정이 깨지는데, BIFF와 OOXML의 필드 집합이 하나씩 맞아떨어지지 않기 때문입니다. BIFF에는 Manager가 있고 시각 기록이 없습니다. OOXML에는 Category, Description, 그리고 Created/Modified 짝이 있습니다. 눈감고 복사하는 변환기는 목적지 형식이 담을 수 없는 것을 무엇이든 잃으므로, 필드를 명시적으로 대응시키고 그 대응표를 여행을 견디지 못하는 다른 모든 것 곁에 변환 점검표로 두십시오
템플릿 상속이 열어 놓는 누출은 반대 방향으로 흐릅니다. 내보낼 뜻이 전혀 없던 정보 말입니다. 작성자 이름, 키워드에 세워 둔 내부 프로젝트 표시, 아무도 승인하지 않은 초안 제목 같은 것들입니다. 위 생성기의 전부 덮어쓰기 규율이 방어의 전부이고, 바깥 사람이 하듯 확인해 볼 값어치가 있습니다. 어느 고객이든 열 수 있는 속성 대화 상자를 열어 보거나, .xlsx의 압축을 풀어 패키지에서 docProps/core.xml을 곧장 읽어 보면 됩니다. 거기서 보이는 것이 바로 하류의 모든 색인기가 보는 것입니다
그 하류 가시성은 몇몇 필드가 나머지보다 더 큰 정성을 벌어들이는 이유이기도 합니다. Title, Author, Keywords(Tags로 나타납니다), 그리고 Comments나 Description이 SharePoint와 Windows 검색에서 색인 무게의 대부분을 집니다. 기간과 계좌를 담아 문서마다 정말로 구별되는 Title 하나가, 그 위에 겹겹이 쌓은 어떤 폴더 이름 규칙보다 찾기 쉬움에 더 크게 이바지하고, 저장마다 대입 한 번의 값이 듭니다
문서 속성은 생성된 통합 문서가 지닐 수 있는 가장 값싼 전문가다운 마감이면서, 아무도 그것을 맡지 않을 때 가장 흔히 출하되는 결함입니다. 여기서 설명한 두 속성 표면 모두 HotXLS Delphi Component에 속하며, Excel 자동화 없이 XLS와 XLSX 양쪽에 네이티브로 그것을 씁니다