[Solved] Import Data Dari Excel Ke Database

maaf nih agan-agan semua, ane terpaksa repost topic ni lagi, ane bener-bener need help…

ane mau import data absensi nih critanya gan, nah udah googling n banyak yg pakai PhpExcelReader.

problem ane tuh waktu submit file itu seakan-akan udah terupload, padahal ndak ada proses sama sekali. dan juga g ada pesan error yang tampil

di controller ane bikin function kyk tutorial yg ane dpet dr googling


public function actionImportExcel()

	{

		error_reporting(E_ALL ^ E_NOTICE);

		$model=new ATTENDANCE;

		

		if(isset($_POST['ATTENDANCE']))

		{

			Yii::import('ext.phpexcelreader.JPhpExcelReader');

			

			$model->attributes=$_POST['ATTENDANCE'];

			if(strlen(trim(CUploadedFile::getInstance(model,'filee'))) >0)

			{

				$import=CUploadedFile::getInstance($model,'filee');

				//$path=Yii::app()->getBasePath().'/../import/absen.xls';

				$import->saveAs(Yii::app()->basePath.'/../import/');

				

				$data = new JPhpExcelReader(Yii::app()->basePath.'/../import/');

				

				$att_emp_id = array();

				$att_emp_name = array();

				$att_date = array();

				$att_clock_in = array();

				$att_clock_out = array();

				

				for ($j=1; $j <= $data->sheets[0]['nuimRows']; $j++)

				{

					$att_emp_id[$j]=$data->sheets[0]['cells'][$j][1];

					$att_emp_name[$j]=$data->sheets[0]['cells'][$j][2];

					$att_date[$j]=$data->sheets[0]['cells'][$j][3];

					$att_clock_in[$j]=$data->sheets[0]['cells'][$j][4];

					$att_clock_out[$j]=$data->sheets[0]['cells'][$j][5];

				}

				

				$niki = $data->rowcount(0);

				

				for($i = 2; $i<=$niki; $i++)

				{

					$model = new ATTENDANCE;

					

					$model->ATT_EMP_ID = $att_emp_id[$i];

					$model->ATT_EMP_NAME = $att_emp_name[$i];

					$model->ATT_DATE = $att_date[$i];

					$model->ATT_CLOCK_IN = $att_clock_in[$i];

					$model->ATT_CLOCK_OUT = $att_clock_out[$i];

					

					$valid = $model->validate();

					if($valid)

					{

						$model->save();

						Yii::app()->user->setFlash('success', 'Data <strong>berhasil</strong> di unggah. Terima kasih');

					}

					else

					{

						Yii::app()->user->setFlash('error', '<strong>Beberapa data sudah ada dalam database.</strong> Silahkan periksa kembali.');

					}

				}

                

				

                $this->redirect(array('admin'));

            }

            else 

			{

				Yii::app()->user->setFlash('error', 'Data <strong>gagal</strong> di unggah. Silahkan periksa file anda.');

            }

        }

               

			$this->render('ImportExcel',array(

			'model'=>$model,

        ));

	}

untuk di form nya ane bikin gini :


