Enabling PHP errors when creating a CSV file from database - php

This method for exporting data on csv has worked previously on other projects, but I can not make this work on here, and I am not sure about how to enable erros for this case.
This PHP file creates a comma-separated file containing an initial row with a single tab ("ID"), and then it should be creating a row for each match on the SELECT query from DB
<?php
session_start();
ob_start();
include('conexionbbdd.php');
$file='informes/expositores_'.time().'.xls';
header("Content-Type: application/xls");
header("Content-Disposition: attachment; filename=$file");
header("Pragma: no-cache");
header("Expires: 0");
$output = fopen($file, 'w');
fwrite($output, chr(239) . chr(187) . chr(191));
fputcsv($output, array('ID'), "\t");
// fetch the data
$rows1 = mysqli_query($con, "SELECT ex_id FROM expositores WHERE ex_id = '26'");
// loop over the rows, outputting them
while ($row1 = mysqli_fetch_assoc($rows1)) {
fputcsv($output, $row1, "\t");
}
fclose($output);
echo $file;
ob_end_flush();
?>
In this particular case I've simplified this to maximu so, apart from the initial row, a unique row containg the "26" should be created (I've tested that the query works with PhpMyAdmin, there's an ID 26). But it does not.
It only creates correctly first row from this first fputcsv method:
fputcsv($output, array('ID'), "\t");
No other row seems to be fetched or placed on the CSV.
As the entire PHP file's aim is to create the CSV file, no error is shown because it does not open on a new window.
Output:

In order to solve this you will need to be able to view the errors. You can have a look in your error logs or add error reporting to the top of your file(s) right after your opening <?php tag error_reporting(E_ALL); ini_set('display_errors', 1);

Related

Exporting/Importing tables with different date format

