I create a csv file with the SQL query:
$sql = "SELECT 'id','username','name','email',
'phone_number','city',
'batch','course_type' UNION ALL
SELECT id, username, name, email,
phone_number, city, batch, course_type
FROM users INTO OUTFILE '".$file_path."' ".
"FIELDS TERMINATED BY ','
ENCLOSED BY '\"'
LINES TERMINATED BY '\n'";
After causing a browser force-download of this file, I need to delete this file from the /tmp directory. But since, the file is owned by mysql, the php code cannot delete it. How do I change permissions on this file in my code so that the file can be deleted?
One solution to do this right, is (This is a rough example of how it could be done):
Return the data from the database as an array, and iterate through it:
// tell the browser that this is a download
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=list.csv");
// column separator
$separator = ';';
// field delimiter
$field_delimiter = '"';
// line end
$line_end = "\r\n";
foreach ($result as $row):
$i = 0;
foreach ($row as $item):
// do not add separator before the first item
if ($i > 0)
{
echo $separator;
}
echo $field_delimiter.$item.$field_delimiter;
$i++;
endforeach;
// line end
echo $line_end;
endforeach;
Do not output anything else, just the CSV content.
Related
I am trying to export data from MySQL to CSV using PHP from a website. When a user clicks generate the report it will automatically create and this will be downloaded as a file on their computer. The code below I have been following an online tutorial but I have run into some issues. Currently, it will download but will only show one row with one date value from the MySQL data.
I was wondering what I need to do to show all the data in the csv file and how do I ensure that the names of the Rows are printed as well.
#header("Content-Disposition: attachment; filename=record.csv");
$select = "SELECT * FROM DBtable WHERE user_id=$id";
$result2 = $conn->query($select);
while ($row = $result2->fetch_assoc()) {
$data = $row['pain']."\n";
$data = $row['sleep']."\n";
$data = $row['mood']."\n";
$data = $row['heartrate']."\n";
$data = $row['time_of_entry']."\n";
}
echo $data;
exit();
Instead of setting the $row values to $data, you should echo instead
#header("Content-Disposition: attachment; filename=record.csv");
$select = "SELECT * FROM DBtable WHERE user_id=$id";
$result2=$conn->query($select);
while($row=$result2->fetch_assoc()){
echo $row['pain']."\n";
echo $row['sleep']."\n";
echo $row['mood']."\n";
echo $row['heartrate']."\n";
echo $row['time_of_entry']."\n";
}
exit();
Your code just keeps setting $data to a rows value, without actually doing anything with it. Each line overwrites the previous, so when you do echo $data, you are echoing the last value it was set to which in your case was the last loops "time of entry" value.
As for adding "names of the Rows", currently the code puts in a value then a new line. You probably want to replace "\n" with ",", so one loops data is one one line, then before the closing while loop, echo a "\n" to insert a new line character. You can then put the titles in the same way, using an echo, and comma seperated titles, followed by a new line character.
For example
echo $row['pain'].",";
echo $row['sleep'].",";
echo $row['mood'].",";
echo $row['heartrate'].",";
echo $row['time_of_entry'].",";
echo "\n";
I added two additional columns in my csv file which contain some Excel formula because I needed to download the MySQL data as an excel file in which those formulas will react.
But after adding these two additional columns the data is not getting inserted into the table.
My code is:
$a = file('/Applications/XAMPP/xamppfiles/htdocs/upload/data.csv');// get array of lines
$new = '';
$i=1;
//$formula1 = "=IF(A$i>=40,2,IF(A$i=20,1))";
foreach($a as $line){
$line = trim($line);// remove end of line
$line .="|=IF(A$i>=40,2,IF(A$i=20,1))"."|=IF(COUNTIF(\$B:\$B,B".$i.")=1,1,C".$i."/COUNTIF(\$B:\$B,B".$i."))";// append new column
$new .= $line.PHP_EOL;//append end of line
$i++;
}
$outputfile = file_put_contents('/Applications/XAMPP/xamppfiles/htdocs/upload/data.csv', $new);// overwrite the same file with new data
$termit = "|";
$encls = "'\"'";
$lyn = "'\r\n'";
$cvsfile = "'/Applications/XAMPP/xamppfiles/htdocs/upload/data.csv'";
$dalete = mysql_query("delete FROM upload_excel_file");
$data_upload = mysql_query ("LOAD DATA INFILE $cvsfile INTO TABLE $cvsfile FIELDS TERMINATED BY '|' ENCLOSED BY $encls LINES TERMINATED BY $lyn IGNORE 1 LINES;");
I am trying to download table data into a CSV format. The data in one of the fields contains ",".
Eg: Doe, John
When I download the csv file, the data after comma is shifted to next column. But I want the entire data i.e including comma in same column.
The Code I used as follows:
<?php
include('dbconfig.php');
//header to give the order to the browser
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename=download.csv');
//select table to export the data
$sql ="SELECT * FROM tablename";
$select_table=mysqli_query($db, $sql);
$rows = mysqli_fetch_assoc($select_table);
if ($rows)
{
getcsv(array_keys($rows));
}
while($rows)
{
getcsv($rows);
$rows = mysqli_fetch_assoc($select_table);
}
// get total number of fields present in the database
function getcsv($no_of_field_names)
{
$separate = '';
// do the action for all field names as field name
foreach ($no_of_field_names as $field_name)
{
if (preg_match('/\\r|\\n|,|"/', $field_name))
{
$field_name = '' . str_replace('<em>', '', $field_name) . '';
}
echo $separate . $field_name;
//sepearte with the comma
$separate = ',';
}
//make new row and line
echo "\r\n";
}
?>
Can someone help me get through this issue.
Thanks
Make sure you escape the ,. Typically values that contain sensitive characters (such as , and \n) are surrounded in ".
So your output can be:
"Doe, John",52,New York
You can either write your own escape function or use PHPs fputcsv. It writes to a file handler that's a bit inconvenient but you can make it stdout.
$handle = fopen("php://stdout");
fputcsv($handle, array("Doe, John", 52, "New York"));
I have a mysql statement and I would like to store the data it fetches in a csv file in tab format. I have used the following statment but it is not creating and storing the results when I run my file and no error files.
$mytry = "SELECT * FROM table WHERE `assigned` = '$id'
INTO OUTFILE '/inactive/orders.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '\"'
LINES TERMINATED BY '\n'";
mysql_query($mytry);
Or there a way I can write to file in a directory without prompting the user to download, this works but it prompts
$sQuery="SELECT * FROM table WHERE `assigned` = '$id'";
$rResult = mysql_query( $sQuery) or die();
$count = mysql_num_fields($rResult);
$html = '<table border="1"><thead><tr>%s</tr><thead><tbody>%s</tbody></table>';
$thead = '';
$tbody = '';
$line = '<tr>%s</tr>';
for ($i = 0; $i < $count; $i++){
$thead .= sprintf('<th>%s</th>',mysql_field_name($rResult, $i));
}
while(false !== ($row = mysql_fetch_row($rResult))){
$trow = '';
foreach($row as $value){
$trow .= sprintf('<td>%s</td>', $value);
}
$tbody .= sprintf($line, $trow);
}
header("Content-type: application/vnd.ms-excel; name='excel'");
header("Content-Disposition: filename=exportfile.xls");
header("Pragma: no-cache");
header("Expires: 0");
print sprintf($html, $thead, $tbody);
exit;
You might want to look into the following PHP function: http://php.net/manual/en/function.fputcsv.php
Fetch the data using your query and then save it to a variable. Then, use fputcsv to store the data to a file.
Also, I would discourage the usage of mysql_query, since it has now become deprecated (as well as the rest of mysql_* family). Furthermore, your code is vulnerable to SQL injection attacks. Read up on using PDO for database interaction.
Some more recommended reading to put you on the right track: http://www.phptherightway.com/#databases
EDIT: From what you have shown in your code sample, you simply output an HTML page to the browser, which gets downloaded right away because of the Content-Disposition header you set.
I am exporting content from an MySQL database to a Word Template (RTF) via PHP.
There is a section, "Appendix B", which should display all the Acronyms found for a record. The minimum records to appear for this section is 90 (i.e. these are standard acronyms (tblAcronyms) that each record will have); however the maximum records are unknown since users can add to this listing (tblAppendixB).
The Word (i.e. RTF) document should display all the records found, however, it is only displaying the first record.
This is what I have thus far:
<?php
....
#Retrieve Appendix B records
$qry_get_AppB = "SELECT vAcronym, vAcronymDesc FROM tblAcronyms
UNION SELECT vAcronym, vAcronymDesc FROM tblAppendixB
WHERE fkID = ". $i_fk_id . " ORDER BY vAcronym ASC";
$qry_appb_result = mysql_query($qry_get_AppB);
$qryAppBno_rows = mysql_num_rows($qry_appb_result);
//Generate the headers to help a browser choose the correct location
header('Content-Type: application/msword');
header('Content-Disposition: inline; filename="'.$vProgramName.'_rec.rtf");
//Open the template file
$tfilename = 'Appb_Template.rtf';
$fp = fopen($tfilename, 'r');
//Read the template into a variable
$toutput = fread($fp, filesize($tfilename));
fclose($fp);
//Replace the place holders in the template with data
if($qryAppBno_rows > 0)
{
while($rowAppB = mysql_fetch_array($qry_appb_result))
{
$vAppB = $rowAppB['vAcronym'] . '-' . $rowAppB['vAcronymDesc'] . "\r\n";
$toutput = str_replace('<<vAppB>>', $vAppB, $toutput);
}
}
//Send the generated document to the browser
echo $toutput;
?>
I have searched this forum and others but have yet to find a solution.
Any assistance is greatly appreciated.
Okay, I'm not quite sure what your template looks like, but I guess, you only have 1 place holder named <<vAppB>>. In your 1st iteration (if there is any data available) you replace that placeholder with your 1st data entry. In this fact only one placeholder is shown.
May rewrite your code to something similar to this
... //do your stuff
$newLine = "\r\n";
$appendix = "";
while($rowAppB = mysql_fetch_array($qry_appb_result)) {
$appendix .= $rowAppB['vAcronym'] . '-' . $rowAppB['vAcronymDesc'] . $newLine;
}
$toutput = str_replace('<<vAppB>>', $appendix, $toutput);
...//do some other stuff
Just simple prototyping, so you may have to do some additional work.
The trick is to collect all entries you got and than replace it with your placeholder :)
I resolved the problem; I had to use "\par" instead of "\r\n" for MS Word (RTF) to recognize it as a paragraph mark. Here is the modified code that now works:
<?php
....
$t_newline = "\par";
#Retrieve Appendix B records
$qry_get_AppB = "SELECT vAcronym, vAcronymDesc FROM tblAcronyms
UNION SELECT vAcronym, vAcronymDesc FROM tblAppendixB
WHERE fkID = ". $i_fk_id . " ORDER BY vAcronym ASC";
$qry_appb_result = mysql_query($qry_get_AppB);
$qryAppBno_rows = mysql_num_rows($qry_appb_result);
//Generate the headers to help a browser choose the correct location
header('Content-Type: application/msword');
header('Content-Disposition: inline; filename="'.$vProgramName.'_rec.rtf");
//Open the template file
$tfilename = 'Appb_Template.rtf';
$fp = fopen($tfilename, 'r');
//Read the template into a variable
$toutput = fread($fp, filesize($tfilename));
fclose($fp);
//Replace the place holders in the template with data
if($qryAppBno_rows > 0)
{
while($rowAppB = mysql_fetch_array($qry_appb_result))
{
$vAppendixB[] = $rowAppB['vAcronym'] . '-' . $rowAppB['vAcronymDesc'] . $t_newline;
$vAppB = implode(" ", $vAppendixB);
}
}
$toutput = str_replace('<<vAppB>>', $vAppB, $toutput);
//Send the generated document to the browser
echo $toutput;
?>
Hopefully this will help someone else. :-)