Export mysql to txt / xml file and download it - php

i have a table which shows some mysql data, every entry has a checkbox to select individual entries, now i want to be able to export those selected entries into a xml or txt file, i tried this:
<?php
if ($_POST['exporttxt']) {
for ($i = 0; $i < count($_POST['checkbox']); $i++) {
$export_id = $checkbox[$i];
$sql = "SELECT * FROM table WHERE id='$export_id'";
$result = mysql_query($sql);
}
$output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>\n";
if ($result->num_rows > 0) {
while ($myrow = $result->fetch_assoc())
{
$output .= "\t<row>\n";
foreach ($myrow as $_name => $_value)
{
$output .= "\t\t<$_name>$_value</$_name>\n";
}
$output .= "\t</row>\n";
}
}
$output .= "</root>";
}
header('content-type: text/xml');
header('content-disposition: attachment; filename=data_export.xml');
echo $output;
exit;
?>
But that didn't work at all, any hints ?
I've changed the code a bit, i am now using this
<?php
if ($_POST['exporttxt']) {
for($i=0;$i<count($_POST['checkbox']);$i++){
$export_id = $checkbox[$i];
$text = mysql_query("SELECT code FROM ticket WHERE id='$export_id'");
$text = mysql_fetch_assoc($text);
$text = $text["code"];
ob_end_flush();
header("Content-type: text/plain");
header("Content-disposition: attachment;filename=\"filename.txt\"");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: ".strlen($output).";\n");
echo($text);
}
}
?>
I now get proper output on my screen, but it won't offer me to download the file ?

Your original code was querying each of the checkboxed IDs individually (a long and laborious way to handle it) and was trying to dump the results individually per row (not going to work well for you).
Try this. (NOTE: Untested, but should give you a good starting point to develop.)
if( $_POST['exporttxt'] ){
if( count( $_POST['checkbox'] )>0 ){
// If the checkbox values are meant to all be integers, you might want to perform some validation/sanitisation/filtering here
// Up to you to do that
// Collapse the IDs from the checkboxes into a comma-delimited string
$export_ids = implode( ',' , $_POST['checkbox'] );
// Template the SQL Query
$sqlTpl = 'SELECT code FROM ticket WHERE id IN ( %s )';
// Compile the SQL Query String
$sqlStr = sprintf( $sqlTpl , $export_ids );
// Execute the SQL Query
if( !( $sqlRes = mysql_query( $sqlStr ) ) ){
// SQL Error - Log it, Handle it
}elseif( mysql_num_rows( $sqlRes )==0) {
// No Rows Returned - Log it, Handle it
}else{
// We have results - process them
$text = array();
while( $r = mysql_fetch_assoc( $sqlRes ) ){
// Looping through the returned rows, adding them to the $text array
$text[] = $r['code'];
}
// Collapse the $text array down into a normal string, with one element per line
$output = implode( "\n" , $text );
// Output Handling from #narcisradu's answer
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Transfer-Encoding: binary;\n");
header("Content-Disposition: attachment; filename=\"filename.txt\";\n");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: ".strlen($output).";\n");
echo $output;
die; // Prevent any further output
}
}else{
// No Checkboxes Checked
echo 'You must select one or more checkboxes to export something, muppet.';
}
}

First of all:
for($i=0;$i<count($_POST['checkbox']);$i++){
$export_id = $checkbox[$i];
$sql = "SELECT * FROM table WHERE id='$export_id'";
$result = mysql_query($sql);}
This piece of code will actually do a query for every element in _POST['checkbox'] array but then you are using the result of the last query and you are not parsing the result of every query.
Please make sure the generated XML is well-formed and you actually have some data, by displaying directly into the browser.
After that you may try to force download:
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Transfer-Encoding: binary;\n");
header("Content-Disposition: attachment; filename=\"".urlencode(basename($file_name))."\";\n");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: ".strlen($output).";\n");
ob_end_flush();

Related

Could not download CSV file on browser using PHP and MySQL

I need to download the mysql record to csv file on browser but as per my code it's not working as expected. Here is my code:
$scope.downloadAllCustomerData=function(){
var url2='../service/admin/customer/customer.php?action=downloadAllCustomerData';
var method='GET';
var data1='';
DataService.connectToServerSideScript(method,url2,data1)
.then(function(response) {
console.log('response',response);
},function(error) {
})
}
Here is my client side code which making request to sevre to download the .CSV file.
if ($_REQUEST["action"]=="downloadAllCustomerData") {
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');
$output = fopen("php://output", "w");
fputcsv($output, array('ID', 'Name', 'Email', 'MObile No'));
$sql = "SELECT user_id,name,email,mobile from cb_customer_info ORDER BY user_id DESC";
$stmt = $db->prepare($sql);
if ($stmt->execute()) {
$row = $stmt->fetchAll();
$number_of_rows= count($row);
if ($number_of_rows > 0) {
fputcsv($output, $row);
$data=array("status"=>1,"msg"=>"Downloaded all data successfully.");
}else{
$data=array("status"=>0,"msg"=>"No record found.");
}
fclose($output);
}
echo json_encode($data);
}
Here I am trying to download the mysql record into .csv file. I need when user will click on the button those record will be downloaded on the browser.
Better to form data and echo/print to browser instead of using php://output stream.
Usual headers for Download,
header("Content-Disposition: attachment;filename=\"".$file_name."\"");
header('Content-Type: '.$content_type);
header("Accept-Ranges: bytes");
header("Pragma: private");
header("Expires: -1");
header("Cache-Control: private, must-revalidate, post-check=0, pre-check=0");
header("Content-Length: ".$filesize);

