🧩.xlsm · .xlsb · .xltx

Alle drei sind ZIP-Pakete wie die .xlsx – sie unterscheiden sich im Content-Type des Hauptteils und darin, was im Paket liegen darf.

🧾Der Unterschied steht in [Content_Types].xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
<Default Extension="xml" ContentType="application/xml"/>
<Default Extension="bin" ContentType="application/vnd.ms-office.vbaProject"/>
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.ms-excel.sheet.macroEnabled.main+xml"/>
<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
<Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
</Types>

Gelb: Zeilen, die sich gegenüber der normalen .xlsx unterscheiden. Die Dateiendung allein reicht nicht – Excel prüft den Content-Type des Hauptteils.

📗.xlsx
Normale Arbeitsmappe, darf keinen VBA-Code enthalten.
⚙️.xlsm
Arbeitsmappe mit Makros (vbaProject.bin).
📐.xltx / .xltm
Vorlage ohne/mit Makros; beim Öffnen per Doppelklick entsteht eine neue, unbenannte Mappe.
🧱.xlsb
Binär-Arbeitsmappe: gleiche Paketidee, aber BIFF12-Records statt XML; Makros möglich.

📚 Quelle: ECMA-376 Teil 1 §18 und Teil 2; [MS-OFFMACRO] (makrofähige Office-Dateien, vbaProject-Beziehung); [MS-XLSB] (Paketteile); geprüfte Content-Types siehe Tests.

⚙️.xlsm – Makros in vbaProject.bin


 umsatz.xlsm  (ZIP)
 ├─ [Content_Types].xml        Hauptteil: application/vnd.ms-excel.sheet.macroEnabled.main+xml
 ├─ xl/workbook.xml
 ├─ xl/_rels/workbook.xml.rels
 │    └─ Type=".../office/2006/relationships/vbaProject"  Target="vbaProject.bin"
 └─ xl/vbaProject.bin          ◄── wieder ein Compound File (D0 CF 11 E0 …)!
      ├─ PROJECT, PROJECTwm     Projekteigenschaften (Text)
      └─ VBA/
         ├─ dir                 Modulverzeichnis (komprimiert)
         ├─ _VBA_PROJECT        Versions-/P-Code-Infos
         └─ Modul1, DieseArbeitsmappe …  Quelltext (MS-OVBA-komprimiert) + P-Code
⚠️ Makros sind Code
VBA kann Dateien schreiben und Programme starten. Microsoft 365 blockiert Makros in Dateien aus dem Internet (Mark of the Web) seit 2022 standardmäßig. Vor dem Öffnen fremder Dateien lohnt ein Blick mit olevba umsatz.xlsm (oletools) – es entpackt den Quelltext, ohne ihn auszuführen.
💡 Bei .xls liegt VBA im selben Compound File
In einer alten .xls steckt das Projekt in der Storage _VBA_PROJECT_CUR neben dem Stream „Workbook“. In .xlsm wurde genau dieses Compound File als vbaProject.bin ins ZIP gelegt.

📚 Quelle: [MS-OVBA] (VBA-Projektstruktur, Kompression); [MS-XLS] (Storage _VBA_PROJECT_CUR); oletools-Dokumentation (olevba).

🧱.xlsb – BIFF12, Records mit variabler Länge

Die Binär-Arbeitsmappe nutzt die ZIP-Struktur der .xlsx, speichert die Teile aber als kompakte Records. Typ und Größe sind variabel lang kodiert: 7 Nutzbit pro Byte, das oberste Bit heißt „es geht weiter“.

 umsatz.xlsb  (ZIP – gleiche Paketstruktur wie .xlsx)
 ├─ [Content_Types].xml        Hauptteil: application/vnd.ms-excel.sheet.binary.macroEnabled.main
 ├─ xl/workbook.bin            BrtBeginBook … BrtBundleSh (Blätter) … BrtEndBook
 ├─ xl/worksheets/sheet1.bin   BrtBeginSheet · BrtWsDim · BrtBeginSheetData · BrtRowHdr · BrtCell… · …
 ├─ xl/sharedStrings.bin       BrtBeginSst · BrtSSTItem… · BrtEndSst
 └─ xl/styles.bin
Record-Kopf mit variabler Länge
TypFD11111101hohes Bit 1 → es folgt ein Byte · 7 Bit = 125
Typ0400000100hohes Bit 0 → letztes Byte · 7 Bit = 4 × 128^1
GrößeC811001000hohes Bit 1 → es folgt ein Byte · 7 Bit = 72
Größe0100000001hohes Bit 0 → letztes Byte · 7 Bit = 1 × 128^1

Kopf: FD 04 C8 01 (4 Byte). Zum Vergleich BIFF8: immer genau 4 Byte, Länge höchstens 8224.

xl/worksheets/sheet1.bin – Record für Record
Schritt 1 / 11 · Tasten ← →
000081010094011000000000010000000000
001000000100000091010000190000000000
00200000002C010000000100000000000000
003001000000070C00000000000000000000
0040000005100100000000000000F6285C8F
0050C2F51340001901000000000000002C01
006000000001000000000000000100000007
00700C000000000000000001000000051001
0080000000000000009A9999999999294092
00900100820100
BrtBeginSheet

Typ 129 (81 01) · Größe 0 (00)

Klammer-Record ohne Daten

Zellen-Records tragen nur die Spalte – die Zeile kommt aus dem vorangehenden BrtRowHdr. Texte liegen wie bei .xlsx in einer Shared String Table (xl/sharedStrings.bin).

⚡Warum .xlsb?
Große Tabellen laden und speichern schneller, die Dateien sind oft kleiner – kein XML-Parsen nötig.
🔒Nachteil
Nicht mit einem Texteditor lesbar; viele Bibliotheken (z. B. openpyxl) können .xlsb nicht lesen. In Python hilft pyxlsb.
📏BIFF8 vs. BIFF12
BIFF8: Kopf immer 4 Byte, Zeile 16 Bit. BIFF12: Kopf 2–6 Byte, Zeile und Spalte je 32 Bit – genug für 1 048 576 × 16 384.

📚 Quelle: [MS-XLSB] 2.1.4 Record (Kodierung von Typ und Größe, Beispiel BrtCommentText 637/200), 2.3 Record Enumeration, BrtRowHdr, Struktur Cell.