Populating a mysql database with an excel file using phpspreadsheet - php

I am trying to populate a mysql database with an excel file using phpspreadsheet library. I am doing it in the following way but I get just the first row. How can I do it for all the rows
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($target_file);
$worksheet = $spreadsheet->getActiveSheet();
$rows = [];
$outer = 1;
foreach ($worksheet->getRowIterator() AS $row) {
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(FALSE); // This loops through all cells,
$cells = [];
foreach ($cellIterator as $cell) {
$cells[] = $cell->getValue();
}
$rows[] = $cells;
while($outer > 1){
$data = [
'testTaker' => $cells[1],
'correctAnswers' => $cells[2],
'incorrectAnswers' => $cells[3],
];
if($this->testModel->addTest($data)){
die('it worked');
} else {
die('Something went wrong');
}
}
$outer++;
}

This is how I am importing a XLSX spreadsheet with phpSpreadSheet into a MySQL database using PDO (modified to fit your criteria).
// read excel spreadsheet
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
if($reader) {
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load($target_file);
$sheetData = $spreadsheet->getActiveSheet()->toArray();
foreach($sheetData as $row) {
// get columns
$testTaker = isset($row[0]) ? $row[0] : "";
$correctAnswers = isset($row[1]) ? $row[1] : "";
$incorrectAnswers = isset($row[2]) ? $row[2] : "";
// insert item
$query = "INSERT INTO item(testTaker, correctAnswers, incorrectAnswers) ";
$query .= "values(?, ?, ?)";
$prep = $dbh->prepare($query);
$prep->execute(array($testTaker, $correctAnswers, $incorrectAnswers));
}
}

Related

Skip First Row in PHPSpreadsheet Import

Just started working with phpspreadsheet. I am trying to figure out how to skip the header row in my excel file when uploading.
require '../vendor/autoload.php';
if (pathinfo($_FILES['upexcel']['name'], PATHINFO_EXTENSION) == 'csv') {
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
} else {
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
}
$spreadsheet = $reader->load($_FILES['upexcel']['tmp_name']);
$worksheet = $spreadsheet->getActiveSheet();
$sql = "INSERT INTO `testCommission` (`One`, `two`, `three`, `four`, `five`, `six`, `seven`) VALUES (?, ?, ?, ?, ?, ?, ?)";
foreach ($worksheet->getRowIterator() as $row) {
// Fetch data
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false);
$data = [];
foreach ($cellIterator as $cell) {
$data[] = $cell->getValue();
}
What can I do to achieve this with the above script?
You need to detect, when it is the first row, a binary variable like this helps
<?php
require '../vendor/autoload.php';
if (pathinfo($_FILES['upexcel']['name'], PATHINFO_EXTENSION) == 'csv') {
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
} else {
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
}
$spreadsheet = $reader->load($_FILES['upexcel']['tmp_name']);
$worksheet = $spreadsheet->getActiveSheet();
$sql = "INSERT INTO `testCommission` (`One`, `two`, `three`, `four`, `five`, `six`, `seven`) VALUES (?, ?, ?, ?, ?, ?, ?)";
$isheader = 0;
foreach ($worksheet->getRowIterator() as $row) {
// Fetch data
if($isheader > 0) {
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false);
$data = [];
foreach ($cellIterator as $cell) {
$data[] = $cell->getValue();
}
} else
{ $isheader = 1; }
}
?>
Use a filter class.
See docs:
https://phpspreadsheet.readthedocs.io/en/latest/topics/reading-files/#reading-only-specific-columns-and-rows-from-a-file-read-filters
Don't forget the autoload:
require_once ( 'vendor/autoload.php' );
Create a filter:
class FirstRowFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
{
public function readCell($column, $row, $worksheetName = '') {
// Return true for rows after first row
return $row > 0;
}
}
Apply to the reader:
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader("Xlsx");
$filterRow = new FirstRowFilter();
$reader->setReadFilter($filterRow);
Load file:
$spreadsheet = $reader->load($file);
The reader will only load rows after the specified row.

How do I skip first row of Excel in order to upload into my database

