I'm new in PHPExcel library and this is my first experience. I'm trying to export MySQL data to Ms Excel by formatting before. I've implemented a procedure that simply formats headings of the table with bold fonts and saves them with all relevants data to the spreadsheet. However, when I run the procedure, it displays the following error:
Fatal error: Call to undefined function getRow() in C:\Xampp\htdocs\test.php on line 182
Here is the PHP code:
require_once 'PHPExcel.php';
require_once 'PHPExcel/IOFactory.php';
require_once 'PHPExcel/Writer/Excel2007.php';
// create mysql query
$query_export = "SELECT * FROM `table1` ORDER BY `date` ASC";
// execute query
$result = mysqli_query($GLOBALS['mysqli'], $query_export) or die ("<b>Couldn't execute SQL query:</b> " . mysqli_error($GLOBALS['mysqli']));
try {
$sheet = new PHPExcel();
// set metadata
$sheet->getProperties()->setCreator('www.example.com')
->setLastModifiedBy('www.example.com')
->setTitle('Report on Table')
->setKeywords('report tables etc.');
// set default settings
$sheet->getDefaultStyle()->getAlignment()->setVertical(
PHPExcel_Style_Alignment::VERTICAL_TOP);
$sheet->getDefaultStyle()->getAlignment()->setHorizontal(
PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$sheet->getDefaultStyle()->getFont()->setName('Calibri');
$sheet->getDefaultStyle()->getFont()->setSize(12);
// get reference to active spreadsheet in workbook
$sheet->setActiveSheetIndex(0);
$activeSheet = $sheet->getActiveSheet();
// populate with data
$row = getRow($result); // line 182
$colHeaders = array_keys($row);
$col = 'A';
$rownum = 1;
// set column headings
foreach ($colHeaders as $header) {
$activeSheet->setCellValue($col . $rownum, $header);
$activeSheet->getStyle($col . $rownum)->getFont()->setBold(true);
$activeSheet->getColumnDimension($col)->setAutoSize(true);
$col++;
}
// populate individual cells with data
do {
$col = 'A';
$rownum++;
foreach ($row as $value) {
$activeSheet->setCellValue($col++ . $rownum, $value);
}
} while ($row = getRow($result));
// setting headers
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename=Export.xlsx');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
$writer = PHPExcel_IOFactory::createWriter($sheet, 'Excel2007');
$writer->save('php://output');
exit();
} catch (Exception $e) {
$error = $e->getMessage();
}
// display error
if (isset($error)) {
echo "<p>" .$error. "</p>";
}
// free resultset
mysqli_free_result($result);
// close db connection
$GLOBALS['mysqli']->close();
exit();
Any help is appreciated.
UPDATE
The following tutorial is used to create above mentioned code:
http://www.youtube.com/watch?v=L6MQQvBi-ks
I believe you need to define getRow or use something like this:
http://php.net/manual/en/mysqli-result.fetch-row.php
Related
I have console app made in Symfony3, where user can import CSV file (which is validate) into database. I need to put records which haven't passed validation into separate file.
I use LeagueCSV to read CSV file and I try to use it to write unvalidated records but it doesn't work.
This is my code:
$reader = Reader::createFromPath($input->getArgument('lokalizacja'));
$reader->setDelimiter(';');
$reader->setHeaderOffset(0);
$results = $reader->getRecords();
foreach ($results as $row) {
$year = $row['description'];
$isValid = false;
if ($row['qty'] > 0 && $row['price'] > 0 && !empty($row['mpn'])) {
$isValid = true;
$rok = filter_var($row['description'], FILTER_SANITIZE_NUMBER_INT);
$product = (new Produkt())
->setMpn($row['mpn'])
->setQty($row['qty'])
->setYear($year)
->setPrice($row['price']);
$this->em->persist($product); }
if ($row['qty'] == 0 || $row['price'] == 0 || empty($row['mpn'])) {
$writer = Writer::createFromPath('/path/to/saved/file.csv', 'w+');
$writer->insertOne([$row['mpn'], $row['qty'], $row['price'],
$row['description']]);
continue;
}
}
$this->em->flush();
All records which passed validation are successfully saved in the database but I have problem with others records. In new CSV file I have only first, one record which haven't passed validation and nothing more. What am I doing wrong? I tried with
$writer->insertAll($results); //using an array
Or with if...else statment but that's nothing.
Also I made ...else statement where unvalidated records are saved in other table in database and its works but I don't know how to immediately convert them into CSV file.
Don't know symfony but CSV output is pretty simple. FWIW...
Pass this an array, like a fetchall resultset.
<?php
public function outputCSV($data, $useKeysForHeaderRow = true) {
if ($useKeysForHeaderRow) {
array_unshift($data, array_keys(reset($data)));
}
$outputBuffer = fopen("php://output", 'w');
foreach($data as $v) {
fputcsv($outputBuffer, $v);
}
fclose($outputBuffer);
}
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="FooBarFileName_' . date('Ymd') . '.csv"');
header("Pragma: no-cache");
header("Expires: 0");
$this->outputCSV($results);
If you look at the doc page for the writer you will see a warning at the top which states
When inserting records into a CSV document using League\Csv\Writer, first insert all the data that need to be inserted before starting manipulating the CSV. If you manipulate your CSV document before insertion, you may change the file cursor position and erase your data.
Your code calls
$writer = Writer::createFromPath('/path/to/saved/file.csv', 'w+');
$writer->insertOne([$row['mpn'], $row['qty'], $row['price'], $row['description']]);
In every iteration the condition is met, this appears to be overwriting or dropping your previous insert every time. You should declare the $writer once before the loop starts in order to preserve each insert.
$writer = Writer::createFromPath('/path/to/saved/file.csv', 'w+');
foreach ($results as $row) {
// do stuff with $writer
}
I have recently made a website and have a members table in my sql. I have an admin page that has the ability to download that with column names; however I used to use INTO OUTFILE but that is not allowed on my host. I came up with this code to download the file:
if(file_exists('downloads/members_'.date("m-d-Y").'.csv') == true) {
header("Location: /downloads/members_".date("m-d-Y").".csv");
}
$output = fopen('downloads/members_'.date("m-d-Y").'.csv', 'w+');
fputcsv($output, array('memberID','username', 'password', 'email', 'active', 'resetToken', 'resetComplete', 'support', 'supportToken' ));
$rows = mysql_query("SELECT * FROM members;");
while ($row = mysql_fetch_assoc($rows)) fputcsv($output,$row);
header("Location: /downloads/members_".date("m-d-Y").".csv");
exit;
This just outputs the column names and I have never used fputcsv before and am a tad confused on what I am doing wrong. I get the file to download but not with the table in it.
[EDIT] I just tried it with a valid sql query and it does not work. updated code above. Also There is stuff in the members table.
Try this:
if (isset($_POST['download'])) {
$result = mysql_query("SELECT * FROM members", $connection);
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename=yourcsv.csv');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
$csvoutput = fopen('php://output', 'w');
$row = getRow($result);
$headers = array_keys($row);//columns from db e.g, memberID','username',...
fputcsv($csvoutput, $headers);
fputcsv($csvoutput, $row);
while ($row = getRow($result)) {
fputcsv($csvoutput, $row);
}
fclose($csvoutput);
exit;
}
Here is your getRow() function:
function getRow($res){
return mysql_fetch_assoc($res);
}
And in your html:
<input type="submit" name="download" value="Download CSV">
Here is realtime demo with sqllite3 database. Uncomment the create database and insert statement in order to see the working demo. I have tested and it is working fine. I hope this will help you.
I am not really a PHP expert as my past experience is mostly geared towards the system engineering side.
I am facing a problem with PHPExcel which gives me this error "Cannot modify header information - headers already sent by in line 1" when I want to output my XLSX file to the browser.
Here is the sample of my code
$host="localhost";
$uname="lol";
$pass="lol123";
$database = "lol12345";
$table="MemReport";
$table1="CPUReport";
$table2="TrafficReport";
$table3="HDDReport";
// create a file pointer connected to the output stream
$output = fopen('Memory.csv', 'w+');
$output1 = fopen('CPU.csv', 'w+');
$output2 = fopen('Traffic.csv', 'w+');
$output3 = fopen('HDD.csv', 'w+');
// output the column headings
fputcsv($output, array('HostName','Date','Time','Percent','TholdDescription'));
fputcsv($output1, array('HostName','Date','Time','Percent','TholdDescription'));
fputcsv($output2, array('HostName','Date','Time','Percent','TholdDescription'));
fputcsv($output3, array('HostName','Date','Time','Percent','TholdDescription'));
// fetch the data
mysql_connect($host, $uname, $pass);
mysql_select_db($database);
echo mysql_error();
$rows = mysql_query("SELECT * FROM $table order by date ASC, Time ASC");
echo mysql_error();
$rows1 = mysql_query("SELECT * FROM $table1 order by date ASC, Time ASC");
echo mysql_error();
$rows2 = mysql_query("SELECT * FROM $table2 order by date ASC, Time ASC");
echo mysql_error();
$rows3 = mysql_query("SELECT * FROM $table3 order by date ASC, Time ASC");
echo mysql_error();
// loop over the rows, outputting them
while ($row = mysql_fetch_assoc($rows))
fputcsv($output, $row);
while ($row1 = mysql_fetch_assoc($rows1))
fputcsv($output1, $row1);
while ($row2 = mysql_fetch_assoc($rows2))
fputcsv($output2, $row2);
while ($row3 = mysql_fetch_assoc($rows3))
fputcsv($output3, $row3);
include '/tmp/Classes/PHPExcel/IOFactory.php';
$inputFileType = 'CSV';
$inputFileNames = array('HDD.csv','Traffic.csv','CPU.csv','Memory.csv');
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$inputFileName = array_shift($inputFileNames);
$objPHPExcel = $objReader->load($inputFileName);
$objPHPExcel->getActiveSheet()->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
foreach($inputFileNames as $sheet => $inputFileName) {
$objReader->setSheetIndex($sheet+1);
$objReader->loadIntoExisting($inputFileName,$objPHPExcel);
$objReader->loadIntoExisting($inputFileName,$objPHPExcel);
$objPHPExcel->getActiveSheet()->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
}
$loadedSheetNames = $objPHPExcel->getSheetNames();
foreach($loadedSheetNames as $sheetIndex => $loadedSheetName) {
$objPHPExcel->setActiveSheetIndexByName($loadedSheetName);
$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
//var_dump($sheetData);
//var_dump($sheetData);
$myfile = "Report.xlsx";
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header("Content-Disposition: attachment;filename=$myfile");
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
}
any help is appreciated, most of my code has been copy and pasted and then edited to my knowledge, also i was able to get to email the xlsx file but just have problem sending it for download.
I don't mind reading the file from the directory for download.
regards,
Lin
No spaces or tabs, no error messages, no newline characters, no BOM markers, no other output whatsoever.
Note that the error message you're seeing tells you which file/line was responsible for the output headers already sent by xxx in line 1.... so that's where to look.
At line 1 of a file, it's most likely to be something before your opening <?php tag, or a file saved with a BOM header
I am trying to pull out data from my database using php and exporting it into a downloadable CSV file that can be opened with excel. I am able to do this when i use mysql however, many have advised to not include mysql syntax in my code as its being deprecated and instead i should use mysqli. I have changed my code but now my code is not working. Does anyone know why that is?
mysql version (working version)`
mysql_connect('localhost', 'xxxxx', 'xxxxx') or die('connect');
mysql_select_db('db') or die('select');
$result = mysql_query('SELECT * bodyshops_master_network') or die('query');
if(mysql_num_rows($result) == 0)
{
die('no data');
}
$fh = tmpfile() or die('tmpfile');
$cols = array_keys(mysql_fetch_assoc($result));
fputcsv($fh, $cols);
mysql_data_seek($result, 0); // set result row pointer back to first row
while($row = mysql_fetch_assoc($result))
{
fputcsv($fh, $row);
}
rewind($fh);
$text = fread($fh, 999999);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="download.csv"');
header('Content-Length: ' . strlen($text));
echo $text;
exit;
mysqli version (not working):
$mysqli = new mysqli("localhost", "xxxxx", "xxxxx", "db");
if (mysqli_connect_errno())
{
printf("Connect failed: ", mysqli_connect_error());
exit();
} else
{
$result = "SELECT * FROM bodyshops_master_network";
if(mysqli_num_rows($result) == 0)
{
die('no data');
}
$fh = tmpfile() or die('tmpfile');
$cols = array_keys($result->fetch_assoc());
fputcsv($fh, $cols);
$result->data_seek(0); // set result row pointer back to first row
while($row = $result->fetch_assoc())
{
fputcsv($fh, $row);
}
rewind($fh);
$text = fread($fh, 999999);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="download.csv"');
header('Content-Length: ' . strlen($text));
echo $text;
exit;
Check phpinfo to see that mysqli extension is enabled.
Remove/comment the header calls so that you receive the output as plain HTML so that you notice if any message shows up (due to die or coding error) or if you actually get the data.
Also note that you loose the date of the first record you retrieve because you call:
$cols = array_keys(mysql_fetch_assoc($result));
respectively
$cols = array_keys($result->fetch_assoc());
What is not working?
Are you getting any errors?
Is the file empty, is there any file downloading?
Maybe errors aren't enabled, try this:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
?>
I'm new on StackOverflow, I think this would help. (I speak spanish, I hope you to understand my english :D )
I've been looking for a simply way to use mysqli and download a csv file that could be read by excel without UTF-8 problems (using ñ,á,ü...). I didn't found it, so I created one by myself (learning from Google and StackOverflow answers), after some hours I got something that works finally.
This is a Class that connects with the database and the functions will do whatever you want using mysqli and PHP. In this case, calling this class (require or include), just use the "downloadCsv()" function.
As an example, this would be the "class.php" file:
<?php
class DB{
private $con;
//this constructor connects with the database
public function __construct(){
$this->con = new mysqli("Your_Host","Your_User","Your_Pass","Your_DatabaseName");
if($this->con->connect_errno > 0){
die('There was a problem [' . $con->connect_error . ']');
}
}
//create the function that will download a csv file from a mysqli query
public function downloadCsv(){
$count = 0;
$header = "";
$data = "";
//query
$result = $this->con->query("SELECT * FROM Your_TableName");
//count fields
$count = $result->field_count;
//columns names
$names = $result->fetch_fields();
//put column names into header
foreach($names as $value) {
$header .= $value->name.";";
}
}
//put rows from your query
while($row = $result->fetch_row()) {
$line = '';
foreach($row as $value) {
if(!isset($value) || $value == "") {
$value = ";"; //in this case, ";" separates columns
} else {
$value = str_replace('"', '""', $value);
$value = '"' . $value . '"' . ";"; //if you change the separator before, change this ";" too
}
$line .= $value;
} //end foreach
$data .= trim($line)."\n";
} //end while
//avoiding problems with data that includes "\r"
$data = str_replace("\r", "", $data);
//if empty query
if ($data == "") {
$data = "\nno matching records found\n";
}
$count = $result->field_count;
//Download csv file
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=FILENAME.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo $header."\n".$data."\n";
}
?>
After creating the "class.php" file, in this example, use that function on "download.php" file:
<?php
//call the "class.php" file
require_once 'class.php';
//instantiate DB class
$export = new DB();
//call function
$export->downloadCsv();
?>
After download, open the file with MS Excel.
I hope this help you, I think I wrote it well, I didn't feel comfortable with the text and code field.
I am trying to send email exported csv file. However, when i click the link, have a pop-up to download a CVS with the record from MySQL. how can i send an email this csv file to spesific email adress ? thanks a lot for help and ideas.
best regards.
Here is my code
header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=log.csv");
header("Pragma: no-cache");
header("Expires: 0");
$resultstr = array();
foreach ($selectionlist as $result)
$resultstr[] = $result;
$ww=implode(",",$resultstr);
function escape_csv_value($value) {
$value = str_replace('"', '""', $value); // First off escape all " and make them ""
if(preg_match('/,/', $value) or preg_match("/\n/", $value) or preg_match('/"/', $value)) { // Check if I have any commas or new lines
return '"'.$value.'"'; // If I have new lines or commas escape them
} else {
return $value; // If no new lines or commas just return the value
}
}
$sql = mysql_query("SELECT * FROM article
WHERE idArticle in ($ww) ORDER BY idArticle DESC"); // Start our query of the database
$numberFields = mysql_num_fields($sql) or die('MySql Error' . mysql_error());; // Find out how many fields we are fetching
if($numberFields) { // Check if we need to output anything
for($i=0; $i<$numberFields; $i++) {
$keys[] = mysql_field_name($sql, $i); // Create array of the names for the loop of data below
$col_head[] = escape_csv_value(mysql_field_name($sql, $i)); // Create and escape the headers for each column, this is the field name in the database
}
$col_headers = join(',', $col_head)."\n"; // Make our first row in the CSV
$data = '';
while($info = mysql_fetch_object($sql)) {
foreach($keys as $fieldName) { // Loop through the array of headers as we fetch the data
$row[] = escape_csv_value($info->$fieldName);
} // End loop
$data .= join(',', $row)."\n"; // Create a new row of data and append it to the last row
$row = ''; // Clear the contents of the $row variable to start a new row
}
// Start our output of the CSV
/*header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=log.csv");
header("Pragma: no-cache");
header("Expires: 0");*/
echo $col_headers.$data;
} else {
// Nothing needed to be output. Put an error message here or something.
echo 'No data available for this CSV.';
}
OK. First you have to Save the CSV file. If you set headers as you mentioned the file will be automatically downloaded. Please read this article on this.
http://us2.php.net/manual/en/function.fputcsv.php
Once you create your CSV file you can email it using PHP mail function. If you need some library just check this out. It's easy to implement.
http://www.redvodkajelly.com/code/php-email-class/