■はじめに
こんにちは。
株式会社iimonでエンジニアをしている「白水(しらみず)」です。
弊社では、主にChromeExtensionを開発しています。
Extensionを使って「CSV」や「Excel」ファイルを出力することが多々あります。各ファイルの特徴について、知らないことが多かったので調べてみました。
また、最近ではExcelファイルでセルに色をつけたり、列や行を固定したいなどExcelファイルの構造を知っている必要がある要望もあったため、この機会に調べてみました。
■CSVファイルについて
◆CSVファイルとは?
CSVファイルとは、「Comma Separated Values(カンマ セパレーティド ヴァリューズ)」の略で、各項目がカンマ(,)で区切られたテキストデータのことです。
CSVファイルはデータの容量が軽く、互換性があるのでExcelやメモ帳、エディタで開く事ができます。
◆CSVファイルの中身を確認してみる
Googleスプレッドシートを開いて、ファイルをCSVで保存するとCSVファイルを取得できます。
cat sample.csv
catコマンドで、csvファイルを開いてみると、行ごとにカンマで区切ってデータ形式を表現していることがわかります。
金額で用いられるカンマ(,)などが含まれる場合は、ダブルクォート(")で囲む必要があります。
プログラムでCSVファイルを作る場合は、文字列をカンマで区切って、行ごとに改行すればファイルが作れるシンプルな形式です。
◆CSVファイルの特徴
●メリット
テキストファイル
CSVはプレーンテキスト形式なので、様々なソフトウェア(Excel、Googleスプレッドシート、テキストエディタなど)で開くことができます。
カンマで区切る
各データ(セルの値)がカンマ(,)で区切られています。例えば、「名前,年齢,住所」といった形式です。
拡張子 .csv
ファイル名の末尾に「.csv」が付きます。
互換性が高い
さまざまなアプリケーションやプログラミング言語で読み書きが容易です。
軽量
余計な書式情報が無く、純粋なデータだけを記録するためファイルサイズが小さくなります。
●デメリット
装飾・数式・グラフなどを保持できない
セルの色やフォント、数式、グラフ、画像など、表現力のある情報は保存できず、データ(値)のみが保存されます。
複雑なデータ構造には不向き
複数シートに渡る表など、複雑な情報は格納できません。
カンマや改行など特殊文字の扱いが面倒
データ中にカンマや改行がある場合は、ダブルクオーテーションで囲うなどの「エスケープ処理」が必要で、これを怠るとデータがずれてしまいやすいです。
■Excelファイルについて
◆Excelファイルとは?
Excel(.xlsx)は、国際標準の「Office Open XML」というデータ仕様で定義されている、国際的なオープンフォーマットです。
主な拡張子は「.xlsx」や「.xls」などがあり、データの分析・計算・グラフ作成など多機能なデータ管理が可能です。
◆Excelファイルの特徴
複数のシートに対応
1つのファイルに複数のワークシートを持たせることができます。
書式や装飾情報の保持
セルの色やフォント、罫線、コメント、セル結合などの装飾情報を保持できます。
数式・関数・グラフ・画像の保存
複雑な計算式や関数、グラフ、図形や画像なども格納・再編集可能です
XMLベース+ZIP圧縮
データはXML形式で保存され、全体をZIPで圧縮して保存が可能です。
◆Excelファイルを解凍してみる
Chromeのスプレッドシートで、セルに「文字列」「数値」「少数」のデータを持たせてみます。
また、「セルの色変更」「行の固定」「シートを2つ作成」してみます。
ファイル→ダウンロードから、xlsxファイルをダウンロードします。
$ unzip sample.xlsx -d sample-unzip Archive: sample.xlsx inflating: sample-unzip/xl/drawings/drawing1.xml inflating: sample-unzip/xl/drawings/drawing2.xml inflating: sample-unzip/xl/worksheets/sheet1.xml inflating: sample-unzip/xl/worksheets/_rels/sheet1.xml.rels inflating: sample-unzip/xl/worksheets/sheet2.xml inflating: sample-unzip/xl/worksheets/_rels/sheet2.xml.rels inflating: sample-unzip/xl/theme/theme1.xml inflating: sample-unzip/xl/sharedStrings.xml inflating: sample-unzip/xl/styles.xml inflating: sample-unzip/xl/workbook.xml inflating: sample-unzip/xl/_rels/workbook.xml.rels inflating: sample-unzip/_rels/.rels inflating: sample-unzip/[Content_Types].xml
先ほどダウンロードしたExcelファイルをunzipコマンドで解凍します。
そうすると、ExcelファイルはXMLファイルがZIP圧縮されているので、XMLファイルが複数取得できます。
sample-unzip/ ├── [Content_Types].xml ├── _rels └── xl ├── _rels │ └── workbook.xml.rels ├── drawings │ ├── drawing1.xml │ └── drawing2.xml ├── sharedStrings.xml ├── styles.xml ├── theme │ └── theme1.xml ├── workbook.xml └── worksheets ├── _rels │ ├── sheet1.xml.rels │ └── sheet2.xml.rels ├── sheet1.xml └── sheet2.xml 8 directories, 12 files
ディレクトリ構成としては、上のようになっています!
◆各ファイルの中身を確認してみる
●[Content_Types].xml
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> <Default ContentType="application/xml" Extension="xml"/> <Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/> <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" PartName="/xl/worksheets/sheet1.xml"/> <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" PartName="/xl/worksheets/sheet2.xml"/> <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml" PartName="/xl/sharedStrings.xml"/> <Override ContentType="application/vnd.openxmlformats-officedocument.drawing+xml" PartName="/xl/drawings/drawing1.xml"/> <Override ContentType="application/vnd.openxmlformats-officedocument.drawing+xml" PartName="/xl/drawings/drawing2.xml"/> <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" PartName="/xl/styles.xml"/> <Override ContentType="application/vnd.openxmlformats-officedocument.theme+xml" PartName="/xl/theme/theme1.xml"/> <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" PartName="/xl/workbook.xml"/> </Types>
[Content_Types].xml は、Excel(.xlsx)ファイルの中で「各ファイルの種類(ContentType)を定義する」ための構成ファイルです。
これは Open XML パッケージの仕様に従っており、ZIPの中にある各ファイルの MIMEタイプの一覧表 のような役割を果たします。
<Default ContentType="application/xml" Extension="xml"/> <Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/>
.xml → application/xml として扱います。
.rels → リレーションシップファイル(_rels/.relsなど)は特別なMIMEタイプとして扱います。
<Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" PartName="/xl/worksheets/sheet1.xml"/>
PartNameが/xl/worksheets/sheet1.xml
は、ワークシートでContentTypeはapplication/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml
(ワークシート用のXML)として扱います。
.xlsx 内の各ファイルは ZIP の中の単なる XML ファイルであり、見た目で意味が分からないです。
そのため どのファイルがどの種類なのかを明示する必要があります。
Excel やライブラリが .xml や .rels などを見て「これはワークシートだ」「これは文字列のデータだ」と認識できるようにしています。
●_rels/.rels
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/> </Relationships>
_rels/.rels ファイルの役割は、Open XML パッケージのエントリーポイント(開始点)を定義することです。
Excelを開くとき、まず _rels/.rels を見て、xl/workbook.xml が メインのワークブック だと分かります。
そこからシート情報(xl/worksheets/sheet1.xmlなど)にリンクが張られていく形になります。
●xl/workbook.xml
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mx="http://schemas.microsoft.com/office/mac/excel/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main"> <workbookPr/> <sheets> <sheet state="visible" name="シート1" sheetId="1" r:id="rId4"/> <sheet state="visible" name="シート2" sheetId="2" r:id="rId5"/> </sheets> <definedNames/> <calcPr/> </workbook>
xl/workbook.xml は .xlsx ファイル内のメインのワークブック構成ファイルです。
Excelファイル全体の「シートの定義」や「名前の定義」、全体の構成情報がここにまとまっています。
<sheet state="visible" name="シート1" sheetId="1" r:id="rId4"/> <sheet state="visible" name="シート2" sheetId="2" r:id="rId5"/>
属性 | 意味 |
---|---|
state="visible" | シートが表示状態(非表示なら hidden) |
name="シート1" | ユーザーが見るシート名 |
sheetId="1" | シートの一意な ID |
r:id="rId4" | xl/_rels/workbook.xml.rels ファイルで定義された XMLファイルとの関連付け ID(例:rId4 → xl/worksheets/sheet1.xml) |
●xl/_rels/workbook.xml.rels
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/> <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/> <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/> <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/> <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet2.xml"/> </Relationships>
xl/_rels/workbook.xml.rels は、Excel(.xlsx)ファイルの内部で workbook.xmlと他のリソース(シート、スタイル、テーマなど)との「つながり(関係)」を記述するファイルです。
workbook.xml.relsを参照することで、xl/workbook.xmlのr:id="rId4"は"worksheets/sheet1.xml"だとわかる。
さらに、worksheets/sheet1.xmlを作成するために必要なその他のパーツのファイルへのパスもきさいされています
●xl/sharedStrings.xml
すべてのシート中で共有利用される文字列リストを一括管理します。
例えばExcelで「あ、い、う、え」を書きましたが、それはsharedStrings.xmlで定義されます。
同じ文字は1回しか定義されないようになっています。
数値は、sharedStrings.xmlでは管理されません。
●xl/theme/theme1.xml
全体で共通して使うデザインルール(テーマカラー・テーマフォント)を定義するファイルです。
例えば、Excelで使うフォントを全体で共通なので、<a:fontScheme name="Sheets">で定義します。
●xl/styles.xml
<fonts count="2"> <font> <sz val="10.0"/> // フォントサイズ 10pt <color rgb="FF000000"/> // 黒 (ARGB: FF=不透明, 000000=黒) <name val="Arial"/> // フォント名 Arial <scheme val="minor"/> </font> <font> <color theme="1"/> <name val="Arial"/> <scheme val="minor"/> </font> </fonts>
fontsがフォントの種類や、文字色などを定義しています。
<fills count="3"> // 塗りつぶしスタイルが 3種類 定義されています。 <fill> <patternFill patternType="none"/> // 塗りつぶしなし </fill> <fill> <patternFill patternType="lightGray"/> // グレーパターン塗りつぶし。Excel が持つ標準的なグレー模様 </fill> <fill> <patternFill patternType="solid"> // patternType="solid"が、単色で塗りつぶす <fgColor rgb="FFFF0000"/> // fgColor(前景色)を赤で塗りつぶし <bgColor rgb="FFFF0000"/> // bgColor(背景色)を赤で塗りつぶし </patternFill> </fill> </fills>
fillsが、塗りつぶしスタイルの定義になります。
<borders count="1"> // ボーダースタイルは 1種類のみ 定義されている。 <border/> // 枠線なし(デフォルトの空のボーダー) を意味します。 </borders>
<cellStyleXfs count="1"> <xf borderId="0" fillId="0" fontId="0" numFmtId="0" applyAlignment="1" applyFont="1"/> </cellStyleXfs>
属性名 | 説明 |
---|---|
borderId="0" | borders の0番目(つまり「線なし」のボーダー)を使う |
fillId="0" | fills の0番目(パターンなしの背景)を使う |
fontId="0" | fonts の0番目(Arial/10pt)を使う |
numFmtId="0" | 標準の表示形式(General) |
applyAlignment="1" | 位置合わせ(alignment)の適用を明示 |
applyFont="1" | フォントの設定を適用する |
<cellXfs count="5"> <xf borderId="0" fillId="0" fontId="0" numFmtId="0" xfId="0" applyAlignment="1" applyFont="1"> <alignment readingOrder="0" shrinkToFit="0" vertical="bottom" wrapText="0"/> </xf> <xf borderId="0" fillId="2" fontId="1" numFmtId="0" xfId="0" applyAlignment="1" applyFill="1" applyFont="1"> <alignment readingOrder="0"/> </xf> <xf borderId="0" fillId="0" fontId="1" numFmtId="0" xfId="0" applyAlignment="1" applyFont="1"> <alignment readingOrder="0"/> </xf> <xf borderId="0" fillId="0" fontId="1" numFmtId="3" xfId="0" applyAlignment="1" applyFont="1" applyNumberFormat="1"> <alignment readingOrder="0"/> </xf> <xf borderId="0" fillId="0" fontId="1" numFmtId="1" xfId="0" applyAlignment="1" applyFont="1" applyNumberFormat="1"> <alignment readingOrder="0"/> </xf> </cellXfs>
属性名 | 意味 |
---|---|
borderId="0" | borders 配列のインデックス。枠線のスタイルを指定します。0はデフォルト(なし)を指すことが多い。 |
fillId="0" | fills 配列のインデックス。背景塗りつぶしのスタイルを指定します。0は「塗りつぶしなし」。 |
fontId="0" | fonts 配列のインデックス。使用するフォントの定義を指定します。 |
numFmtId="0" | 数値フォーマットの ID。例:0 は「標準」:自動で整数や小数などを調整(見た目依存)、3:桁区切りあり(例:1234 → 1,234) |
xfId="0" | cellStyleXfs のどのテンプレート(xf)を継承するかを指定。スタイルのベースとして使います。 |
applyFont="1" | fontId で指定されたフォントを実際に使用する(1: 使用する / 0: 無視) |
applyFill="1" | fillId の塗りつぶしを使用する |
applyAlignment="1" | |
applyNumberFormat="1" | numFmtId の数値書式を使用する |
readingOrder | テキストの読み方向:0 は左→右、1 は右→左 |
<xf>
は eXtended Format(拡張書式)を意味し、セルに適用される見た目のルールを定義します。
●xl/worksheet/sheet1.xml
各ワークシート(シート)ごとのデータ本体を定義しています。
<pane ySplit="1.0" topLeftCell="A2" activePane="bottomLeft" state="frozen"/>
- pane: ウィンドウ枠の分割設定
- ySplit="1.0":1行目で 水平に分割(=1行目が固定)
- state="frozen":固定表示
- topLeftCell="A2":分割後、左上に来るセルは A2
sheet1.xmlのsheetDataの各セルが、sharedStrings.xmlやstyles.xmlの情報を参照しているという形になっています。
■まとめ
普段何気なく触っているCSVファイルやExcelファイルがどんな構造なのか?ファイルのメリット・デメリットを知ることができ、勉強になりました。
特にExcelファイルは構造は複雑で、Excelライブラリのメンテナンスをしたい場合は、Excelの構造をぼんやりとでも知っている必要があるため、良い機会になりました。
現在弊社ではエンジニアを募集しています!
この記事を読んで少しでも興味を持ってくださった方は、ぜひカジュアル面談でお話ししましょう!
iimon採用サイト / Wantedly / Green
■参考記事
CSVファイルとExcel(エクセル)ファイルの違いとは?使い分けの方法や注意点・対策法も紹介