CSVファイルをDBにインポート

サーバのテーブルに,CakePHP経由でアップロードしたCSVファイルをインポートする必要がありましたので,その処理を作ってみました。CSVファイルをサーバにアップロードし,そのファイルをDBにインポートするという手順になろうかと思います。

ビュー

<div class="options form">
<div class="actions">
    <ul>
        <li><?php echo $html->link('メニューに戻る', array('action'=>'index'));?></li>
    </ul>
</div>
<?php echo $form->create('Options', array('action'=>'upload', 'type' => 'file'));?>
    <fieldset>
        <legend>データのアップロード</legend>
    <?php
        echo $form->file('result');
    ?>
    </fieldset>
<?php echo $form->end('アップロード');?>
</div>

 コントローラ

function upload(){
        if (!empty($this->data)) {
            $model =& $this->Result;
            /* @var $model result */
            $up_file = $this->data['Options']['result']['tmp_name'];
            $fileName = CSV_FILE_PATH."result.csv";
            if (is_uploaded_file($up_file)){
                move_uploaded_file($up_file, $fileName);
                $model->loadFromCSV($fileName);         
                $this->Session->setFlash('データをアップロードしました。');
                $this->redirect(array('action'=>'index'));
            }
        }
    }

コントローラでは,返された$this->dataの'tmp_name'の中にアップロードされたファイル名が入っています。上記のコード では,それのファイルをmove_uploaded_file関数で,特定の場所に保存しています。その後,モデルに定義したloadFromCSVメ ソッドでDBに読み込んでいます。

モデル

function loadFromCSV($fileName) {
        $this->begin();
        try{
            $this->deleteAll('1 = 1', false);
            $csvData = file($fileName, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
            foreach($csvData as $line){
                $record = split(",", $line);
                $data = array(
                    "field1" => $record[0],
                    "field2" => $record[1]
                );
                $this->create($data);
                $this->save();
            }
            $this->commit();
        } catch(Exception $e) {
            $this->rollback();
        }
    }

モデルに定義したloadFromCSVメソッドは上記の通りです。ファイルをfile関数で読み込み,各行をsplitで分割してフィールドに セットしています。MySQLにはファイルからデータをインポートするSQL文もあるので,それを使おうかとも思ったのですが,CakePHPの機能で実 装しました。

大変な処理かと思ったのですが,わりと簡単に実現できました。

トラックバック


URL から "-MoIyadayo" を削除してトラックバックを送信してください。
トラックバックは承認後に表示されます。