In PHP, I am looping through an excel file and inserting it into an MSSQL database. I am getting this error:
Uncaught exception 'PHPExcel_Exception' with message 'Invalid cell coordinate A'
I don't get this error if I only run one of the queries in the loop. Separately, both queries work. So I am pretty sure it has to do with the fact that the 2 queries are running. With the following code, there is one row inserted in both tables and then the error. Any ideas on how to fix this?
Heres the code...
$dbc = odbc_connect(DB_DRIVER, DB_USER, DB_PASSWORD);
$inputFileName = 'lib/test.xlsx';
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();
// Loop through each row of the worksheet in turn
for ($row = 2; $row <= $highestRow; $row++){
// Read a row of data into an array
$rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row,
NULL,
TRUE,
FALSE);
$name = ms_escape_string($rowData[0][0]);
$city = ms_escape_string($rowData[0][2]);
$state = ms_escape_string($rowData[0][3]);
$phone = ms_escape_string($rowData[0][4]);
$website = ms_escape_string($rowData[0][5]);
$profit_status = ms_escape_string($rowData[0][6]);
$query = "insert into account2 ([name], [city], [state], [phone], [website], [type], [created_by], [last_modified_by])
values ('$name', '$city', '$state', '$phone', '$website', '6', '3', '3')
SELECT SCOPE_IDENTITY() AS ins_id";
$data = odbc_exec($dbc, $query);
if (odbc_next_result($data)){
while ($row = odbc_fetch_object($data)) {
$account_id = $row->ins_id;
}
$query = "insert into account_hic2 (account_id, profit_status)
values ('$account_id', '$profit_status')";
}
$data2 = odbc_exec($dbc, $query);
odbc_free_result($data);
odbc_free_result($data2);
}
The error message suggests that you're mis-setting the value of $row at some point, perhaps setting it to null, or to an empty string...
... or perhaps to a resource, as you're using the same variable name in your database fetch in the same loop where you're using it to keep track of the Excel row number
Related
I have written a scraper in php using simple html Dom.
Problem is that it returns the results but gives me an error
Can anyone point me in the right direction on how to fix it please
Error is:
Notice: Trying to get property of non-object in C:\xampp\htdocs\scraper\au_div_puller.php on line 60
Many thanks
Line 60 is
$Ex_Date = $tr->find('td', 0)->plaintext; // Find the first TD (starts with 0)
<?php
//REQUIRED FILES
require ('connect_mysql.php');
require('simple_html_dom.php');
//SET VARIABLES OF WEBSITE TO CRAWL
$url = ('http://www.shares.com/ANZ'); //WEBSITE TO SCRAPE WITH MYSQL INJECTED FROM ABOVE
echo ($url . "<br>");
//SET USER AGENT TO BE GOOGLEBOT
$opts = array ('http'=>array( 'method'=>"GET", 'header' => 'User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)', ));
$context = stream_context_create($opts);
//$html = new simple_html_dom();
$response = file_get_html($url, false, $context);
$html = str_get_html($response);
//CHECK IT IS NOT A 404 PAGE IF SO SKIP
if (!empty($html)) {
//CHECK IT IS NOT BLANK PAGE OR EMPTY PAGE IF SO SKIP
$count = count($html->find('table'));
if($count > 0){
//START TABLE PROCESSING
$table = $html->find('table', 0); // ID LOCK IE TABLE 0 (first table) Get the first table ??
foreach($table ->find('tr') as $tr) { // Foreach row in the table!
$Ex_Date = $tr->find('td', 0)->plaintext; // Find the first TD (starts with 0)
if($Ex_Date == "" || $Ex_Date == " ") continue; // Don't allow empty records
$Amount = $tr->find('td', 1)->plaintext; // Find the second TD (which will be 1)
$Franked = $tr->find('td', 2)->plaintext; // Find the third TD (which will be 2)
$Franking_Credit = $tr->find('td', 3)->plaintext; // Find the fourth TD (which will be 3)
$Books_Close = $tr->find('td', 4)->plaintext; // Find the fifth TD (which will be 4)
$Date_Payable = $tr->find('td', 5)->plaintext; // Find the sixth TD (which will be 5)
//MYSQL DATA FORMATTING
//ESCAPE STRINGS AND DATE FORMATTING
//Now validate the data with mysqli_real_escape_string(). This function will escape characters that cause problems, like single quotes.
//Note there needs to be an open connection to the MySQL server for this work, otherwise you'll have blank strings returned.
// convert 04-Dec-1997 to yyyy-mm-dd formate
// for other versions of date format see: https://stackoverflow.com/questions/16139696/convert-date-to-mysql-date-format-php
$Ex_Date_c = mysqli_real_escape_string($conn, $Ex_Date);
$Ex_Date_c = date('Y-m-d', strtotime($Ex_Date_c)); //fix date format
$Amount_c = mysqli_real_escape_string($conn, $Amount);
$Franked_c = mysqli_real_escape_string($conn, $Franked);
$Franking_Credit_c = mysqli_real_escape_string($conn, $Franking_Credit);
$Books_Close_c = mysqli_real_escape_string($conn, $Books_Close);
$Books_Close_c = date('Y-m-d', strtotime($Books_Close_c));//fix date format
$Date_Payable_c = mysqli_real_escape_string($conn, $Date_Payable);
$Date_Payable_c = date('Y-m-d', strtotime($Date_Payable_c));//fix date format
//MYSQL INSERT TIME AND TESTING
//MYSQL INSERT QUERY
$sql = "INSERT INTO $insertintotable (stockcode, exchange, exdate, amount, franked, frankingcredit, booksclose, datepayable, updatedatetime)
VALUES ('$stockcode', 'ASX', '$Ex_Date_c', '$Amount_c', '$Franked_c', '$Franking_Credit_c', '$Books_Close_c', '$Date_Payable_c', '$updatedatetime')";
//MYSQL RESULT TEST
//echo ($sql . "<br>"); // Show the Mysql query
if ($conn->query($sql) === TRUE) {
// echo "New record created successfully <br>"; //TESTING --- Uncomment this code after verifying that the echo statements produce valid INSERT queries.
}
else {echo "Error: " . $sql . "<br>" . $conn->error;}
}
}
}
}
// CLOSE AND CLEAR SESSION
$html->clear();
unset($html);
}
$conn->close();
?>
This is a prepared statement I could use that I copied off a learning site
// prepare and bind
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);
// set parameters and execute
$firstname = "John";
$lastname = "Doe";
$email = "john#example.com";
$stmt->execute();
$firstname = "Mary";
$lastname = "Moe";
$email = "mary#example.com";
$stmt->execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "julie#example.com";
$stmt->execute();
echo "New records created successfully";
$stmt->close();
$conn->close();
Since you can't guarantee that find('td', 0) will find a value, you must guarantee that you don't try to ask for the property plaintext if there is no td found.
$table = $html->find('table', 0); // ID LOCK IE TABLE 0 (first table) Get the first table ??
foreach($table ->find('tr') as $tr) { // Foreach row in the table!
if($td = $tr->find('td', 0)) {
$Ex_Date = $td->plaintext; // Find the first TD (starts with 0)
// ... and so on for each variable
Granted, it's not as sexy as chaining them together, but the chaining only works if you know that the first method ($td in my example) will always return an object having the method/property you're calling.
On a side note, you should also look at using prepared statements (values(?,?,?,?,?,?,?,?)) instead of sticking values into your $sql variable.
I have a script to upoad an excel file and insert data from the xlsx file to a mysql table . It is like this
<?php
require_once('Connections/met.php');
$file = './uploads/windrose_data.xlsx';
if (move_uploaded_file($_FILES['uploadfile']['tmp_name'], $file)) {
$msg="File upload successful";
$db=mysql_select_db($database_met,$met);
set_include_path(get_include_path() . PATH_SEPARATOR . 'Classes/');
include 'PHPExcel/IOFactory.php';
// This is the file path to be uploaded.
$inputFileName = $file;
try {
$objPHPExcel = PHPExcel_IOFactory::load($inputFileName);
} catch(Exception $e) {
die('Error loading file "'.pathinfo($inputFileName,PATHINFO_BASENAME).'": '.$e->getMessage());
}
$allDataInSheet = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
$arrayCount = count($allDataInSheet); // Here get total count of row in that Excel sheet
for($i=2;$i<=$arrayCount;$i++){
$date = trim($allDataInSheet[$i]["A"]);
$time = trim($allDataInSheet[$i]["B"]);
$dir = trim($allDataInSheet[$i]["C"]);
$spd = trim($allDataInSheet[$i]["D"]);
$insertTable= mysql_query("insert into wr_copy (date,time,dir,spd) values('$date', '$time',$dir,$spd)") or die(mysql_error());
$msg=$i-1." records inserted into the table";
}
echo $msg;
} else {
echo "Upload Failed";
}
?>
here for each row in excel one insert statement is executed., then I am sending a response using the iteration variable as the number of records inserted. There are two issues, one, I want to use a single insert statement which can be used for inserting all the rows in excel. second issue is using iterating variable values as no. of records can be a problem because, the query may not execute if there is any error in data. Can anybody suggest a work around for this?
For creating the one statement:
$statement = 'insert into wr_copy (date,time,dir,spd) values';
$values = [];
for($i=2;$i<=$arrayCount;$i++){
$date = trim($allDataInSheet[$i]["A"]);
$time = trim($allDataInSheet[$i]["B"]);
$dir = trim($allDataInSheet[$i]["C"]);
$spd = trim($allDataInSheet[$i]["D"]);
$values[] = "('$date', '$time',$dir,$spd)";
}
$statement .= implode(',',$values);
To get the real numbers of records that are inserted (i copied the example from here and change it):
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* prepare statement */
if ($stmt = $mysqli->prepare($statement)) {
/* execute statement */
$stmt->execute();
printf("rows inserted: %d\n", $stmt->affected_rows);
/* close statement */
$stmt->close();
}
/* close connection */
$mysqli->close();
?>
I have used the following code to read the data of exceltodb.xlsx file and import it into the table city of database world. The library to read the file is PHPExcel which is very common library.The code I found is as follows but the code is executing but the row is not added into the database.
<?php
include 'PHPExcel-develop/Classes/PHPExcel/IOFactory.php';
$inputFileName = 'exceltodb.xlsx';
// Read your Excel workbook
try {
$inputFileType = PHPExcel_IOFactory::identify($inputFileName);
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load('exceltodb.xlsx');
} 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();
// 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);
// Insert row data array into your database of choice here
mysql_connect('localhost','root','');
mysql_select_db('world');
mysql_query('insert into city("city","id","stateid","countryid") values("$rowData")');
}
?>
This code segment will upload your xml data sheet in to a particular location in the server:
<?php
$uploadedStatus = 0;
if ( isset($_POST["submit"]) ) {
if ( isset($_FILES["file"])) {
//if there was an error uploading the file
if ($_FILES["file"]["error"] > 0) {
echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
}
else {
if (file_exists($_FILES["file"]["name"])) {
unlink($_FILES["file"]["name"]);
}
$storagename = "discussdesk.xlsx";
move_uploaded_file($_FILES["file"]["tmp_name"], $storagename);
$uploadedStatus = 1;
}
} else {
echo "No file selected <br />";
}
}
?>
This will upload the data taken from xml to the database:
<?php
/************************ YOUR DATABASE CONNECTION START HERE ****************************/
define ("DB_HOST", "localhost"); // set database host
define ("DB_USER", ""); // set database user
define ("DB_PASS",""); // set database password
define ("DB_NAME",""); // set database name
$link = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die("Couldn't make connection.");
$db = mysql_select_db(DB_NAME, $link) or die("Couldn't select database");
$databasetable = "YOUR_TABLE";
/************************ YOUR DATABASE CONNECTION END HERE ****************************/
set_include_path(get_include_path() . PATH_SEPARATOR . 'Classes/');
include 'PHPExcel/IOFactory.php';
// This is the file path to be uploaded.
$inputFileName = 'discussdesk.xlsx';
try {
$objPHPExcel = PHPExcel_IOFactory::load($inputFileName);
} catch(Exception $e) {
die('Error loading file "'.pathinfo($inputFileName,PATHINFO_BASENAME).'": '.$e->getMessage());
}
$allDataInSheet = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
$arrayCount = count($allDataInSheet); // Here get total count of row in that Excel sheet
for($i=2;$i<=$arrayCount;$i++){
$userName = trim($allDataInSheet[$i]["A"]);
$userMobile = trim($allDataInSheet[$i]["B"]);
$query = "SELECT name FROM YOUR_TABLE WHERE name = '".$userName."' and email = '".$userMobile."'";
$sql = mysql_query($query);
$recResult = mysql_fetch_array($sql);
$existName = $recResult["name"];
if($existName=="") {
$insertTable= mysql_query("insert into YOUR_TABLE (name, email) values('".$userName."', '".$userMobile."');");
I'm trying to import CSV data into a MySQL database using the fgetcsv function.
if(isset($_POST['submit'])) {
$fname = $_FILES['sel_file']['name'];
$var = 'Invalid File';
$chk_ext = explode(".",$fname);
if(strtolower($chk_ext[1]) == "csv") {
$filename = $_FILES['sel_file']['tmp_name'];
$handle = fopen($filename, "r");
$res = mysql_query("SELECT * FROM vpireport");
$rows = mysql_num_rows($res);
if($rows>=0) {
mysql_query("DELETE FROM vpireport") or die(mysql_error());
for($i =1;($data = fgetcsv($handle, 10000, ",")) !== FALSE; $i++) {
if($i==1)
continue;
$sql = "INSERT into vpireport
(item_code,
company_id,
purchase,
purchase_value)
values
(".$data[0].",
".$data[1].",
".$data[2].",
".$data[3].")";
//echo "$sql";
mysql_query($sql) or die(mysql_error());
}
}
fclose($handle);
?>
<script language="javascript">
alert("Successfully Imported!");
</script>
<?
}
The problem is it gets stuck in between the import process and displays the following error:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'S',0,0)' at line 1
The file is imported only partially each time. Only between 200-300 lines out of a 10000 line file are imported.
Here is the DDL of my table:
create table vpireport (
id int not null auto_increment,
item_code int,
company_id int,
purchase double,
primary key(id),
foreign key(company_id) references users(userid)
);
I haven't been able to find the problem so far, any help appreciated. Thanks.
You probably need to escape quotes, which you could accomplish using PDO and prepared statements.
I've skipped most of your code in the example for brevity and just focused on the for loop.
<?php
// Use PDO to connect to the DB
$dsn = 'mysql:dbname=YOUR_DB;host=localhost';
$user = 'DB_USERNAME';
$password = 'DB_PASSWORD';
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
for($i =1;($data = fgetcsv($handle, 10000, ",")) !== FALSE; $i++) {
// The query uses placeholders for data
$sql = "INSERT INTO vpireport
(item_code,company_id,purchase,purchase_value)
VALUES
(:item_code,:company_id,:purchase,:purchase_value)";
$sth = $dbh->prepare($sql);
// The data is bound to the placeholders
$sth->bindParam(':item_code', $data[0]);
$sth->bindParam(':company_id', $data[1]);
$sth->bindParam(':purchase', $data[2]);
$sth->bindParam(':purhcase_value', $data[3]);
// The row is actually inserted here
$sth->execute();
$sth->closeCursor();
}
That won't get rid of any problem characters, though, so you may want to look at some kind of data sanitization if that poses a problem.
uncomment the //echo "$sql"; and look what is the last query (with error) - it may be that the csv data contains strange characters or the query is cut off.
BTW: you can also import csv file by mysql:
http://dev.mysql.com/doc/refman/5.1/en/load-data.html
$row = 1;
if (($handle = fopen("albums.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ',','"')) !== FALSE) {
if($row!=1){
$num = count($data);
$albumIndex=0;
//Insert into tbl_albums
$sqlAlbums="INSERT INTO tbl_albums(albumName) VALUES ('".$data[$albumIndex]."')";
$resultAlbums=mysql_query($sqlAlbums);
}
}
$row++;
}
}
fclose($handle);
I am wondering I have been trying to place me MySQL query and MySQL result code into a PHP function like this
function setting($claim){
$query = "SELECT `cases`, `hg`, `surname`, `firstname`, `type`, `claim`, `charge`, `damage`, `payment`, `repair`, `returned`, `comments`, `cost` FROM `rep_log` WHERE claim='$claim'";
$result = mysql_query($query) or die(mysql_error());
}
I'm trying to use this so that I can make it easier to change what is being selected without having to have heaps of different variables and stuff just to change the query... so basically what I do is
echo setting("warrenty");
But I'm getting an error:
Warning: mysql_fetch_row() expects parameter 1 to be resource, string given in ...
So I am wondering is it even possible to put a MySQL query and result into a function or is it just something which cannot happen...
If it is possible any help would be great.
COMPLETE CODE
<?
// connection with the database
$dbhost = "localhost";
$dbuser = "root";
$dbpass = "";
$dbname = "netbookdb";
$result="";
mysql_connect($dbhost,$dbuser,$dbpass);
mysql_select_db($dbname);
// require the PHPExcel file
require 'Classes/PHPExcel.php';
// simple query
function setting($claim){
$query = "SELECT `cases`, `hg`, `surname`, `firstname`, `type`, `claim`, `charge`, `damage`, `payment`, `repair`, `returned`, `comments`, `cost` FROM `rep_log` WHERE claim='$claim'";
$result = mysql_query($query) or die(mysql_error());
}
// Create a new PHPExcel object
$objPHPExcel = new PHPExcel();
$objPHPExcel->getActiveSheet()->setTitle('Insurance');
echo setting('Warrenty');
$rowNumber = 1;
while ($row = mysql_fetch_row($result)) {
$col = 'A';
foreach($row as $cell) {
$objPHPExcel->getActiveSheet()->setCellValue($col.$rowNumber,$cell);
$col++;
}
$rowNumber++;
}
// Save as an Excel BIFF (xls) file
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="myFile.xls"');
header('Cache-Control: max-age=0');
$objWriter->save('php://output');
exit();
echo 'a problem has occurred... no data retrieved from the database';
?>
You are not returning any result out of a function.
Use return $result;
UPDATE 1:
You have not decalred the $result variable which you are trying to use in mysql_fetch_row so first return the value from the function assign it and then use it.
UPDATE 2:
function setting($claim){
$query = "SELECT `cases`, `hg`, `surname`, `firstname`, `type`, `claim`, `charge`, `damage`, `payment`, `repair`, `returned`, `comments`, `cost` FROM `rep_log` WHERE claim='$claim'";
$result = mysql_query($query) or die(mysql_error());
return $result;
}
and then get the output of function in a variable which you are using in mysql_fetch_row method. i.e.
$result = setting('Warrenty');
Hope this helps.
You are assigning a local "$result" variable, so "mysql_fetch_row($result)" is using the string variable "$result", initialized as "$result = ''", that is not a resource and therefore will raise the exception.
In the "setting" function, put add "global $result;" line:
function setting($claim){
global $result;
$query = "...;
...
}