I'm still at the first stage of learning. Here is my problem: I want to skip the first row of an Excel file to upload it into the database. I hope you can help me to solve this.
Here is the code:
$Reader = new SpreadsheetReader($targetPath);
$sheetCount = count($Reader->sheets());
for($i=0;$i<$sheetCount;$i++)
{
$Reader->ChangeSheet($i);
foreach ($Reader as $Row)
{
$period = "";
if(isset($Row[0])) {
$period = mysqli_real_escape_string($conn,$Row[0]);
}
$target = "";
if(isset($Row[1])) {
$target = mysqli_real_escape_string($conn,$Row[1]);
}
$achieved = "";
if(isset($Row[2])) {
$achieved = mysqli_real_escape_string($conn,$Row[2]);
}
$batch = "";
Use continue to skip processing for just the first row.
foreach ($Reader as $index => $Row) {
if ($index === 0) {
continue;
}
// process $Row
}
This assumes $Reader has a zero-based index.

PHP mysql import data through excel

I want to import data using php mysql from excel sheet containing 1.6 million records. What is the best way to do this?
this is the sample code I have used to iterate excel file and insert data in database:
public function iterateData($file_name) {
$fileDirectory = '';
$file_name = $fileDirectory . $file_name;
if (file_exists($file_name)) {
$this->truncateTable();
include 'PHPExcel2/Classes/PHPExcel/IOFactory.php';
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objPHPExcel = $objReader->load($file_name);
$count = 1;
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
foreach ($worksheet->getRowIterator() as $row) {
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(true); // Loop all cells, even if it is not set
$cellValues = array();
foreach ($cellIterator as $cell) {
if (!is_null($cell)) {
$cellValues[] = $cell->getCalculatedValue();
}
}
if (isset($cellValues[0]) && $cellValues[0] != 'Product' && $cellValues[0] != '') {
$this->inserInDatabase($cellValues);
} elseif (empty($cellValues[0]) && empty($cellValues[1]) && empty($cellValues[2])) {
continue;
}
}
if ($objPHPExcel->getSheetCount() == $count) {
return TRUE;
}
$count++;
}
} else {
return FALSE;
}
} private function inserInDatabase($data) {
$dbDetails = array(
'db_name' => '*',
'db_pass' => '*',
'db_host' => 'localhost',
'db_user' => '*'
);
$dbh = dbConnect::connect($dbDetails);
$date = date('Y-m-d H:i:s');
$sql = "INSERT INTO product_description (product_id, prpoduct_description, price, created_date) values ('" . mysql_escape_string($data[0]) . "', '" . mysql_escape_string($data[1]) . "', '" . mysql_escape_string($data[2]) . "', '$date')";
if (!$dbh->dbh->query($sql)) {
die('Database Connection Failed.');
}
}
export you excel data to csv format, and then import the csv format to mysql
you can import using ;
if($request->hasFile('excelFile')){
$inputFileType = 'Xlsx';
$inputFileName = $request->file('excelFile')->getRealPath();
/** Create a new Reader of the type defined in $inputFileType **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Advise the Reader that we only want to load cell data **/
$reader->setReadDataOnly(true);
/** Load $inputFileName to a Spreadsheet Object **/
$spreadsheet = $reader->load($inputFileName);
foreach ($spreadsheet->getActiveSheet()->toArray() as $key => $row) {
$data['question'] = $row[0];
$data['option1'] = $row[1];
$data['option2'] = $row[2];
$data['option3'] = $row[3];
$data['option4'] = $row[4];
$data['correct'] = $row[5];
$data['status'] = 1;
$data['receiver'] = 'all';
$data['createdOn'] = date("Y-m-d H:i:s");
if(!empty($data)) {
DB::table('questions')->insert($data);
}
}
}

Excel functions showing as it is when converting excel to CSV in php

We are converting excel to CSV with every sheet. For example if a excel file has 5 sheets then we are converting 5 CSV file for every sheet.
Its working fine except one thing.
As we know excel sheet has some formulas for calculation like sum, Average etc..., So when we are converting them to CSV file, Then function is showing as it is, Their calculated value is not showing, which we can read as a excel sheet.
This is the function which we are using
function write_csv($filename,$definename){
$dir = "";
$file_arr = array();
array_push($file_arr, $filename);
// Make CSV File
$list = array();
foreach($file_arr as $val)
{
$arr_data = array();
// echo $val;
$objPHPExcel = PHPExcel_IOFactory::load($dir . $val);
// print_r($objPHPExcel->getSheetNames());exit;
$loadedSheetNames = $objPHPExcel->getSheetNames();
foreach($loadedSheetNames as $sheetIndex => $loadedSheetName) {
// echo $sheetIndex;
$objPHPExcel->setActiveSheetIndex($sheetIndex);
$fp = fopen($definename.'_'.$sheetIndex.'.csv', 'a');
$cell_collection = $objPHPExcel->getActiveSheet()->getCellCollection();
// print_r($cell_collection);
foreach($cell_collection as $cell)
{
$column = $objPHPExcel->getActiveSheet()->getCell($cell)->getColumn();
$row = $objPHPExcel->getActiveSheet()->getCell($cell)->getRow();
$data_value = $objPHPExcel->getActiveSheet()->getCell($cell)->getValue();
//header will / should be in row 1 only. of course this can be modified to suit your need.
// Skip Rows From Top if you have header in Excel then Change 0 to 1
if($row == 0)
{
$header[$row][$column] = $data_value;
}
else
{
$arr_data[$row]['row'] = $row;
$arr_data[$row][$column] = $data_value;
}
}
$data = $arr_data;
foreach($data as $val1)
{
$num_col = sizeof($val1) - 1; // get number of columns in Excel
break;
}
$lwrcol=array();
foreach($data as $val2)
{
$alphaArr = range('A','Z');
$colArr = range('A',$alphaArr[$num_col - 1]);
foreach($colArr as $col)
{
$lwrcol[$col] = isset($val2[$col]) ? utf8_decode($val2[$col]) : "";
fwrite($fp,$lwrcol[$col].",");
}
fwrite($fp,"\n");
}
// chmod(getcwd()."/file.csv", 0777);
fclose($fp);
}
}
}
Please tell me what we are doing wrong.
Complete Code:
http://pastebin.com/DaRBSpqP

PHPExcel -> creating duplicate worksheets

I am trying to create a application that will parse a CSV file of items, and do specific things for each item in the CSV file. I have the upload/parsing figured out, however, when I export it to Excel each CSV entry is duplicated in the worksheets. For example, if there were 4 entries in the CSV file, the first entry is duplicated 4 times, the second entry is duplicated 3 times, etc. I have look through documentation for days, and I am unable to locate where I am going wrong. Below is the code that is generating the XLSX file.
if (in_array($type,$csv_types)){
if (move_uploaded_file($tmp_name, $path)){
foreach ($csv as $locar){
foreach ($locar as $locid){
$locs[] = $locid;
$count = count($locs);
/*if ($i < $count - 1){
$objPHPExcel->createSheet();
$i++;
}*/
$xmls = array();
foreach ($locs as $locids){
$url = 'Link to XML API' . $locids;
$xmls[] = $url;
$objWorkSheet = $objPHPExcel->createSheet();
$objWorkSheet->setTitle($locids);
$objPHPExcel->setActiveSheetIndexByName($locids);
}
foreach ($xmls as $links){
$locations = explode("=", $links);
$row = 1;
//
$objPHPExcel->getActiveSheet()->setCellValue('A'.$row,'Location ID:' . $locations[1]);
$row++;
$objPHPExcel->getActiveSheet()->SetCellValue('A'.$row,'Database');
$objPHPExcel->getActiveSheet()->SetCellValue('B'.$row,'URL');
$row++;
$xml = simplexml_load_file($links);
foreach ($xml as $product){
foreach ($product->title as $item){
$dbtitle = str_replace(',',' ',$item);
$dblink = $product->link;
}
$objPHPExcel->setActiveSheetIndexByName($locations[1]);
$objPHPExcel->getActiveSheet()->SetCellValue('A'.$row,$dbtitle);
$objPHPExcel->getActiveSheet()->SetCellValue('B'.$row,$dblink);
$row++;
}
}
}
}
}
The Links that are generated by the code are only showing up in the correct worksheet (the first created worksheet for the entry in the csv). Any help would be greatly appreciated.
Try this...
if (in_array($type,$csv_types)){
if (move_uploaded_file($tmp_name, $path)){
foreach ($csv as $key => $locar){
$locs[] = $locid[$key];
$count = count($locs);
/*if ($i < $count - 1){
$objPHPExcel->createSheet();
$i++;
}*/
$xmls = array();
$url = 'Link to XML API' . $locids[$key];
$xmls[] = $url;
$objWorkSheet = $objPHPExcel->createSheet();
$objWorkSheet->setTitle($locids[$key]);
$objPHPExcel->setActiveSheetIndexByName($locids[$key]);
$locations = explode("=", $links[$key]);
$row = 1;
//
$objPHPExcel->getActiveSheet()->setCellValue('A'.$row,'Location ID:' . $locations[1]);
$row++;
$objPHPExcel->getActiveSheet()->SetCellValue('A'.$row,'Database');
$objPHPExcel->getActiveSheet()->SetCellValue('B'.$row,'URL');
$row++;
$xml = simplexml_load_file($links[$key]);
foreach ($xml as $product){
foreach ($product->title as $item){
$dbtitle = str_replace(',',' ',$item);
$dblink = $product->link;
}
$objPHPExcel->setActiveSheetIndexByName($locations[1]);
$objPHPExcel->getActiveSheet()->SetCellValue('A'.$row,$dbtitle);
$objPHPExcel->getActiveSheet()->SetCellValue('B'.$row,$dblink);
$row++;
}
}
}
}
Also can you post the $xml array (print_r)...
$xml = simplexml_load_file($links[$key]);

Categories