<?php if(!$model->isNewRecord) { ?>

<div class="well">

	

		<?php $form=$this->beginWidget('bootstrap.widgets.TbActiveForm',array(

			'id'=>'attendance-form',

			'enableAjaxValidation'=>false,

		)); ?>

		

			<p class="help-block">Fields with <span class="required">*</span> are required.</p>


			<?php echo $form->errorSummary($model); ?>

		<div class="row-fluid">

			<div class="span2">

			<?php echo $form->textFieldRow($model,'ATT_EMP_ID',array('class'=>'span15','maxlength'=>20)); ?>

			</div>

			<div class="span3">

			<?php echo $form->textFieldRow($model,'ATT_EMP_NAME',array('class'=>'span10','maxlength'=>30)); ?>

			</div>

		</div>

		

			<?php //echo $form->textFieldRow($model,'ATT_DATE',array('class'=>'span5')); ?>

			<?php echo $form->labelEx($model,'ATT_DATE'); ?>

				<?php 

					$this->widget('zii.widgets.jui.CJuiDatePicker',array(

						'attribute'=>'ATT_DATE',

						'model'=>$model,

						// additional javascript options for the date picker plugin

									

						'options'=>array(

							'mode'=>'focus',

							'showAnim'=>'bounce',

							'flat'=>true,

							'dateFormat'=>'dd-mm-yy',

							'changeMonth'=>true,

							'changeYear'=>true,

							'yearRange'=>'1900:2099',

							'showButtonPanel'=>true,

						),

						'htmlOptions'=>array(

							'style'=>'height:20px; width:150px; text-align:center;',

						),

					));

				?>

			

			

			<div class="row-fluid">

				<div class="span2">

					<?php echo $form->textFieldRow($model,'ATT_STAND_CLOCK_IN',array('class'=>'span8', 'maxlength'=>6)); ?>

				</div>

				<div class="span2">

					<?php echo $form->textFieldRow($model,'ATT_CLOCK_IN',array('class'=>'span8','maxlength'=>6)); ?>

				</div>

				<div class="span2">

					<?php echo $form->textFieldRow($model,'ATT_STAND_CLOCK_OUT',array('class'=>'span8','maxlength'=>6)); ?>

				</div>

				<div class="span2">

					<?php echo $form->textFieldRow($model,'ATT_CLOCK_OUT',array('class'=>'span8','maxlength'=>6)); ?>

				</div>

				<div class="span2">

					<?php echo $form->textFieldRow($model,'ATT_LATE_STAT',array('class'=>'span8','maxlength'=>15)); ?>

				</div>

				<div class="span2">

					<?php echo $form->textFieldRow($model,'ATT_PERMIT_ID',array('class'=>'span8',)); ?>

				</div>

		</div>

			<div class="form-actions">

				<?php $this->widget('bootstrap.widgets.TbButton', array(

					'buttonType'=>'submit',

					'type'=>'primary',

					'label'=>$model->isNewRecord ? 'Tambahkan' : 'Simpan',

				)); ?>

			</div>


		<?php $this->endWidget(); ?>

	

</div><?php } ?>

<br>




<h3> Import Dari Excel</h3>

<div class="well">	

	<?php if($model->isNewRecord) { ?>

	<?php $form=$this->beginWidget('bootstrap.widgets.TbActiveForm',array(

			'id'=>'attendance-form',

			'enableAjaxValidation'=>false,

			'htmlOptions' => array('enctype' => 'multipart/form-data'),

		)); ?>

		<?php echo $form->fileFieldRow($model,'filee',array('class'=>'span3')); ?>

		<div class="form-actions">

				<?php $this->widget('bootstrap.widgets.TbButton', array(

					'buttonType'=>'submit',

					'icon'=>'white upload',

					'type'=>'primary',

					'label'=>'UPLOAD',

				)); ?>

			</div>

		

	<?php $this->endWidget(); ?>

	<?php } ?>

</div>

di form ntu ane aktifin yg untuk upload file doank, untuk formnya aktif kalau kondisi data nya bukan data baru(update)

di modelnya udah ane bikin gini :


class ATTENDANCE extends CActiveRecord

{

	

	public $filee;

        

             ....


public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('ATT_EMP_ID, ATT_EMP_NAME, ATT_DATE', 'required'),

			array('ATT_PERMIT_ID', 'numerical', 'integerOnly'=>true),

			array('ATT_EMP_ID', 'length', 'max'=>20),

			array('ATT_EMP_NAME', 'length', 'max'=>30),

			array('ATT_CLOCK_IN, ATT_CLOCK_OUT, ATT_STAND_CLOCK_IN, ATT_STAND_CLOCK_OUT', 'length', 'max'=>6),

			array('ATT_LATE_STAT', 'length', 'max'=>15),

			array('filee', 'file', 'types'=>'xls, xlsx'),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('ATT_ID, ATT_EMP_ID, ATT_EMP_NAME, ATT_DATE, ATT_CLOCK_IN, ATT_CLOCK_OUT, ATT_LATE_STAT, ATT_STAND_CLOCK_IN, ATT_STAND_CLOCK_OUT, ATT_PERMIT_ID', 'safe', 'on'=>'search'),

		);

	}


....

}




trimakasih sebelumnya para master.

mohon bantuannya banget gan, ane udah cb otak atik lagi nih controller ane,

jd kayak gini :


