Excel ブック(xlsx)ファイル形式
Office Open XML 形式の Microsoft Excel ブック。
- MIME タイプ
- application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
- 拡張子
- .xlsx
- カテゴリ
- ドキュメント
マジックナンバー(ファイル署名)
| 0x00000000 | 504B0304 | PK·· | 'PK' — it is a ZIP |
ZIP 内に '[Content_Types].xml' と 'xl/' ディレクトリがあります。
Excel ブック(xlsx)形式について
.xlsx は Open Packaging Conventions のパッケージ(XML パーツを詰めた ZIP)を表形式データ向けに並べたものです。セルは xl/worksheets/sheet1.xml などにありますが、文字列の多くはそこにいません。繰り返し現れるテキストは xl/sharedStrings.xml にプールされ、インデックスで参照されます。同じラベルが 10 万行並んだブックがほぼ無に等しいサイズまで縮むのはこの仕組みのおかげです。スタイルも同じように xl/styles.xml にプールされます。ファイルの先頭バイトにはこれが表計算であることを示すものは何もなく、判別できるのは ZIP ディレクトリのエントリ名だけです。
ヘッダーの構造(バイト単位)
| オフセット | 長さ | フィールド | 意味 |
|---|---|---|---|
| 0 | 4 | Local file header signature | 50 4B 03 04、ZIP のローカルファイルヘッダです。ブックも Word 文書もスライドも電子書籍も Android パッケージも、このオフセットでは区別が付きません。この形式は独自の署名ではなく、ZIP の上に載せたコンテナの取り決めだからです。 |
| 4 | 2 | Version needed to extract | 必要な読み取り側の最小バージョンを 10 倍した値、リトルエンディアン。deflate なら 20 です。パーツが 65535 個を超えるブックや 4 GiB を超えるブックは ZIP64 の 45 になりますが、それが起きるのは巨大なメディアを埋め込んだときくらいです。 |
| 6 | 2 | General purpose bit flag | ビット 3 は CRC とサイズを圧縮データの後ろの data descriptor へ移します。ストリーミングで書く実装の挙動です。ビット 11 はエントリ名が UTF-8 であることを宣言します。ワークシートのパーツ名は ASCII でも、埋め込みメディアのファイル名はそうとは限らないので、これは意味を持ちます。 |
| 8 | 2 | Compression method | XML パーツはすべて 8(deflate)。表計算の XML は OOXML 一族の中で最もよく縮む中身で、数値セルのシートは冗長なマークアップが平然と 10 分の 1 以下になります。 |
| 10 | 2 | Last modified time | MS-DOS のパック形式の時刻で、分解能 2 秒、タイムゾーンなし。Excel はパーツのタイムスタンプを正規化するので、ブックの本当の編集履歴はここではなく docProps/core.xml にあります。 |
| 12 | 2 | Last modified date | MS-DOS のパック形式の日付で、1980 年起点。ブック自身の日付システム(1900 年、オプションで 1904 年からの日数)と並べて覚えておく価値があります。無関係な 2 つの起点が同じファイルに同居しているわけです。 |
| 14 | 4 | CRC-32 | このパーツの非圧縮バイト列のチェックサム。Excel は読み込み時にこれを検証するので、転送中に壊れたブックは中途半端に開いて数字が狂うのではなく、きちんと失敗します。 |
| 18 | 4 | Compressed size | このパーツの deflate バイト数。FF FF FF FF なら ZIP64 の extra field に委ねますが、それが必要なほど大きいブックはたいてい別のところで既に間違えています。 |
| 22 | 4 | Uncompressed size | パーツの元の長さ。この値と圧縮後サイズの差こそ、共有文字列の設計が効いている場所です。プールされたテーブルは格納サイズの何倍にも膨らみます。 |
| 26 | 2 | File name length | OOXML の書き手はどれも [Content_Types].xml を先頭に置くので、そのときは 13 00(19 バイト)になります。ファイルの実際の種類について何かを語る最初のフィールドです。 |
| 28 | 2 | Extra field length | Excel が書いたものなら通常はゼロ。スクリプトで再パックしたブックは Unix のパーミッションやタイムスタンプの extra field を拾いがちで、機能は何も変わりませんがファイルのハッシュは変わります。 |
| 30 | 19 | First entry name | [Content_Types].xml。その中の Override 要素が /xl/workbook.xml を spreadsheetml.sheet で終わるコンテンツタイプに対応づけていて、この文字列こそが「このパッケージは文書でもプレゼンでもなくブックである」という正式な宣言です。 |
| variable | variable | xl/workbook.xml | このパッケージを表計算にしているパーツです。オフセットは固定ではないのでセントラルディレクトリ経由で探します。各シートとそのリレーションシップ id を列挙しており、id は xl/_rels/workbook.xml.rels 経由で実体の xl/worksheets/sheetN.xml に解決されます。 |
| -22 | 4 | End of central directory signature | 50 4B 05 06。アーカイブコメントが無ければ末尾から 22 バイトの位置です。ブックのシートを列挙するのに必要なものはすべてここから辿ります。つまり最後の 22 バイトのほうが最初の 30 バイトより重要だということです。 |
| -6 | 4 | Offset of the central directory | ディレクトリの開始位置を、ファイル先頭からの絶対位置で示します。パッケージの前に何バイトか足されるとこの値は無効になり、Excel は本当のオフセットを探しに行かず、読めないファイルだと宣言します。 |
似た形式との見分け方
| 紛らわしい形式 | 見分け方 |
|---|---|
| Word 文書(docx) | ローカルファイルヘッダの全フィールドが同一で、オフセット 30 も同一です。どちらのパッケージも [Content_Types].xml で始まるからです。分かれ目はファイル末尾のディレクトリ一覧で、ブックなら xl/workbook.xml と xl/ ツリー、文書なら word/document.xml と word/ ツリー。拡張子を読むのは代わりになりません。Excel はバイトが言うとおりのものを開きます。 |
| xls | 前の世代であり、まったく別物です。D0 CF 11 E0 A1 B1 1A E1 で始まる Compound File Binary コンテナで、中に 'Workbook' という名前のストリームを持ちます。どちらも Excel で開き、どちらも「Excel のファイル」と呼ばれますが、行と列の上限がまるで違います。バイナリ形式は 65536 × 256、.xlsx は 1048576 × 16384。世界の大半が変換した実務上の理由がこれです。 |
| csv | 現場では絶えず混同されますが、バイトレベルでは一度も似ていません。CSV は署名を一切持たないプレーンテキスト、.xlsx は ZIP です。痛い違いは意味のほうにあります。CSV が運ぶのは値だけ、ブックが運ぶのは値に加えて数式・型・書式・複数シート。だから「CSV でエクスポート」はファイルの大半を捨てる操作で、「CSV を Excel で開く」は元々なかった型を勝手にでっち上げる操作です。 |
| xlsm | マクロ有効のブックで、ヘッダを通して .xlsx とバイト単位で同一です。違いは xl/vbaProject.bin パーツがあることと、宣言されたコンテンツタイプが異なることだけ。目に見える違いが拡張子しかなく、リネームは無料なので、メールフィルタはパッケージを開かないとどちらか判定できません。 |
よくある壊れ方
- end-of-central-directory レコードが失われている。ダウンロードが途中で切れても各ワークシートのパーツは無傷で正しく圧縮されたまま残りますが、それでも Excel は開こうとしません。列挙が末尾から始まるからです。50 4B 03 04 を前方に拾ってディレクトリを組み直せば、たいていすべてのシートが戻ります。
- パッケージの前にバイトが付いた。50 4B 03 04 の前にプロキシのエラーページや余計な BOM が入るとファイル全体がずれ、セントラルディレクトリの絶対オフセットがその分だけ狂います。ブックは丸ごと存在しているので、前のゴミを削れば元に戻ります。
- テキストモード転送。deflate ストリーム内の改行変換はヘッダもエントリ名もサイズも綺麗に残すので、パッケージは正しく一覧でき、シートを展開する段になって CRC で落ちます。事前に気づける手掛かりは ZIP の構造の中にありません。
- 手で編集したパーツを誤って再パックした。シートがただの XML なので直接いじりたくなりますが、XML 宣言の前に BOM を入れる、エントリ名の大小文字を変える、フォルダのディレクトリエントリを含める。どれをやってもアーカイブツールは健全と言い、Excel は拒否します。
- xl/sharedStrings.xml が壊れている。セルのテキストはプールされてインデックスで参照されるので、このパーツ 1 つの破損はセル 1 つを空にするのではなく、ブック中の文字列インデックスをまとめてずらします。結果、正しい数値に間違ったラベルが付いたシートが開きます。この形式が抱える障害の中で、最も人を誤らせるものです。
この形式の現在地
.xlsx は、多少なりとも構造のある表データを受け渡す事実上の共通形式です。その普及は技術というよりビジネス上の事実で、財務も業務も行政もこれで公開するから、あらゆるデータツールが読めるようにするしかありません。技術的にも、この用途としては悪くない形式です。公開された ISO 標準で、圧縮が効き、パーツが XML なので復旧しやすく、大量エクスポートを不可能にしていた .xls の行数制限もありません。一方でデータ処理用の形式としては貧弱です。パースには展開して数 MB の XML を流し込む必要があり、日付は 1900 年起点の連番で(しかも Lotus 由来のうるう年バグをわざと残したまま)、桁の多い数値 ID は黙って浮動小数点に丸められて指数表記に化けます。分析用途なら、単純な受け渡しは CSV、規模が要るなら Parquet のほうがよく、読み込み速度は桁違いです。.xlsx が本当に第一候補なのは、人が開いて編集する成果物のときです。数式も複数シートも書式もグラフも生き残りますが、CSV ではどれも残りません。
Excel ブック(xlsx)ファイルをこのサイトで開く
どれもブラウザ内で動きます。ファイルが端末から出ることはありません。
関連する形式
Excel ブック(xlsx)と混同しやすい形式です。先頭バイトを見比べてください。
| 形式 | 先頭バイト | 拡張子 |
|---|---|---|
| Word 文書(docx) | 50 4B 03 04 | .docx |
| PowerPoint プレゼン(pptx) | 50 4B 03 04 | .pptx |
| ZIP | 50 4B 03 04 | .zip |
| OLE2 / CFB | D0 CF 11 E0 A1 B1 | .doc |