在Sourceforge上提供了一個開源的PHP導入Excel數據的類,在下載的項目中也提供了簡單的示例。下面我做了一些簡易的包裝,讓PHP導入Excel數據用起來更為簡便。
首先看看示例代碼,了解一下Excel Reader的基本使用方式(按照下面的注釋step by step)
<?php // 1.引用ExcelReader類文件 require_once 'Excel/reader.php'; // 2.實例化讀取Excel的類 $data = new Spreadsheet_Excel_Reader(); // 3.設置輸出編碼 $data->setOutputEncoding('utf-8'); // 4.讀取指定的excel $data->read('test.xls'); // 5.循環輸出每一行數據,這里讀取的是Excel的第一個Sheet表格 // sheets[0]['numRows']代表行數 // sheets[0]['numCols']代表列數 for ($i = 1; $i <= $data->sheets[0]['numRows']; $i++) { // 遍歷行 for ($j = 1; $j <= $data->sheets[0]['numCols']; $j++) { // 遍歷列 echo "\"".$data->sheets[0]['cells'][$i][$j]."\","; } echo "\n"; } ?>
這個簡單的例子只是輸出了Excel中每個單元格的值,我們還需要拼接sql語句最終將這些值插入到數據庫中,而且當Excel的第一行為列頭時,這一行數據是不能夠插入到數據表中的。
下面的步驟就來演示這一簡單過程。
1. 創建數據庫,數據表
--創建test數據庫 create database test; use test; --創建books表 create table books ( ISBN varchar(50) primary key, Pubdate varchar(50) );
2. 拼接sql
<?php require_once 'Excel/reader.php'; @ $db = mysql_connect ( 'localhost', 'root', 'root' ) or die ( "Could not connect to database." ); // 連接數據庫 mysql_query ( "set names 'utf-8'" ); // 輸出中文 mysql_select_db ( 'test' ); // 選擇數據庫 $data = new Spreadsheet_Excel_Reader (); $data->setOutputEncoding ( 'utf-8' ); $data->read ( 'Books.xls' ); // 調用ImportExcelData方法 ImportExcelData ( $data, 'books', array ('ISBN', 'Pubdate' ), true ); /** * 將讀取到的Excel數據導入到數據庫中 * * @access public * @param * hasColumnHeader 是否包含列頭 * @param * columnArray 要插入的列 * @param * tableName 要插入的表 * @return bool */ function ImportExcelData($data, $tableName, $columnArray, $hasColumnHeader = false) { // 默認不包含列頭,起始行就為1 $start = 1; if ($hasColumnHeader) { // 如果包含列頭,跳過列頭,起始行為2 $start = 2; } // 生成insert語句的前半部分 // 形式如這種:insert into table_name('field1','field2'...) values $insert_statement = CreateInsertStatement ( $tableName, $columnArray ); for($i = $start; $i <= $data->sheets [0] ['numRows']; $i ++) { // 遍歷行 $sql = $insert_statement; $sql .= "("; for($j = 1; $j <= $data->sheets [0] ['numCols']; $j ++) { // 遍歷列 $sql .= "'" . $data->sheets [0] ['cells'] [$i] [$j] . "',"; } $sql = trimEnd ( $sql, "," ); $sql .= ");"; $res = mysql_query ( $sql ); } } /** * 創建插入sql的語句 * * @access public * @param * tableName * @param * columnArray * @return string */ function CreateInsertStatement($tableName, $columnArray) { $sql = "insert into ".$tableName."("; foreach ( $columnArray as $c ) { $sql .= "" . $c . ","; } $sql = trimEnd ( $sql, "," ); $sql .= ") values"; return $sql; } /** * 移除字符串中指定的尾部字符 * * @access public * @param * str * @param * strEnd * @return string */ function trimEnd($str, $strEnd) { return substr ( $str, - (strlen ( $strEnd )) ) == $strEnd ? substr ( $str, 0, strlen ( $str ) - strlen ( $strEnd ) ) : $str; } ?>
3. 優化
上面的方法有一個問題,每次生成一個insert語句,就執行一次插入操作,如果Excel的數據量很大,那么執行的插入操作也非常多。既然如此,何不生成一批sql語句后再執行插入操作呢?
我對ImportExcelData方法做了簡單的優化,加了一個batchSize參數,表示每次執行多少條插入語句,也許這樣的做法會更加節約資源。
/** * 將讀取到的Excel數據導入到數據庫中 * * @access public * @param hasColumnHeader 是否包含列頭 * @param columnArray 要插入的列 * @param tableName 要插入的表 * @param batchSize 每次執行插入語句的條數 * @return bool */ function ImportExcelData($data,$tableName,$columnArray,$hasColumnHeader = false, $batchSize = 100){ // 默認不包含列頭,起始行就為1 $start = 1; if($hasColumnHeader){ // 如果包含列頭,跳過列頭,起始行為2 $start = 2; } // 記錄循環次數 $loop = 0; $sql = ""; // 生成insert語句的前半部分 // 形式如這種:insert into table_name('field1','field2'...) values $insert_statement = CreateInsertStatement($tableName, $columnArray); for($i = $start; $i <= $data->sheets[0]['numRows']; $i++){ // 遍歷行 $sql .= $insert_statement; $sql .= "("; for ($j = 1; $j <= $data->sheets[0]['numCols']; $j++){ // 遍歷列 $sql .= "'".$data->sheets[0]['cells'][$i][$j]."',"; } $sql = trimEnd($sql,","); $sql .= ");"; $loop ++; // 當loop值等於batchSize時,執行插入操作 if($loop == $batchSize){ $res = mysql_query ( $sql ); $loop = 0;
$sql = ""; } //echo $sql; } // 如果有950條記錄,執行了前9個batch,剩余50條也應當執行 if($loop != 0){ $res = mysql_query ( $sql ); } }
Books.xls文件的內容如圖1:
【圖1】
生成的sql語句如圖2:
【圖2】
當然Excel Reader類中提供的方法不止這些,大家可以參考Sourceforge上提供的example,也可以直接去查看或更改源代碼獲取自己需求的功能。
本文源代碼下載:http://files.cnblogs.com/keepfool/phpExcelReader.zip



