HotXLS læser og skriver Excel Binary Workbook (XLSB)-filer fra Delphi gennem samme TXLSXWorkbook-facade som bruges til XLSX: Open opdager en binær arbejdsbog ud fra pakkens indhold, og SaveAs eller SaveAsChecked med xlsxExcelBinaryWorkbook skriver én. Backend'en dækker et valideret subset og afviser alt, den ikke kan repræsentere, før destinationen røres
Netop den sidste klausul er delen, der er værd at læse langsomt. XLSB ligner en simpel variation af XLSX, og i pakke-termer er den det. Problemet bor i detaljerne, som de to formater koder forskelligt, og i, hvad et bibliotek stille antager, når det broer det ene ind i det andet. Den mest lærerige bug i denne backend var slet ikke en misdannet record. Det var en standardfont, der forsvandt, og en datokolonne, der blev til #### i Excel, selvom værdien, formatkoden og kolonnebredden alle var korrekte
Hvad er en XLSB-fil, og hvordan adskiller den sig fra XLSX?
En XLSB-fil er en OPC-pakke med præcis XLSX-arbejdsbogens part-struktur, men workbook-, worksheet-, style- og shared-string-parts gemmer binære records i stedet for XML. Formatet er specificeret i [MS-XLSB], og record-kodningen kaldes ofte BIFF12. Man får stadig [Content_Types].xml, relationship-parts og en ZIP-container; det, der ændrer sig, er, at xl/workbook.bin erstatter xl/workbook.xml, xl/worksheets/sheet1.bin erstatter worksheet-XML'en og så videre
Hver BIFF12-record starter med en kompakt header med variabel længde. Record-typen tager én eller to bytes, syv bits pr. byte med den høje bit som fortsættelsesflag, så en record-type er i 14 bits. Payload-størrelsen følger i én til fire bytes med samme syv-bit-skema. Strenge er et 32-bit tegnantal efterfulgt af UTF-16 code units. Sammenlignet med BIFF8 er det et meget renere layout: ingen 8224-byte CONTINUE-splitning, ingen compressed-versus-wide strengflags midt i en record. Sammenlignet med XLSX springer den XML-tokenisering helt over, hvilket er derfor, store XLSB-filer har tendens til at være mindre på disken og hurtigere for Excel at åbne
Én pakkedetalje vælter detektionskode. Excel registrerer XLSB-workbook-part'en med content type application/vnd.ms-excel.sheet.binary.macroEnabled.main, selv for arbejdsbøger uden makroer. HotXLS tjekker den registrering i [Content_Types].xml først og falder kun tilbage på .bin-part-udvidelsen, når content typen mangler, og begge veje skal stadig bestå den strenge record-validator. De generelle regler om part-navne, relationships og content types er de samme, der er dækket i hvorfor Excel reparerer en gyldig XLSX, og OPC-pakkereglerne bag
Hvornår bør man vælge XLSB frem for XLSX?
Vælg XLSB, når et downstream-system kræver det, eller når man udveksler store værditunge arbejdsbøger med Excel-brugere, der bryder sig om åbningstid; ellers forbliver XLSX det sikrere standardvalg. XLSX er en ISO-standard (ISO/IEC 29500) med bred værktøjs-understøttelse, den kan inspiceres med et ZIP-værktøj og en teksteditor, og alle regnearksprodukter læser den. XLSB er et Microsoft-format med en publiceret specifikation men et smallere økosystem
I praksis kommer anmodningerne fra to retninger. Nogle rapporteringspipelines og arkiver standardiserede på .xlsb for år siden og afviser alt andet. Andre teams genererer arbejdsbøger med hundredtusindvis af numeriske celler og fandt, at brugere åbner den binære version mærkbart hurtigere. Begge er legitime grunde. "Det lyder mere effektivt" er ikke, for HotXLS' binære backend stagerner hele pakken i hukommelsen, så det er ikke værktøjet til server-eksporter med afgrænset hukommelse. Til dem er streaming XLSX-writeren den rigtige vej
Åbning og gemning af XLSB med TXLSXWorkbook
TXLSXWorkbook.Open behøver intet format-hint: samme kald indlæser XLSX, XLSM eller XLSB, og efter en vellykket binær indlæsning rapporterer TXLSXWorkbook.SourceFormat xlsxExcelBinaryWorkbook. Skrivning er eksplicit. SaveAs(FileName) uden format frembringer altid en Open XML-arbejdsbog, selv når filnavnet slutter på .xlsb, så binært output navngiver altid formatet
uses
SysUtils, lxHandleX;
procedure ConvertToXlsb(const Source, Target: string);
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
// Open opdager XLSX, XLSM eller XLSB fra pakken selv
if Book.Open(Source) <> 1 then
raise Exception.Create('Input is unsupported or invalid');
// Udvidelsen alene vælger aldrig binært output
if Book.SaveAsChecked(Target, xlsxExcelBinaryWorkbook) <> 1 then
raise Exception.Create('XLSB output is unsupported or failed');
finally
Book.Free;
end;
end;
Stream-output går gennem SaveAs(Stream, xlsxExcelBinaryWorkbook) eller stream-overloaden af SaveAsChecked. Internt router begge til de private SaveAsXlsbStream- og SaveAsXlsbFile-metoder; man kalder dem aldrig direkte. Fil-output stagernes ind i en søskende midlertidig fil og commit'es med én endelig erstatning. En stream-destination skal være læsbar og søgbar, for writeren tager snapshot af dens bytes, størrelse og position og gendanner dem, hvis den endelige kopiering fejler. TXLSXWorkbook.LastSaveUsedStreaming rapporterer False efter en binær gem, hvilket er korrekt: hele pakken findes i hukommelsen, før en eneste byte når destinationen
Hvorfor et valideret subset i stedet for fuld trofasthed?
HotXLS vedligeholder ikke en anden objektmodel til XLSB. Ved åbning konverterer XlsbToOpenXml den binære pakke til en in-memory Open XML-pakke, og den almindelige XML-parser indlæser den; ved gem bygger XML-writeren en pakke, og OpenXmlToXlsb koder den som binære records. Hver funktion skal derfor overleve to oversættelser, og en funktion, broen ikke kan oversætte præcist, afvises frem for at approksimeres
Det understøttede sæt pr. HotXLS 2.384.113 er bredt nok til de fleste dataarbejdsbøger: typede værdier, shared og inline strenge, almindelige fonte, fills, kanter og talformater, række-højder og kolonnebredder, almindelige celleformler med cachede resultater, defined names, flettede celler, hyperlinks, frosne og splittede ruder, AutoFilter-områder med simple brugerdefinerede kriterier og almindelige regnearks-tabeller. Uden for ligger shared og array-formler, future- og brugerdefinerede funktioner, eksterne arbejdsbogs-referencer, diagrammer og tegninger, PivotTables og slicers, VBA, betinget formatering, datavalidering og ikke-standard beregningsindstillinger som manuel beregning eller iteration
Afvisning er obligatorisk, ikke vejledende. TXLSXWorkbook.GetConversionReport(xlsConversionExcelBinaryWorkbook) lister ikke-understøttede funktioner, før man gemmer, og de poster fikser gemen, selv med AAllowLossy = True eller en utjekket SaveAs. Det er bevidst. Stille at droppe en PivotTable fra en binær kopi er den slags tab, ingen bemærker, før arbejdsbogen står foran en kunde
uses
Classes, lxHandleX, lxDiagnostics;
function CanSaveAsXlsb(Book: TXLSXWorkbook; Log: TStrings): Boolean;
var
Report: TXLSConversionReport;
I: Integer;
begin
Report := Book.GetConversionReport(xlsConversionExcelBinaryWorkbook);
try
Result := True;
for I := 0 to Report.Count - 1 do
if Report[I].Fidelity = xlsConversionUnsupported then
begin
Result := False;
Log.Add(Report[I].SheetName + ' ' + Report[I].Location + ': ' +
Report[I].Feature + ' - ' + Report[I].Message);
end;
finally
Report.Free; // kalderen ejer rapporten
end;
end;
Rapporten dækker den levende model. Endelig pakkevalidering er stadig den sidste gate for ting, modellen aldrig ser, som misdannede records eller ukendte attributter i source-filen, så en ren rapport efterfulgt af en fejlet gem er mulig, og gem-resultatet er det, man handler på
Hvorfor forsvandt standardfonten og 0.00-formatet?
Standardfonten og de indbyggede talformater forsvandt, fordi XML style-readeren lavede to antagelser, der holder for filer, HotXLS selv skriver, men ikke for arbejdsbøger, Excel skriver. Broen bevarede begge ressourcer perfekt; tabet skete ét lag oppe, i den offentlige Open-vej. Det hul er denne backends hovedlektie: en korrekt formatbro garanterer ikke en trofast offentlig round trip
Den første antagelse drejede sig om fonts[0]. Når HotXLS gemmer XLSX, skriver den en implicit standardfont ind i slot nul, og dens XML-reader springer den slot over, så den brugerrettede Fonts-samling starter ved indeks nul. En Excel-forfattet XLSB bærer sin egen eksplicitte standard i den slot, og at springe den over kastede det valg væk. Den anden antagelse drejede sig om talformater. Readeren mappede kun brugerdefinerede numFmtId-værdier (164 og opefter) ind i NumberFormats; indbyggede id'er forblev nul. En stylet blank celle med indbygget format 2, som er 0.00, kom tilbage som General
Fixet bor helt i den binære importvej. Efter hele pakken består preflight, sætter XLSB-åbningen en privat style-mode kun for den synkrone XML-parsing. I den mode indlæser readeren hver font inklusive slot nul og forskubber hver fontId med én, konverterer hvert understøttet indbygget id til en eksplicit formatkode i modellen og bruger stadig det oprindelige numFmtId til datodetektering, så et indbygget datoformat beholder sin datosemantik. En finally-blok rydder altid moden, og en senere almindelig XLSX- eller ODS Open rydder også den fastholdte standardfont-tilstand
Hvordan påvirker fonts[0] Excel-kolonnebredder?
Excel beregner kolonnebredder ud fra arbejdsbogens standardfont i fonts[0], ikke ud fra fontene anvendt på cellerne i den kolonne. Kolonne-width gemmes i tegnenheder af standardfontens maksimale cifferbredde, så at ændre fonts[0] ændrer pixel-bredden af hver kolonne, inklusive kolonner, hvis celler alle bruger en anden font
Det frembragte det mest forvirrende symptom på hele undersøgelsen. Den gen-gemte arbejdsbog havde identiske celleværdier, identiske formatkoder og identiske width-attributter, cellefonten og Normal-stylen pegede begge på den bevarede font, og Excel renderede stadig en datokolonne som ####. Den skrevne fonts[0] var vendt tilbage til Calibri 11, den maksimale cifferbredde skrumpede, og datoerne passede ikke længere. HotXLS beholder nu source-standardfonten og skriver den tilbage som fonts[0] og falder kun tilbage på Calibri 11 for arbejdsbøger, der aldrig havde en binær source. Hele bredde-aritmetikken er i Excel-kolonnebredde og max digit width (MDW) i Delphi
Lokale-afhængige indbyggede formater afvises, ikke gættes
Et indbygget talformat-id uden eksplicit formatkode accepteres kun, når dets betydning er fast; locale-afhængige id'er afvises under pakke-preflight. HotXLS mapper id'er 0 til 22, 37 til 40 og 45 til 49 til kendte koder som 0.00, 0%, mm:ss og @. De resterende id'er under 164 tilhører formater, hvis rendering afhænger af Excel-installationens regionale indstillinger, og importen nægter dem med beskeden "A locale-dependent number format requires an explicit format code"
At finde på en kode til de id'er ville være værre end at fejle. Et gættet østasiatisk datomønster ligner noget, round-tripper uden fejl og viser det forkerte for halvdelen af ens brugere. Timing betyder også noget: tjekket kører i hele-pakken-preflight, før den eksisterende arbejdsbog ryddes, så en afvist fil lader den tidligere indlæste model, filnavn og source-format urørt. Excel date serial- og numFmt-artiklen dækker, hvordan indbyggede dato-id'er interagerer med 1900- og 1904-datosystemerne
procedure LoadBinaryWorkbook(Book: TXLSXWorkbook; const FileName: string);
var
I: Integer;
begin
// Binært input behøver ivrig fuld indlæsning; selektive modes afviser på forhånd
Book.MetadataOnly := False;
Book.SelectedSheets.Clear;
if Book.Open(FileName) <> 1 then
begin
for I := 0 to Book.Diagnostics.Count - 1 do
Writeln(Book.Diagnostics[I].Message);
Exit; // den tidligere indlæste arbejdsbog er stadig intakt
end;
// Formel-output behøver en cache, medmindre gemmet genberegner
Book.RecalcBeforeSave := xrmAlways;
end;
Praktiske regler for XLSB i produktionskode
Den binære backend er sikker at stole på, når man behandler dens afvisninger som data frem for som fejl at undertrykke. Et par regler følger af adfærden ovenfor
- Navngiv formatet ved hver binær gem;
.xlsb-udvidelsen alene frembringer stadig XLSX - Kør
GetConversionReport(xlsConversionExcelBinaryWorkbook)før gem af brugerredigerede arbejdsbøger og bring de ikke-understøttede funktioner frem for brugeren - Lad
MetadataOnlyvære fra ogSelectedSheetstom for binært input, da lazy loading ville kræve at fastholde et konverteret arkiv - Giv formler et cached resultat eller genberegn før gem, for en manglende cache afvises under
xrmManualog under en renxrmIfDirty - Budgetter hukommelse til den komplette konverterede pakke plus det binære output; brug streaming XLSX, når hukommelsen skal forblive afgrænset
Når man tester, så sammenlign med Excel gennem den offentlige API frem for på broniveau. Standardfont- og 0.00-regressionerne bestod begge bro-tests, og begge viste sig straks i en Excel-forfattet arbejdsbog åbnet og gen-gemt gennem Open og SaveAsChecked
FAQ
Opdager HotXLS XLSB-filer automatisk?
Ja. TXLSXWorkbook.Open inspicerer content typen registreret for workbook-part'en og validerer de binære records, så samme kald indlæser XLSX og XLSB, og SourceFormat rapporterer, hvilken der blev læst
Hvorfor skriver SaveAs med et .xlsb-filnavn stadig XLSX?
HotXLS udleder aldrig output-formatet fra udvidelsen. Giv xlsxExcelBinaryWorkbook til SaveAs eller SaveAsChecked for at skrive en binær arbejdsbog
Hvad sker der, når en arbejdsbog bruger funktioner uden for XLSB-subsettet?
Gemen fejler, før destinationen ændres, selv med lossy gem tilladt. GetConversionReport lister de blokerende funktioner på forhånd, og Diagnostics forklarer fejlen bagefter
XLSB-understøttelse, konverteringsrapporten og resten af arbejdsbogs-API'et følger med i HotXLS, den native Delphi- og C++Builder regnearkskomponent