public function actionImport()

	{

		

		//require_once('..\protected\extentions\excelreader\excel_reader2.php');

		//error_reporting(E_ALL ^ E_NOTICE);

		$model=new ATTENDANCE;

		//spl_autoload_unregister(array('YiiBase','autoload'));

		if(isset($_POST['ATTENDANCE']))

		{

			//$phpExcelPath = Yii::getPathOfAlias('ext.excelreader.excel_reader2');

			   

			Yii::import('ext.excelreader.excel_reader2', true);

			

			

			$model->attributes=$_POST['ATTENDANCE'];


				$import=CUploadedFile::getInstance($model,'filee');

				//$path='/../import/absen.xls';

				if(isset($import))

				{

					$import->saveAs(Yii::app()->basePath.'/../import/absen.xls');

				}

				

				$data = new Spreadsheet_Excel_Reader('import/absen.xls');

				

				$att_emp_id = array();

				$att_emp_name = array();

				$att_date = array();

				$att_clock_in = array();

				$att_clock_out = array();

				

				for ($j=0; $j <= $data->sheets[0]['nuimRows']; $j++)

				{

					$att_emp_id[$j]=$data->sheets[0]['cells'][$j][1];

					$att_emp_name[$j]=$data->sheets[0]['cells'][$j][2];

					$att_date[$j]=$data->sheets[0]['cells'][$j][3];

					$att_clock_in[$j]=$data->sheets[0]['cells'][$j][4];

					$att_clock_out[$j]=$data->sheets[0]['cells'][$j][5];

				}

				

				$niki = $data->rowcount(0);

				

				for($i = 1; $i<=$niki; $i++)

				{

					$model = new ATTENDANCE;

					

					$model->ATT_EMP_ID = $att_emp_id[$i];

					$model->ATT_EMP_NAME = $att_emp_name[$i];

					$model->ATT_DATE = $att_date[$i];

					$model->ATT_CLOCK_IN = $att_clock_in[$i];

					$model->ATT_CLOCK_OUT = $att_clock_out[$i];

					

				

						$model->save();

						//Yii::app()->user->setFlash('success', 'Data <strong>berhasil</strong> di unggah. Terima kasih');

				

				}

            

                $this->redirect(array('admin'));

           

        }

               

			$this->render('Import',array(

			'model'=>$model,

        ));

	}	

nah sekarang muncul error gini :

[color="#FF0000"]Undefined index: nuimRows[/color]

Itu bukannya ‘numRows’, ya, gan?


for ($j=0; $j<=$data->sheets[0]['numRows']; $j++)

o iy gan :) salah ketik,

uda ane ganti gitu, skrg errornya karena


for ($j=0; $j <= $data->sheets[0]['numRows']; $j++)

tp kalau ane ganti


for ($j=5; $j <= $data->sheets[0]['numRows']; $j++)

ini bisa jalan, knp y gan? tp apakah ndak salah?

Ada pesan errornya, gan?

Ngomong2 agan pake PHP Excel Reader yang mana? Ane dulu pernah pake yang ini, dan seinget ane (ane juga udah agak lupa, ya :) ) indeksnya itu dimulai dari 1:


for ($i=1; $i<=$data->sheets[0]['numRows']; $i++) 

kalau indexnya di kasih 1 error nya [color="#FF0000"]Undfined offset: 1[/color] gan,

nah indexnya bakal jalan kalau ane kasih 5, tapi masih error juga… (errornya ane lampirin di gambar ke 2 dan ke 3)

untuk php excel readernya ane ambil langsung dari [color="#FF0000"]sini[/color] gan.

sempat juga sih pakai yang kyk agan rei, tp error wktu mbaca file excelnya. unreadable.

Setau ane kalau Undefined Offset kayak gitu berarti array $att_emp_id gak punya elemen pada index ke-1. Sebaiknya dilakukan pengecekan terlebih dahulu sebelum mengakses nilai dari array tersebut.

Ane gak terlalu ngerti error waktu savenya, tapi kemungkinan ada masalah di field yang berkaitan dengan date (mungkin format $att_date?). Saran ane kalau bisa nilai field - field-nya dicek dulu (bisa pake var_dump()) supaya ketauan errornya di mana.

emank sih gan data masternya masih belum di input… :D

ane cb cek and input dulu deh…

agan rei, maaf nih sebelum lanjut masalah import, ini ane sekalian otak-atik dependent dropdown list untuk propinsi n kota ane (untuk keperluan entry master data karyawan) jg :D

ane udah susun di formnya kyk gni :




<div class="span4">

         <?php echo $form->dropDownListRow($model,'EMP_PROVINCE_ID', CHtml::listData(PROVINCE::model()->findAll(), 'PROVINCE_ID','PROVINCE_NAME'),array(

			'prompt'=>'----- Pilih Propinsi -----',

			'ajax'=>array(

			'type'=>'POST',						           

                        'url'=>CController::createUrl('filterkota'),

                         //'update'=>'#EMPLOYEE_EMP_CITY_ID',

                        'update'=>'#'.CHtml::activeId($model,'CITY_ID'),

			'beforSend'=>'function(){

                             $("#EMPLOYEE_EMP_CITY_ID").find("option").remove();

			}',

		       //'data'=>array('CITY_ID'=>'js:this.value'),

		)

	)); ?>

</div>

