Hello i have an import of an xls file with multiple rows on it and i want to insert them into database only if the price columns has a value different than nothing else display an error msg. It works on half it only inserts those rows that have a value for price but instead returning the html error msg it returns the sql msg, that means it goes on the else branch.
Here is my code
$exceldata = array();
$uploadFilePath = 'uploads/'.basename($_FILES['doc']['name']);
move_uploaded_file($_FILES['doc']['tmp_name'], $uploadFilePath);
$inputfilename = 'uploads/'.$_FILES['doc']['name'].'';
// Read your Excel workbook
try
{
$inputfiletype = PHPExcel_IOFactory::identify($inputfilename);
$objReader = PHPExcel_IOFactory::createReader($inputfiletype);
$objPHPExcel = $objReader->load($inputfilename);
}
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();
$header=$_POST['membership'];
if($header==1)
{
// Loop through each row of the worksheet in turn
for ($row = 1; $row <= $highestRow; $row++)
{
// Read a row of data into an array
$rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, NULL, TRUE, FALSE);
if ($rowData[0][9]=='')
{
echo 'No price for the product '.$rowData[0][1].'';
}
else
{
$a = array('8', '1', '2', '3', '4', '5','6');
$b = array($rowData[0][0], $rowData[0][2], $rowData[0][3],$rowData[0][5],$rowData[0][6],$rowData[0][8],$rowData[0][8]);
$c = array_combine($a, $b);
$slug = str_replace(" ", "-",$rowData[0][1]);
$slug = str_replace('"', "",$slug);
$slug = str_replace('/', "-",$slug);
$stmt=$dbh->prepare("INSERT INTO tbl_products (name,slug,description,price)
VALUES (:name,:slug,:desc,:pret)");
$stmt->bindParam(":name",$rowData[0][1]);
$stmt->bindParam(":slug",$slug);
$stmt->bindParam(":desc",$rowData[0][10]);
$stmt->bindParam(":pret",$rowData[0][9]);
$stmt->execute();
$id_product=$dbh->lastInsertId();
$stmt=$dbh->prepare("INSERT INTO tbl_products_images_gallery (id_product,name,image,sort_order)
VALUES (:id,:name,:image,100)");
$stmt->bindParam(":id",$id_product);
$stmt->bindParam(":name",$rowData[0][4]);
$stmt->bindParam(":image",$slug);
$stmt->execute();
$stmt=$dbh->prepare("SELECT id_category from tbl_catalog_categories where name=:name");
$stmt->bindParam(":name",$rowData[0][2]);
$stmt->execute();
if($row=$stmt->fetch())
{
$id_cat=$row['id_category'];
}
$stmt=$dbh->prepare("INSERT INTO tbl_products_to_categories (id_category,id_product)
VALUES (:id_cat,:id_prod)");
$stmt->bindParam(":id_cat",$id_cat);
$stmt->bindParam(":id_prod",$id_product);
$stmt->execute();
foreach($c as $key => $value)
{
$stmt=$dbh->prepare("INSERT INTO tbl_products_attributes_values (id_product,id_attribute,attribute_value)
VALUES (:id_product,:id_attribute,:value)");
$stmt->bindParam(":id_product",$id_product);
$stmt->bindParam(":id_attribute",$key);
$stmt->bindParam(":value",$value);
$stmt->execute();
}
}
}
}
if (empty($rowData[0][9])) perhaps?
Or test for null as well as for empty strings - nulls are perfectly valid response from PHPExcel...
especially as
$rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, NULL, TRUE, FALSE);
with it's null second argument is telling PHPExcel to return a null value if the cell simply doesn't exist in the spreadsheet
Though you can change the rangeToArray() call to
$rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, '', TRUE, FALSE);
to return an empty string instead of a null if the cell doesn't exist
Related
I'm using the column header as an array index (row 1), and I don't want to have problems when they start uploading their XLSX file with incorrect column headers (or sometimes missing).
I found this answer really useful. I can make my array indexes as column headers:
for ($row = 2; $row <= $highestRow; $row++){
// Read a row of data into an array
$rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row,
NULL,
TRUE,
FALSE);
$rowData[0] = array_combine($headings[0], $rowData[0]);
}
The code above is from https://stackoverflow.com/a/32526911/8191721
Here's what I want to happen:
Check first the column headers if they matches with the column
headers I provided (in array, so I can use in_array in a loop) before
writing it to the database.
If the headers are correct, I will now turn the array indexes to column headers (so instead of [0], it should now return [firstname]) or else throw an error message.
Write to database where the column names in my database exactly matches the column header names (or if not, at least matches the query) in their XLSX file. (I called them "column mapping").
Long story short, here's my code:
try {
$inputFileName = $_FILES['file']['tmp_name'];
$inputFileType = PHPExcel_IOFactory::identify($inputFileName);
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFileName);
//-- Get worksheet dimensions
$sheet = $objPHPExcel->getSheet(0);
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
$headings = $sheet->rangeToArray('A1:'.$highestColumn.'1', NULL, TRUE, FALSE);
//-- $row = 2 <- skip row 1 since this is our headers
for($row = 2; $row <= $highestRow; $row++) {
//-- Read a row of data into an array
$xlsxRow = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, NULL, TRUE, FALSE);
//-- Combine to replace indexes with header names
$xlsxRow[0] = array_combine($headings[0], $xlsxRow[0]);
//-- Got stucked in here..
/*
If column header fails, should exit the loop
*/
//-- SQL query follows here..
}
So can someone help me figuring this out?
To compare the header value you can use array_diff() function.
If you want to give more flexibility to user then you can use following example.
In this case use
$excelSheetHeaders = array();
for ($i = 1; $i <= 1; $i++) {
$rowData = $sheet->rangeToArray('A' . $i . ':' . $highestColumn . $i, NULL, TRUE, FALSE);
$excelSheetHeaders = $rowData[0];
$excelSheetHeaders = array_map('strtolower', $excelSheetHeaders);
$errorCount = 0;
foreach ($headerArray as $index => $value){
if(!in_array(strtolower($value), $excelSheetHeaders)){
$errorCount++;
}
}
if($errorCount > 0){
//Throw Error and exit;
}
}
for ($i = 2; $i <= $highestRow; $i++){
$rowData = $sheet->rangeToArray('A' . $i . ':' . $highestColumn . $i,NULL,TRUE,FALSE);
$spreadsheetData = array();
foreach($headerArray as $index => $value){
$spreadsheetData[$value] = $rowData[0][array_search(strtolower($value),$excelSheetHeaders)];
}
var_dump($spreadsheetData);
}
This error is exactly what you want. Now you can access $spreadsheetData['firstName'].
I am trying to parse an Excel file. I am able to get the contents of individual cells of the excel. I am unable to add the data I got from the cell into an array.
function parseExcel($inputFileName){
$mh = new MainHandler;
// Read your Excel workbook
try {
$inputFileType = PHPExcel_IOFactory::identify($inputFileName);
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFileName);
}catch(Exception $e) {
die('Error loading file "'.pathinfo($inputFileName,PATHINFO_BASENAME).'": '.$e->getMessage());
}
$Arr = array();
// Get worksheet dimensions
$sheet = $objPHPExcel->getActiveSheet();
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
for ($row = 1; $row <= $highestRow; $row++){
$myArray = array();
for($col = 'A' ; $col <= $highestColumn ; $col++){
$a = $sheet->getCell($col.$row);
// echo "\n".$a;
$myArray[] = $a;
}
// $Arr[] = $myArray;
echo json_encode($myArray);
}
// echo json_encode($Arr);
}
The output i get is
[{},{},{},{},{}][{},{},{},{},{}][{},{},{},{},{}]
What should be done to get the populated array as output?
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);
}
}
}
This is the PHP code, I don't know much about PHPExcel to make it run faster, ideally I don't want to limit to 10000 rows (still takes at least 5 minutes before it sends the excel file)
Any ideas?
The script basically selects all data from the sqlite database then it loops the keys of the first row to add as titles for the columns.
Then it loops all rows and sets each cell value.
After this it adds the formula columns.
Then sends the excel data to the user.
The script is run at: http://example-site.org/getStatsExcel.php - so each time a user goes to that page, it runs this script - I think I should store the database per day and if it's already stored for that day, then just return the file, else generate the excel again...
<?php
date_default_timezone_set('Europe/Zurich');
require_once 'phpexcel/Classes/PHPExcel.php';
ini_set('max_execution_time', 900);
$dbname = 'admin';
$fullPath = sprintf('/var/www/fullpathtosqlite/%s.sqlite', $dbname);
$dbh = new PDO('sqlite:' . $fullPath);
$phpExcel = new PHPExcel();
$phpExcel->getProperties()->setTitle('Export : Statistics');
$phpExcel->getProperties()->setCreator('PHPExcel Stats Script');
$sheet = $phpExcel->getActiveSheet();
$sheet->setTitle('stats');
$phpExcel->setActiveSheetIndex(0);
$sql = 'SELECT * FROM (SELECT * FROM statistics ORDER BY timestamp DESC LIMIT 10000) ORDER BY timestamp ASC';
if(!$stmt = $dbh->prepare($sql, array(PDO::ATTR_CURSOR, PDO::CURSOR_SCROLL))) {
die(var_export($dbh->errorinfo(), TRUE));
}
$stmt->execute();
// Fetch the first row
$row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT);
$results = array();
// Iterate over the results and print each one in a line
while ($row != false) {
$results[] = $row;
// Fetch the next line
$row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT);
}
$row = 1;
$col = 0;
foreach ($results[0] as $key => $value) {
$sheet->setCellValueByColumnAndRow($col, $row, $key);
$col++;
}
// date
$sheet->setCellValueByColumnAndRow($col, $row, 'date');
$col++;
// time
$sheet->setCellValueByColumnAndRow($col, $row, 'time');
$col++;
// full_date
$sheet->setCellValueByColumnAndRow($col, $row, 'full_date');
$row = 2;
foreach ($results as $result) {
$col = 0;
foreach ($result as $key => $value) {
$sheet->setCellValueByColumnAndRow($col, $row, $value);
$col++;
}
// date
$sheet->setCellValueByColumnAndRow($col, $row, '=DATE(LEFT(A' . $row . ',4),MID(A' . $row . ',5,2),MID(A' . $row . ',7,2))');
$col++;
// time
$sheet->setCellValueByColumnAndRow($col, $row, '=TIME(MID(A' . $row . ',9,2),MID(A' . $row . ',11,2),MID(A' . $row . ',13,2))');
$col++;
// full_date
$sheet->setCellValueByColumnAndRow($col, $row, '=F' . $row . '+G' . $row);
$row++;
}
$sheet->getStyle('F2:F' . $row)
->getNumberFormat()
->setFormatCode('dd/mm/yyyy');
$sheet->getStyle('G2:G' . $row)
->getNumberFormat()
->setFormatCode('h:mm AM/PM');
$sheet->getStyle('H2:H' . $row)
->getNumberFormat()
->setFormatCode('dd/mm/yyyy hh:mm');
foreach(range('A','H') as $columnID) {
$sheet->getColumnDimension($columnID)->setAutoSize(true);
}
header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=\"statistics.xls\"");
header("Cache-Control: max-age=0");
$objWriter = PHPExcel_IOFactory::createWriter($phpExcel, "Excel5");
$objWriter->save("php://output");
exit;
The more data you're working with, the longer it will take. That's why we recommend that generating large spreadsheets should be farmed off to a back-end process so that it doesn't leave the user waiting while it builds the spreadsheet.
If you can build these large data spreadsheets "offline", then do so; if you can cache them, then do so.
I have the following code that does a great job sending data to excel sheet. In the database I have values under a column say k i have values which are comma separated e.g. alphonce, ochieng, abc, so for each value/word, i want to create a new row so that alphonce is in the new row in a given cell same as ochieng etc, like generated table rows holding the names.
$trd = $this->getRequestedTestsDisplay2($labref);
$coa_details = $this->getAssayDissSummary($labref);
$row = 26;
$worksheet = $objPHPExcel->getActiveSheet();
for ($i = 0; $i < count($trd); $i++) {
$col = 1;
foreach ($coa_details as $coa) {
if ($coa->test_id == $trd[$i]->test_id) {
$determined = $coa->determined;
$remarks = $coa->verdict;
}
}
$worksheet
->setCellValueByColumnAndRow($col++, $row, $trd[$i]->name)
->setCellValueByColumnAndRow($col++, $row, $trd[$i]->methods)
->setCellValueByColumnAndRow($col++, $row, $trd[$i]->compedia);
$worksheet->setCellValueByColumnAndRow($col++, $row, str_replace(",", "\n", $trd[$i]->specification));
$worksheet->setCellValueByColumnAndRow($col++, $row, str_replace(",", "\n",$determined));
$worksheet->setCellValueByColumnAndRow($col++, $row, str_replace(",", "\n", $trd[$i]->complies));
$worksheet->getStyle($col++ . $row)->getAlignment()->setWrapText(true);
$worksheet->getRowDimension($row)->setRowHeight(-1);
$row++;
}
}
$myData = "Hello,World";
// Write data to cell A1, replacing comma with a new line character
$worksheet->setCellValueByColumnAndRow(1, 1, str_replace(",", "\n", $myData));
// Set the cell alignment to wrap the text
$worksheet->getStyle('A1')->getAlignment()->setWrapText(true);
// Set the row height to automatically adjust to the number of lines
// of data in the cell
$worksheet->getRowDimension(1)->setRowHeight(-1);