How to upload the image into folder

I need to push the image into a folder, here image will generated in for loop according to my query, for each and every loop in need push the $img to a specific folder.
If it's possible..? Kindly give some solution.
<?php
for($i=0;$i<10;$i++)
{
$sql_sub = select_query("select DESPHOT from photo where photoid = ".$i."");
$img = $sql_sub[0][0]->load();
header("Content-type: image/pjpeg");
echo $img;
}
?>
You needs to use file_put_contents function for it.
Try
<?php
for($i=0;$i<10;$i++)
{
$sql_sub = select_query("select DESPHOT from photo where photoid = ".$i."");
$img = $sql_sub[0][0]->load();
$target_folder = 'test';
$filename = $i.'.jpg';
$new_saved = file_put_contents($target_folder.'/'.$filename, $img);
echo "Picture save as ".$new_saved;
}
?>
Note You have to set 0777 permission to target_folder if you are using UNIX/LINUX.
Above code is not tested. What $sql_sub[0][0]->load(); do?
Your going to need move_uploaded_file($tmp_path, $newpath)
more info here: http://php.net/manual/en/function.move-uploaded-file.php
// set headers
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: $file_type");
header("Content-Disposition: attachment; filename=\"$file_name\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $file_size);

My download.php script sends a corrupt file

I am having difficulty working out my download.php script. The customer gets a unique download link generated from my database and when they click it on it is meant to send them the file from my server. Only in my case the zip file is always corrupt and bigger then the original file. Original file is 68KB and the downloaded file ends up being 90KB.
Here is my code that sends the file to the browser:
<?php
$actual_link = "http://$_SERVER[HTTP_HOST]";
$post_id = $wpdb->get_results("SELECT transaction_id FROM slx_jomsocial_plugin_orders WHERE (transaction_id ='". $tx ."' and unique_code='". $token ."')");
$rowCount = $wpdb->num_rows;
if($rowCount==1){
$name="Unzip_First_Video_Embedding.zip";
$file_url=$actual_link."/jomsplugins/".$name;
header("Content-type: application/x-file-to-save");
header("Content-Disposition: attachment; filename=".$name);
readfile($file_url);
echo "<h1>Thank you ".$name=$_SESSION['s_name']." For downloading the plugins.</h1><br />";
}else{
echo "<h1>You are not permitted to downlaod, Please purchase plugin first.</h1> <br /><div style=\"margin-left: 25%;margin-top: 1%;\">Click Here</div>";
}
?>
What am I doing wrong here?
UPDATE:
I have been experimenting with the script but still my files come out corrupted (Unzipping them gives a .cpgz file). Here is my current script now:
<?php
$actual_link = "http://$_SERVER[HTTP_HOST]";
$post_id = $wpdb->get_results("SELECT transaction_id FROM slx_jomsocial_plugin_orders WHERE (transaction_id ='". $tx ."' and unique_code='". $token ."')");
$rowCount = $wpdb->num_rows;
if($rowCount==1){
// set example variables
$filename = "Unzip_First_Video_Embedding.zip";
$filepath = $actual_link."/jomsplugins/";
// http headers for zip downloads
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
ob_end_flush();
ob_clean();
flush();
#readfile($filepath.$filename);
ob_clean();
flush();
exit;
}

File Export Script Hangs on Large Output

Below is the script im using to export a MySQL database to a .csv file.
It seems to do fine with smaller outputs (under about 30,000 rows), but hangs on my larger outputs and just wont complete (1 million rows total).
Any ideas why?
Also, the PHPMyAdmin export utility dumps it incredibly quickly (just a few seconds). Wondering how it does it.
if(isset($_POST['submit'])) {
// Fetch Record from Database
$output = "";
$table = "tt_output";
$sql = mysqli_query($connection,"select * from {$table}");
$columns_total = mysqli_num_fields($sql);
// Get The Field Name
$query = "SHOW COLUMNS FROM {$table}"; $result_set = mysqli_query($connection,$query);
while ($result = mysqli_fetch_array($result_set)) {
$heading = $result[0];
$output .= trim($heading.',');
}
$output = substr($output,0,strlen($output)-1)."\r\n";
// Get Records from the table
while ($row = mysqli_fetch_array($sql)) {
for ($i = 0; $i < $columns_total; $i++) {
$output .='"'.$row["$i"].'",';
}
$output = substr($output,0,strlen($output)-1)."\r\n";
}
// Download the file
$filename = "output".".csv";
header("Pragma: public", true);
header("Expires: 0"); // set expiration time
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header('Content-Disposition: attachment; filename='.$filename);
header("Content-Transfer-Encoding: binary");
header('Connection: Keep-Alive');
echo $output;
exit;
}
On problem I can see is that you are reading everything into a variable / memory and only then start outputting it.
You should put your loop below the headers and output it right away:
...
header('Connection: Keep-Alive');
// Get Records from the table
while ($row = mysqli_fetch_array($sql)) {
for ($i = 0; $i < $columns_total; $i++) {
$output .='"'.$row["$i"].'",';
}
echo substr($output,0,strlen($output)-1)."\r\n";
}
Another possible problem is how you are building your row. If any of the fields contains an unescaped " character, it will break your csv. You might want to use fputcsv() to save the csv to a temporary file and only then send it to the client.
You can also save yourself a query as the column names will be the keys of your results arrays and if you really want to build the csv manually, you could use implode() instead of a loop but you would have to test if that is faster.

Naming file to save when php export to xls

My code kinda weird, i don't know what would be the problem of my code.. here's my code.
$project_name = $_POST['project_name'];//example the retrieved data is Testing Project
$quote_id = $_POST['quote_id'];//example the retrieved data is 34425
$date = date("M/d/y");
$as_agent = $_POST['as_agent'];//example the retrieved data is John Doe
$name_for_project = $project_name.' '.$quote_id.' '.$date.' '.$as_agent;
header("Content-Type: application/vnd.ms-excel");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("content-disposition: attachment;filename='".$name_for_project.".xls'");
ob_start();
//The rest of the code is Workbook
echo"
<?xml version='1.0'?>
<?mso-application progid='Excel.Sheet'?>
<Workbook
xmlns='urn:schemas-microsoft-com:office:spreadsheet'
xmlns:o='urn:schemas-microsoft-com:office:office'
xmlns:x='urn:schemas-microsoft-com:office:excel'
xmlns:ss='urn:schemas-microsoft-com:office:spreadsheet'
xmlns:html='http://www.w3.org/TR/REC-html40'>
<DocumentProperties xmlns='urn:schemas-microsoft-com:office:office'>
<Version>11.8036</Version>
</DocumentProperties>
<ExcelWorkbook xmlns='urn:schemas-microsoft-com:office:excel'>
<WindowHeight>6795</WindowHeight>
<WindowWidth>8460</WindowWidth>
<WindowTopX>120</WindowTopX>
<WindowTopY>15</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>";
//so on and so fort...
When this code runs it only capture the $project_name value.. Please Help me... Thank you..
The following line header("... will prompt to save a file with apostrophes to the beginning and end of the file.
Example: 'project_quote_id_2013-08-31_as_agent.xls'
header("content-disposition: attachment;filename='".$name_for_project.".xls'");
which should be changed to:
header("content-disposition: attachment;filename=".$name_for_project.".xls");
The code below will produce/echo a saveable file called: project_quote_id_2013-08-31_as_agent.xls (as of today's date for testing).
If, and as Aiden stated in his answer, you are using slashes as your seperator for your $date variable, you will encounter problems.
Try to avoid using spaces for seperators, use hyphens and/or underscores to seperate your values.
For example, this will save to prompt to a file with some dummy content.
<?php
$date = gmdate('Y-m-d', time() - 3600 * $hours);
$project_name = "project";
$quote_id = "quote_id";
$as_agent = "as_agent";
$name_for_project = $project_name.'_'.$quote_id.'_'.$date.'_'.$as_agent;
$file = $name_for_project.".xls";
// start buffering
ob_start();
// sample dynamically generated data
echo '<table border="1"> ';
echo '<tr><th>Name</th><th>Age</th></tr>';
for ($i=0; $i<=5; $i++) { echo "<tr><td>Name$i</td><td>".($i+1)."</td></tr>";
}
echo '</table>';
$content = ob_get_contents();
ob_end_clean();
header("Expires: 0");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Content-type: application/vnd.ms-excel;charset:UTF-8");
header('Content-length: '.strlen($content));
header('Content-disposition: attachment; filename='.basename($file));
// output all contents
echo $content;
exit;
?>
will produce a file called: project_quote_id_2013-08-31_as_agent.xls (as of today's testing date) and will prompt the user to save it under that name.
The rest of the code that is to insert the actual content, will need to be inserted accordingly, because there was nothing else posted in regards to variables or text associated with the question/code.
Do any of your other variables contain invalid characters for a file name? E.g. If you declared your $date as 30/08/2013 then php will not concatenate your variables past the invalid character.
Spaces affect in naming filename. what i do is transform my code into.
$project_name = $_POST['project_name'];//example the retrieved data is Testing Project
$quote_id = $_POST['quote_id'];//example the retrieved data is 34425
$date = date("M/d/y");
$as_agent = $_POST['as_agent'];//example the retrieved data is John Doe
$proj_name = str_replace(' ', '', $project_name);
$as_agent = str_replace(' ', '', $as_agent);
$name_for_project = $proj_name."-".$quote_id."-".$date."-".$as_agent;
header("Content-Type: application/vnd.ms-excel");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("content-disposition: attachment;filename=$name_for_project.xls");
Thanks to #Fred -ii-

Categories