<div class="span4">

	<?php echo $form->dropDownListRow($model,'EMP_CITY_ID', CHtml::listData(CITY::model()->findAll(), 'CITY_ID','CITY_NAME'), array('prompt'=>'----- Pilih Kota -----')); ?>

</div>

di controllernya ane bikin function method nya :


public function actionFilterkota()

	{

		$data=CITY::model()->findAll('PROVINCE_ID=:PROVINCE_ID',

			array(':PROVINCE_ID'=>(int)$_POST['PROVINCE_ID'])

		);

		

		$data=CHtml::listData($data,'CITY_ID','CITY_NAME');

		

		

		echo "option value=''>-----Pilih Kota-----</option>";

		foreach($data as $value =>$CITY_NAME)

		echo CHTML::tag('option', array('value'=>$value),CHtml::encode($CITY_NAME),true);	

	}

sesuai saran agan rei dulu yang tinjau id field menggunakan inspect element untuk memastikan field yang akan di update ane udah pastiin di atas field yg mau di update id nya #EMPLOYEE_EMP_CITY_ID

nah waktu di jalanin, ane tracking pakai inspect element juga ternyata error code 500 internal server error… knp ya?

kalau ane perhatiin coding ane sih kyknya udah sesuai sama yang di tutorial… :huh:

Coba diklik link yang menuju action filterkota, gan (di kotak Console ato Network). Biasanya ada penjelasan lebih lanjut untuk error kaya gitu.

error nya :


Undefined index: CITY_PROVINCE_ID (C:\xampp\htdocs\att\protected\controllers\EMPLOYEEController.php:104)

padahal di tabel ane untuk nampung nama2 kota udah di panggil :




public function actionFilterkota()

	{

		$models=CITY::model()->findAll('CITY_PROVINCE_ID=:CITY_PROVINCE_ID',

			array(':CITY_PROVINCE_ID'=>(int)$_POST['CITY_PROVINCE_ID'])

		);

		

		$data=CHtml::listData($models,'CITY_ID','CITY_NAME');

		

		echo "option value=''>-----Pilih Kota-----</option>";

		foreach($data as $value =>$CITY_NAME)

		echo CHTML::tag('option', array('value'=>$value),CHtml::encode($CITY_NAME),true);	

		

	}



untuk dependent dropdown list nya solved gan rei, ternyata ane kliru di formnya :D

yang mulanya :




<div class="row-fluid">

     <div class="span4">

		<?php echo $form->dropDownListRow($model,'EMP_PROVINCE_ID', CHtml::listData(PROVINCE::model()->findAll(), 'PROVINCE_ID','PROVINCE_NAME'),array(

			'prompt'=>'----- Pilih Propinsi -----',

			'ajax'=>array(

				'type'=>'POST',

                                'url'=>CController::createUrl('filterkota'),

                                'update'=>'#EMPLOYEE_EMP_CITY_ID',

                                'data'=>array('EMPLOYEE_EMP_CITY_ID'=>'js:this.value'),      <------- ini yang keliru

			)

		)); ?>

</div>




ane ubah gini :




<div class="row-fluid">

	<div class="span4">

		<?php echo $form->dropDownListRow($model,'EMP_PROVINCE_ID', CHtml::listData(PROVINCE::model()->findAll(), 'PROVINCE_ID','PROVINCE_NAME'),array(

			'prompt'=>'----- Pilih Propinsi -----',

			'ajax'=>array(

				'type'=>'POST',

				'url'=>CController::createUrl('filterkota'),

				'update'=>'#EMPLOYEE_EMP_CITY_ID',									                   

                                'data'=>array('EMP_PROVINCE_ID'=>'js:this.value'), <------ harusnya datanya ini <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/biggrin.gif' class='bbc_emoticon' alt=':D' />

			)

		)); ?>

</div>




Alhamdulillah proses import sebenernya udah jalan, hanya karena master data karyawan yang belum di input, jd data yang berelasi tidak bisa mengambil data referensinya, setelah di input masternya sekarang sudah jalan… :D

thank’s buat agan rei :D

satu lagi nih gan yg mau ane tanyain untuk import, ini kan belum ada counter untuk data yang berhasil di import and gagal diimport, nah itu gmn ya?

Data yang berhasil diimpor itu data yang udah disimpan ke database, bukan, gan? Kalo iya, agan kan bisa tambahin counter setelah method save() dipanggil:




if ($model->save())

  $berhasil++;

else

  $gagal++;



Jangan lupa juga variabel $berhasil dan $gagal diset ke 0 dulu sebelum perulangan (for).

oce gan rei… trims :D