Im having this problem, that when i export my table as csv file and open it on the excel: the date seems to have different format (in the database : yyyy-mm-dd, while on the excel dd/mm/yyyy)
Is there a way of solving these things to have the same format either when exporting or importing
This is my code when importing
elseif ($_POST["program"]=="dengue"){
$filename = $_FILES['file']['tmp_name'];
$file = fopen($filename, "r");
while (($getData = fgetcsv($file, 10000, ",")) !== FALSE)
{
$sql = "INSERT into lcho_dengue_activities (district_id,barangay_id,month,year,dengue_ind1,dengue_ind2,dengue_ind3,dengue_ind4,dengue_ind5,dengue_ind6,dengue_ind7,dengue_ind8,dengue_ind9,dengue_ind10,dengue_ind11,date)
values ('".$getData[0]."','".$getData[1]."','".$getData[2]."','".$getData[3]."','".$getData[4]."','".$getData[5]."','".$getData[6]."','".$getData[7]."','".$getData[8]."','".$getData[9]."','".$getData[10]."','".$getData[11]."','".$getData[12]."','".$getData[13]."','".$getData[14]."','".$getData[14]."')";
if(!mysqli_query($con, $sql))
{
echo ("Error description: " . mysqli_error($con));
}
else {
echo "<script type=\"text/javascript\">
alert(\"CSV File has been successfully Imported.\");
window.location = \"imports.php\"
</script>";
}
}
While this is on exporting
if($_POST["program"]=="dengue"){
// get records from database
$query = $db->query("SELECT * FROM lcho_dengue_activities ");
if($query->num_rows > 0){
$delimiter = ",";
$filename = "dengueactivities" . date('Y-m-d') . ".csv";
//create a file pointer
$f = fopen('php://memory', 'w');
//output each row of the data, format =line as csv and write to file pointer
while($row = $query->fetch_assoc()){
$lineData = array( $row['district_id'], $row['barangay_id'], $row['month'], $row['year'],$row['dengue_ind1'],$row['dengue_ind2'],$row['dengue_ind3'],$row['dengue_ind4'],$row['dengue_ind5'],$row['dengue_ind6'],$row['dengue_ind7'],$row['dengue_ind8'],$row['dengue_ind9'],$row['dengue_ind10'],$row['dengue_ind11'],$row['date']);
fputcsv($f, $lineData, $delimiter);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
//output all remaining data on a file pointer
fpassthru($f);
}
exit;
Need to have same format
You wrote in short:
"Im having this problem, that when i export my table as csv file and open it on the excel: the date seems to have different format (in the database : yyyy-mm-dd, while on the excel dd/mm/yyyy)"
Seems like that's just the nature of the beast. Remember that a .csv file is not an Excel file (which may store exact instructions on how to format everything). So when Excel opens a .csv file it tries to make some guesses about how to format columns of data and sometimes that may not be exactly what you intend.
A similar thing is trying to show something like 2 decimal places where Excel shows whatever it considers significant such as 0.12, 0.13, 0.1, 0. Another similar weird thing I've seen is if the first 10 or 20 rows or something in the .csv file are blank and then Excel often seems to have no clue on how to properly format the column.
To REALLY see exactly what is in a .csv file you can open it up in some kind of word processor such as a coding editor.

PHP export CSV Table from Database

I'm new to PHP and I'm trying to do a small experiment to learn.
I want to create a line of words, that when clicked, will download a csv file from a table I have in my database.
So far, this is what I've come up with (which isn't even near what I want to do. But I was able to make it turn into a hyperlink).
echo "<a href=http://www.google.com>Click here to visit site</a>";
Assuming I already have a connection to my database, how would I go about connecting "Click here to visit site" to download a csv file, from say, table1 of my database ABC?
I think there will have to be some loop that reads the rows in table1 and writes it into the csv file, right?
Create a file separate file having the following code and create a hyperlink in your current file like:
echo "<a href='http://<your domain name>/test.php'>Click here to visit site</a>";
<?php
//test.php
// output headers so that the file is downloaded rather than displayed
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
// output the column headings
fputcsv($output, array('Column 1', 'Column 2', 'Column 3'));
// fetch the data
$rows = mysqli_query($conn, 'SELECT name, email FROM users limit 10');
// loop over the rows, outputting them
while ($row = mysqli_fetch_assoc($rows)) fputcsv($output, $row);
?>

PHP Excel export only shows last row of MYsql table

I am having problems exporting data from a MySQL database using a PHP script that mimes an excel file.
The data is only exporting the last row of the MySQL table.
I have chopped the code down to remove all the relational look ups (as there are multiple MySQL queries through out which make it hard to read).
I understand I am over writing my variables so only the last row of selected is available to the script but after a lot of searching I still cant seem to find an answer (I am guessing I need to store the data in an array then call that array within the code that exports the data as an excel file).
All help will be greatly appreciated.
My code (chopped down version) is:
<?php
// Apply server security settings and keep cookies
// connecting to the server
// selecting the appropriate database
//storing and fetching user data
$generate_query = "SELECT * FROM main_report";
$generate_data = mysql_query($generate_query, $link);
while($report = mysql_fetch_array($generate_data))
{
$reportnoout = "<td>".$report['report_number']."</td>";
$incdateout = "<td>".$report['incident_time']."</td>";
$siteout = "<td>".$site_data['site_name']."</td>";
$deptout = "<td>".$dept_data['department_name']."</td>";
$reportout = " <td>".$report['report_type']."</td>";
$superout = "<td>".$staff_data5['name']."</td>";
$descout = "<td>".$report['detailed_desc']."</td>";
// Needs some form of array declaration here maybe?
}
// filename for download
$filename = "test_data_" . date('Ymd') . ".xls";
header("Content-type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=$filename");
$test="<table><th>Report No.</th><th>Incident Date</th><th>Site</th><th>Department</th><th>Incident Type</th><th>Responsible Supervisor</th><th>Description</th><tr>";
$test2="$reportnoout $incdateout $siteout $deptout $reportout $superout $descout"; // This is not right either should probably be an array or not even here?
echo $test;
echo $test2; // This was a stop gap to at least see if some of the code worked
exit;
?>
Many thanks in advance.
Cheers
Jase
PS I worked this code up by searching the web over the last few days and put it together from that prior to this I have never worked on this type of stuff (outputting file types)
Your code could use a lot of cleanup, but I will let you figure that out later, and focus on making it work as you have intended.
You can do this by using concatenation .=
//start table string
$table = "<table><tr>
<th>Report No.</th>
<th>Incident Date</th>
<th>Site</th>
<th>Department</th>
<th>Incident Type</th>
<th>Responsible Supervisor</th>
<th>Description</th><tr>";
$generate_query = "SELECT * FROM main_report";
$generate_data = mysql_query($generate_query, $link);
while($report = mysql_fetch_array($generate_data))
{
//add row to string using concatenation
$table .= "<tr><td>{$report['report_number']}</td>
<td>{$report['incident_time']}</td>
<td>{$site_data['site_name']}</td>
<td>{$dept_data['department_name']}</td>
<td>{$report['report_type']}</td>
<td>{$staff_data5['name']}</td>
<td>{$report['detailed_desc']}</td></tr>";
}
//close table
$table .="</table>";
// filename for download
$filename = "test_data_" . date('Ymd') . ".xls";
header("Content-type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=$filename");
echo $table;

inserting sql output rows to excel file

i have 150 rows and 40 columns in a sql table..i am displaying the entire table in a web page..now,what i want to do is create a link on that web page that will take the entire table and insert it in an excel file(dosn't matters if it creates a new excel file,or modifies sum exisiting one)...now i can do it manually by using(PHPExcel library)," objPHPExcel->setCellValue('C5', $v) "...but i would have to write this like 40 times(change '$v' variable in every statment) nd its inside a loop that will run 150 times..hence i dont wanna do it this way..
now i wanted to know if i can insert the table,row by row in the excel sheet..like when i insert a row,it will insert the entire cells of d row..that way it will be pretty easy..so i wanted to know if there any specific commands for doing this..
if not,wat other alternatives do i have of doing this..all i want to do is to export the entire sql table to an excel file using php..
So use the fromArray() method that PHPExcel thoughtfully provides that allows you to write a whole row or whole block of cells in one call from an array.
Looking at the examples and reading the documentation always helps
Additional note
Incidentally, $objPHPExcel->setCellValue('C5', $v) will only work if $objPHPExcel is a worksheet, most of the examples use $objPHPExcel for the workbook (ie the collection of worksheets) so don't get confused
EDIT
For fetching the results from your database, use
sqlsrv_fetch_array($tsql, SQLSRV_FETCH_ASSOC)
or
sqlsrv_fetch_array($tsql, SQLSRV_FETCH_NUMERIC)
EDIT 2
Check how the database is set to handle NULL returns; but using
$objPHPExcel->getActiveSheet()->fromArray($rows, 0, 'A'.$rowCNT);
should set all NULL values from the database result to 0 value in PHPExcel
The easiest way is to export a .csv file, which can also be read by excel.
All you have to do is create this page :
<?
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");
$link = mysql_connect('db', 'dblogin', 'dbpasswd');
#mysql_select_db('dbname') or die( "Unable to select database");
$query=mysql_query("SELECT * FROM whatever");
$j=0;
$nbField = mysql_num_fields($query);
while ($j < $nbField) {
echo mysql_field_name($query,$j).";";
$j++;
}
echo "\n";
while ($row = mysql_fetch_array($query, MYSQL_NUM)) { echo implode(";", $row)."\n"; }
?>
Then you insert a link pointing directly to this php page, it will download the csv file.

small glitch while generating csv with newline character in php

I am simply generating a csv file based on data stored in a mysql table. The generated csv, when opened in excel, seems mostly ok, but whenever it has a newline character, excel puts the data on a new row. Any idea how to prevent that?
Sample data
line 1 some data
another data
CSV generation code:
header("Content-Type: text/csv; charset=UTF-8");
header("Content-Disposition: attachment; filename=\"".$MyFileName."\"");
$filename = $MyFileName;
$handle = fopen("temp_files/".$filename, "r");
$contents = fread($handle, filesize("temp_files/".$filename));
fclose($handle);
echo $contents;
exit;
content snippet I used to get rid of new line(didn't work):
$pack_inst = str_replace(',',' ',$get_data->fields['pack_instruction']);
$pack_inst = str_replace('\n',' ',$pack_inst);
$pack_inst = str_replace('\r',' ',$pack_inst);
$pack_inst = str_replace('\r\n',' ',$pack_inst);
$pack_inst = str_replace('<br>',' ',$pack_inst);
$pack_inst = str_replace('<br/>',' ',$pack_inst);
$pack_inst = str_replace(PHP_EOL, '', $pack_inst);
$pattern = '(?:[ \t\n\r\x0B\x00\x{A0}\x{AD}\x{2000}-\x{200F}\x{201F}\x{202F}\x{3000}\x{FEFF}]| |<br\s*\/?>)+';
$pack_inst = preg_replace('/^' . $pattern . '|' . $pattern . '$/u', ' ', $pack_inst);
$content .=','.$pack_inst;
According to RFC 4180, if a column's content contains the row delimiter (\r\n), the column delimiter (,) or the string delimiter (") then you must enclose the content inside double quotes ". When you do that, you must escape all " characters inside the content by preceding them with another ". So the following CSV content:
1: OK,2: this "might" work but not recommended,"3: new
line","4: comma, and text","5: new
line and ""double"" double quotes"
1: Line 2
Will produce 2 rows of CSV data, first one containing 5 columns.
Having said that, have a look at fputcsv() function. It will handle most gory details for you.
What you show is not the CSV generation code, it is simply the code that you have used to force a download to the browser. Regardless, the function that you need to sort this out is fputcsv(), which will automatically consider all sorts of edge cases that any code you write to convert tabular data to CSV format will likely not consider.
You say you are basing this on data in MySQL table, here is a basic framework for creating the CSV file, assuming the MySQLi extension used in a procedural manner:
<?php
// Connect to database and generate file name here
$fileName = 'file.csv';
// Get the data from the database
$query = "
SELECT *
FROM table_name
WHERE some_column = 'Some Value'
ORDER BY column_name
";
if (!$result = mysqli_query($db, $query)) {
// The query failed
// You may want to handle this with a more meaningful error message
header('HTTP/1.1 500 Internal Server Error');
exit;
} else if (!mysqli_num_rows($result)) {
// The query returned no results
// You may want to handle this with a more meaningful error message
header('HTTP/1.1 404 Not Found');
exit;
}
// Create a temporary file pointer for storing the CSV file
$tmpFP = fopen('php://temp', 'w+');
// We'll keep track of how much data we write to the file
$fileLength = 0;
// Create a column head row and write first row to file
$firstRow = mysqli_fetch_assoc($result);
$fileLength += fputcsv($tmpFP, array_keys($firstRow));
$fileLength += fputcsv($tmpFP, array_values($firstRow));
// Write the rest of the rows to the file
while ($row = mysqli_fetch_row($result)) {
$fileLength += fputcsv($tmpFP, $row);
}
// Send the download headers
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="'.$fileName.'"');
header('Content-Length: '.$fileLength);
// Free some unnecessary memory we are using
// The data might take a while to transfer to the client
mysqli_free_result($result);
unset($query, $result, $firstRow, $row, $fileName, $fileLength);
// Prevent timeouts on slow networks/large files
set_time_limit(0);
// Place the file pointer back at the beginning
rewind(tmpFP);
// Serve the file download
fpassthru($tmpFP);
// Close the file pointer
fclose($tmpFP);
// ...and we're done
exit;

Categories