環境は Excel 2010、PHP5.3.10 + Zip拡張 + SimpleXML拡張。
エクセルはこういう簡単なもの。
で、こういうコードを書く。
<?php | |
// エクセルファイルを zip として処理 | |
$zip = new ZipArchive(); | |
$zip->open( 'test.xlsx' ); | |
// 1シート目のxml取得 | |
$xml_sheet = simplexml_load_string( $zip->getFromName( 'xl/worksheets/sheet1.xml' ) ); | |
// sharedStrings.xml を取得 | |
$xml_sst = simplexml_load_string( $zip->getFromName( 'xl/sharedStrings.xml' ) ); | |
// 結果格納用 | |
$result = array(); | |
// 行ループ | |
foreach( $xml_sheet->sheetData->row as $row ) { | |
// セルループ | |
foreach( $row->c as $cell ) { | |
// セルの名前。"A1" とか "B2" とか | |
$cell_name = (string)$cell->attributes()->r; | |
// セルのタイプ。文字列が設定されている場合は "s" | |
$cell_type = (string)$cell->attributes()->t; | |
// セルの値。$cell_type が "s" の場合は | |
// sharedStrings.xml -> si の index値が設定される。 | |
$cell_value = (int)$cell->v; | |
// "s" の場合は sharedStrings.xml から取得 | |
if ( $cell_type === 's' ) { | |
$cell_value = (string)$xml_sst->si[ (int)$cell->v ]->t; | |
} | |
$result[ $cell_name ] = $cell_value; | |
} | |
} | |
$zip->close(); | |
print_r( $result ); | |
実行結果。
Array | |
( | |
[A1] => あああ | |
[B1] => 111 | |
[A2] => いいい | |
[B2] => 222 | |
[A3] => ううう | |
[B3] => 333 | |
) |
--------------
Excel2007以降のエクセルファイルの実体は zip アーカイブだから、unzip するとこんな具合に展開される。
test/
│ [Content_Types].xml
├─docProps/
│ app.xml
│ core.xml
├─xl/
│ │ sharedStrings.xml
│ │ styles.xml
│ │ workbook.xml
│ ├─printerSettings/
│ │ printerSettings1.bin
│ ├─theme/
│ │ theme1.xml
│ ├─worksheets/
│ │ │ sheet1.xml
│ │ │ sheet2.xml
│ │ │ sheet3.xml
│ │ └─_rels/
│ │ sheet1.xml.rels
│ └─_rels/
│ workbook.xml.rels
└─_rels/
.rels
xl/sharedStrings.xml ってのが文字列情報の共通ファイル。
xl/worksheerts/sheet*.xml が各シートの定義。
この2種類のXMLファイルを使えば、セルの内容を抽出できる。
--------------
生PHPでやりたくない人は PHPExcel を使えばいいけど、結構重たい。
≪ 決まり