Je développe un composant à partir duquel l'utilisateur peut télécharger une feuille Excel et les données doivent être enregistrées dans une base de données. Lorsque les lignes d'une feuille Excel sont 250
, L'insertion fonctionne correctement, mais lorsque les lignes sont 2500
Ou plus, une page vierge ne contient pas d'erreur et les lignes ne sont pas complètement insérées dans la base de données. J'utilise la bibliothèque PHPExcel
pour importer des feuilles Excel. Voici le code:
contrôleurs/fileuploads.php :
public function uploadData($fileData, $data,$tablename){
//Validate file by checking if Excel sheet is uploaded
$isValid = $this->validateFileType($fileData);
if($isValid){
$inputFilename = $fileData['excelfile']['tmp_name'];
try {
$objPHPExcel = PHPExcel_IOFactory::load($inputFilename); //read the spreadsheet workbook
} catch (Exception $e) {
die('Error loading file "'.pathinfo($inputFilename,PATHINFO_BASENAME).'": '.$e->getMessage());
}
// Get worksheet dimensions
$sheet = $objPHPExcel->getSheet(0);
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
for ($row = 4; $row <= $highestRow; $row++){
// Read a row of data into an array
$rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row);
if(!empty($rowData[0][0])){ //if row is null
// Insert row data array into database
$isInserted = $this->insertData($rowData, $data);
}
}// Excel for loop ends
if($isInserted){
//redirect after importing the data from Excel into database
$this->setRedirect(JRoute::_('index.php?option=com_mycomponent&view=fileuploads', false), 'File uploaded successfully','message');
}
}//if($isValid)
}
controllers/fileuploads - méthode insertData: cette méthode appelle différentes méthodes de modèle en fonction de la feuille de la section à télécharger. Ex. Section Test
Appellera une méthode getInsertSectionTest()
à partir du modèle. Il y a 6 sections différentes.
models/fileupload.php: Voici le code pour insérer des données
public function getInsertSectionTest($rowData, $data){
$objData = new stdClass();
$objData->section_id = $data['section'][0];
$objData->category = str_replace("'","",$rowData[0][0]);
$objData->subcategory = str_replace("'","",$rowData[0][6]);
$objData->year = $data['year'];
$objData->number_type = $rowData[0][7];
.
. // and so on
.
$objData->region_northwest = $rowData[0][43];
$objData->region_southwest = $rowData[0][44];
$objData->region_unknown = $rowData[0][45];
$insertResult = JFactory::getDbo()->insertObject('#__testsection_tablename', $objData);
if( $insertResult){
return true;
}
else{
$this->setRedirect(JRoute::_('index.php?option=com_mycomponent&view=fileuploads', false), 'Data could not be imported. Please try again' ,'error');
return false;
}
}
Veuillez me faire savoir comment plus de 2000 lignes peuvent être insérées simultanément. Je me suis également référé à cette question mais je ne suis pas en mesure de former le tableau de valeurs à insérer.
J'ai résolu le problème. Le problème était que lorsque la requête d'insertion a été appelée dans une boucle 2 000 fois, un blocage s'est produit et a renvoyé une page vierge. La solution consiste à créer une requête d'insertion unique, puis à insérer les valeurs. Voici le code que j'ai ajouté dans le fichier de modèle -
Au lieu d'appeler la méthode d'insertion dans la boucle, j'ai formé le tableau d'insertion de valeurs:
$getValues = array();
for ($row = 4; $row <= $highestRow; $row++){
// Read a row of data into an array
$rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row);
if(!empty($rowData[0][0])){ //if row is null
// Insert row data array into database
$getValues[] = $this->getValuesModel($rowData, $data);
}
}// Excel for loop ends
$columns = $this->getColumns($data); //call columns method to fetch different section's columns
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->insert($db->quoteName($tablename));
$query->columns($columns);
$query->values($getValues);
$db->setQuery($query);
$isInserted = $db->query();
if($isInserted){
//redirect after importing the data from Excel into database
$this->setRedirect(JRoute::_('index.php?option=com_componentname&view=fileuploads', false), 'File uploaded successfully','message');
}
Pour le code complet et les fichiers, vous vous référez Github .