PHP not creating downloadable CSV file - php

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.

Related

MySQLi Query To Excel Generating Two Blank Row

I am trying to generate excel file for my dynamic query using below codes.
$cname = $_POST["cname"];
$cnote = $_POST["cnote"];
$ccondition = $_POST['sql'];
$crange = $_POST['start'] . "-" . $_POST['end'];
$sql_query = $ccondition;
$filename = "export".date('Ymd') . ".xls";
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header("Content-Disposition: attachment; filename=\"$filename\"");
$show_coloumn = false;
$resultset = mysqli_query($mysqli, $sql_query) or die("database error:". mysqli_error($mysqli));
$rowcount=mysqli_num_rows($resultset);
$developer_records = array();
while( $rows = mysqli_fetch_assoc($resultset) ) {
$developer_records[] = $rows;
}
if(!empty($developer_records)) {
foreach($developer_records as $record) {
if(!$show_coloumn) {
echo implode("\t", array_keys($record)) . "\n";
$show_coloumn = true;
}
echo implode("\t", array_values($record)) . "\n";
}
}
I am facing two issue in it.
1) When I try to open it in excel 2016, its giving error like below but when I press yes its opening file.
2) each my exported excel file have two blank row on top before header row, I don't know from where its coming and how I can fix it.
I have searched lot for it but I have not found any working solution for it. Let me know if someone can help me for solve the issues. Thanks

fputcsv Creates the file but downloads it empty

I have this piece of PHP code that's intended to retrieve data from a mySQL database, and export it to a CSV file that has to be automatically downloaded after it was created.
$connection = mysqli_connect($host, $username, $password, $dbname) or die("Connection Error " . mysqli_error($connection));
// fetch mysql table rows
$sql = "select * from users";
$result = mysqli_query($connection, $sql) or die("Selection Error " . mysqli_error($connection));
$fp = fopen('users.csv', 'w');
while($row = mysqli_fetch_assoc($result)) {
fputcsv($fp, $row);
}
fclose($fp);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="users.csv"');
mysqli_close($connection);
The problem here is that it:
Retrieves the data.
Retrieves the CSV file on the server in the same directory of the export.php file with the data on it.
Downloads the file with the same name BUT it's EMPTY
Thanks.
You're writing it to a file called users.csv, but the file you are forcing the user to download is the output of the page.
As long as your query is correct, once the PHP script has run, there should be a file called users.csv in the same directory as the PHP file that contains the correct data.
You need to output the data to the browser for it to be attributed to the file you're downloading.
Try this:
//Connect to database
$connection = mysqli_connect($host, $username, $password, $dbname) or die("Connection Error " . mysqli_error($connection));
//Fetch mysql table rows
$sql = "select * from users";
$result = mysqli_query($connection, $sql) or die("Selection Error " . mysqli_error($connection));
//Close connection
mysqli_close($connection);
//Set $output
$output = "";
//Set header values
$headers = array("Header 1", "Header 2", "Header 3");
//Insert header values to $output
foreach($headers as $h){
$output .= fieldCheck($h) . ",";
}
$output = rtrim($output, ","). "\n";
//Iterate through results
while($row = mysqli_fetch_assoc($result)) {
foreach($row as $cell){
//Comma-separate each value
$output .= fieldCheck($cell).",";
}
//Remove last comma of each line and add newline
$output = rtrim($output, ",") . "\n";
}
//Set headers
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="users.csv"');
//Output
echo $output;
exit;
//Function in case of comma in field
function fieldCheck($string){
if(strpos($string, ",") !== false){
$string = '"'.$string.'"';
}
return $string;
}
I have seen this question come up quite a few times and here the user is sending the data to "users.csv" as shown below:
$fp = fopen('users.csv', 'w');
The issue is that unless the file "users.csv" is already created there is nothing to write the data to, so the CSV is blank. The "fopen" does not create the file it only opens an existing file and the "w" directive then instructs "fputcsv" to put it into the file "users.csv" which may not exist and if the file does exist it writes over the existing file.
Here is an explainer PHP script that will send the output (CSV) to a filename of your choice for downloading:
//Connect to database
$connection = mysqli_connect($host, $username, $password, $dbname) or die("Connection Error " . mysqli_error($connection));
//Get the data
//The order and number of elements must match the header below or the data
//will appear in the wrong columns.
$sql = "SELECT FirstName,LastName,Address,City,State,Zip FROM users";
$result = mysqli_query($connection, $sql) or die("Selection Error " . mysqli_error($connection));
//Close connection
mysqli_close($connection);
//Name of the file you want the user to download can be any name but
//use the .CSV file extension so it will be recognized
//as a CSV when downloaded.
$NameOfCSVFileToDownload = "MyCSVFile.csv";
//set headers tells the page what to do
header("Content-Type: application/csv; charset=utf-8");
header("Content-Disposition: attachment;filename=\"$NameOfCSVFileToDownload\"");
//Where to send the data -
//there are several option but sending it to output will insert
//the data into "$NameOfCSVFileToDownload" when complete, your output.
//Output is a way to access I/O streams
$output = fopen("php://output", 'w');
//Add the header or 1st row for your data
//-notice we are sending it to "$output" you can add any names you want
//for this header row but make sure that the number of columns in the header
//matches the number of columns you are retrieving from the database or they
//will not line up when you open up the CSV and things will look scrambled.
fputcsv($output, array('FirstName','LastName','Address','City','State','Zip'));
//Loop through the data and insert the data into "$output"
while($rows = $result->fetch_assoc()){
fputcsv($output, $rows);
}
//Close the "$output" file to complete the write.
fclose($output);
That's all, call the page and it will prompt to open or download the CSV that contains data. If it is still blank make sure your SQL statement is actually pulling data.
You can also review the PHP manual on streams to better understand.
PHP Manual
Combining a few ideas mentioned in the comments:
Output directly to stdout (rather than a users.csv file). This prevents concurrent processes from clashing with the same output file. No need to buffer temporary results in a variable, either.
Use fputcsv()'s 3rd argument to specify ';' as the field separator. No need to rewrite special code for that.
Use array_map() and a custom filter to add quotes around all the fields.
// Helper function to surround a string with double quotes
function pad_with_quotes($s) {
return '"' . $s . '"';
}
// Helper function to output a row to $fp:
function output_row($fp, $row) {
// Separate fields with ';':
fputcsv($fp, array_map('pad_with_quotes', $row), ';');
}
// Send HTTP headers
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="users.csv"');
// Open a pointer to stdout:
$fp = fopen('php://output', 'w'); // TO DO: check for fopen() failure
// Output headers (padded with quotes):
output_row($fp, ['foo', 'bar']); // TO DO: change headers
// DB connection/query goes here; omitted for brevity
// Loop through DB results:
while($row = mysqli_fetch_assoc($result)) {
// Output a row of results:
output_row($fp, row);
}

exporting MYSQL fectched row into csv in php

Following is a part of my php program which is written to fetch rows from mysql table from input IDs. But I wanted to get the result directly to '.csv' file. I know php has built in function for that, but I could not include it effectively. So can anyone give a direction for export to csv using advanced php function?
$file = fopen("fetched.csv","w");
for($i=0;$i<=$len;$i++)
{
$lo = $locus[$i];
mysqli_select_db($conn,"microarray");
$query = mysqli_query("SELECT * FROM anatomy WHERE locus_id = "$lo"");
while ($row = mysqli_fetch_row($query))
{
}
}
You don't necessarily need an "advanced php function". A csv file is just a sequence of comma separated columns. Try this out.
function addRowToCsv(& $csvString, $cols) {
$csvString = implode(',', $cols) . PHP_EOL;
}
$csvString = '';
$first = true;
while ($row = mysqli_fetch_assoc($query)) {
if ($first === true) {
$first = false;
addRowToCsv($csvString, array_keys($row));
}
addRowToCsv($csvString, $row);
}
header('Content-type: text/csv');
header('Content-disposition: attachment;filename=MyCsvFile.csv');
echo $csvString;
Notice that the first argument to addRowToCsv is passed by reference. This is not required and you could easily use a return value, but this is just how I would do it.
-- Edit --
I just noticed you are saving the output to a file rather than serving it as a download. If that is what you want to do then use the above but replace
header('Content-type: text/csv');
header('Content-disposition: attachment;filename=MyCsvFile.csv');
echo $csvString;
With..
file_put_contents('MyCsvFile.csv', $csvString);

send an email exported cvs file php mysql

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/

Forcing file download in PHP - inside Joomla framework

I have some PHP code that runs a query on a database, saves the results to a csv file, and then allows the user to download the file. The problem is, the csv file contains page HTML around the actual csv content.
I've read all the related questions here already, including this one. Unfortunately my code exists within Joomla, so even if I try to redirect to a page that contains nothing but headers, Joomla automatically surrounds it with its own navigation code. This only happens at the time of download; if I look at the csv file that's saved on the server, it does not contain the HTML.
Can anyone help me out with a way to force a download of the actual csv file as it is on the server, rather than as the browser is editing it to be? I've tried using the header location, like this:
header('Location: ' . $filename);
but it opens the file in the browser, rather than forcing the save dialog.
Here's my current code:
//set dynamic filename
$filename = "customers.csv";
//open file to write csv
$fp = fopen($filename, 'w');
//get all data
$query = "select
c.firstname,c.lastname,c.email as customer_email,
a.email as address_email,c.phone as customer_phone,
a.phone as address_phone,
a.company,a.address1,a.address2,a.city,a.state,a.zip, c.last_signin
from {$dbpre}customers c
left join {$dbpre}customers_addresses a on c.id = a.customer_id order by c.last_signin desc";
$votes = mysql_query($query) or die ("File: " . __FILE__ . "<br />Line: " . __LINE__ . "<p>{$query}<p>" . mysql_error());
$counter = 1;
while ($row = mysql_fetch_array($votes,1)) {
//put header row
if ($counter == 1){
$headerRow = array();
foreach ($row as $key => $val)
$headerRow[] = $key;
fputcsv($fp, $headerRow);
}
//put data row
fputcsv($fp, $row);
$counter++;
}
//close file
fclose($fp);
//redirect to file
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=".$filename);
header("Content-Transfer-Encoding: binary");
readfile($filename);
exit;
EDITS
Full URL looks like this:
http://mysite.com/administrator/index.php?option=com_eimcart&task=customers
with the actual download link looking like this:
http://mysite.com/administrator/index.php?option=com_eimcart&task=customers&subtask=export
MORE EDITS
Here's a shot of the page that the code is on; the generated file still is pulling in the html for the submenu. The code for the selected link (Export as CSV) is now
index.php?option=com_eimcart&task=customers&subtask=export&format=raw
Now here is a screenshot of the generated, saved file:
It shrank during the upload here, but the text highlighted in yellow is the html code for the subnav (list customers, add new customer, export as csv). Here's what my complete code looks like now; if I could just get rid of that last bit of html it would be perfect.
$fp= fopen("php://output", 'w');
$query = "select c.firstname,c.lastname,c.email as customer_email,
a.email as address_email,c.phone as customer_phone,
a.phone as address_phone, a.company, a.address1,
a.address2,a.city,a.state,a.zip,c.last_signin
from {$dbpre}customers c
left join {$dbpre}customers_addresses a on c.id = a.customer_id
order by c.last_signin desc";
$votes = mysql_query($query) or die ("File: " . __FILE__ . "<br />Line: " . __LINE__ . "<p>{$query}<p>" . mysql_error());
$counter = 1;
//redirect to file
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=customers.csv");
header("Content-Transfer-Encoding: binary");
while ($row = mysql_fetch_array($votes,1)) {
//put header row
if ($counter == 1){
$headerRow = array();
foreach ($row as $key => $val)
$headerRow[] = $key;
fputcsv($fp, $headerRow);
}
//put data row
fputcsv($fp, $row);
$counter++;
}
//close file
fclose($fp);
UPDATE FOR BJORN
Here's the code (I think) that worked for me. Use the RAW param in the link that calls the action:
index.php?option=com_eimcart&task=customers&subtask=export&format=raw
Because this was procedural, our link was in a file called customers.php, which looks like this:
switch ($r['subtask']){
case 'add':
case 'edit':
//if the form is submitted then go to validation
include("subnav.php");
if ($r['custFormSubmitted'] == "true")
include("validate.php");
else
include("showForm.php");
break;
case 'delete':
include("subnav.php");
include("process.php");
break;
case 'resetpass':
include("subnav.php");
include("resetpassword");
break;
case 'export':
include("export_csv.php");
break;
default:
include("subnav.php");
include("list.php");
break;
}
So when a user clicked on the link above, the export_csv.php file is automatically included. That file contains all the actual code:
<?
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=customers.csv");
header("Content-Transfer-Encoding: binary");
$fp= fopen("php://output", 'w');
//get all data
$query = "select
c.firstname,c.lastname,c.email as customer_email,
a.email as address_email,c.phone as customer_phone,
a.phone as address_phone,
a.company,a.address1,a.address2,a.city,a.state,a.zip, c.last_signin
from {$dbpre}customers c
left join {$dbpre}customers_addresses a on c.id = a.customer_id order by c.last_signin desc";
$votes = mysql_query($query) or die ("File: " . __FILE__ . "<br />Line: " . __LINE__ . "<p>{$query}<p>" . mysql_error());
$counter = 1;
while ($row = mysql_fetch_array($votes,1)) {
//put header row
if ($counter == 1){
$headerRow = array();
foreach ($row as $key => $val)
$headerRow[] = $key;
fputcsv($fp, $headerRow);
}
//put data row
fputcsv($fp, $row);
$counter++;
}
//close file
fclose($fp);
This is a piece of sample code that I just cooked up to help you out. Use it as an action method in your controller.
function get_csv() {
$file = JPATH_ADMINISTRATOR . DS . 'test.csv';
// Test to ensure that the file exists.
if(!file_exists($file)) die("I'm sorry, the file doesn't seem to exist.");
// Send file headers
header("Content-type: text/csv");
header("Content-Disposition: attachment;filename=test.csv");
// Send the file contents.
readfile($file);
}
This alone will not be enough, because the file you download will still contain the surrounding html. To get rid of it and only receive the csv file's contents you need to add format=raw parameter to your request. In my case the method is inside the com_csvexample component, so the url would be:
/index.php?option=com_csvexample&task=get_csv&format=raw
EDIT
In order to avoid using an intermediate file substitute
//set dynamic filename
$filename = "customers.csv";
//open file to write csv
$fp = fopen($filename, 'w');
with
//open the output stream for writing
//this will allow using fputcsv later in the code
$fp= fopen("php://output", 'w');
Using this method you have to move the code that sends headers before anything is written to the output. You also won't need the call to the readfile function.
Add this method to your controller:
function exportcsv() {
$model = & $this->getModel('export');
$model->exportToCSV();
}
Then add a new model called export.php, code below. You will need to change or extend the code to your situation.
<?php
/**
* #package TTVideo
* #author Martin Rose
* #website www.toughtomato.com
* #version 2.0
* #copyright Copyright (C) 2010 Open Source Matters. All rights reserved.
* #license http://www.gnu.org/copyleft/gpl.html GNU/GPL
*/
//No direct acesss
defined('_JEXEC') or die();
jimport('joomla.application.component.model');
jimport( 'joomla.filesystem.file' );
jimport( 'joomla.filesystem.archive' );
jimport( 'joomla.environment.response' );
class TTVideoModelExport extends JModel
{
function exportToCSV() {
$files = array();
$file = $this->__createCSVFile('#__ttvideo');
if ($file != '') $files[] .= $file;
$file = $this->__createCSVFile('#__ttvideo_ratings');
if ($file != '') $files[] .= $file;
$file = $this->__createCSVFile('#__ttvideo_settings');
if ($file != '') $files[] .= $file;
// zip up csv files to be delivered
$random = rand(1, 99999);
$archive_filename = JPATH_SITE.DS.'tmp'.DS.'ttvideo_'. strval($random) .'_'.date('Y-m-d').'.zip';
$this->__zip($files, $archive_filename);
// deliver file
$this->__deliverFile($archive_filename);
// clean up
JFile::delete($archive_filename);
foreach($files as $file) JFile::delete(JPATH_SITE.DS.'tmp'.DS.$file);
}
private function __createCSVFile($table_name) {
$db = $this->getDBO();
$csv_output = '';
// get table column names
$db->setQuery("SHOW COLUMNS FROM `$table_name`");
$columns = $db->loadObjectList();
foreach ($columns as $column) {
$csv_output .= $column->Field.'; ';
}
$csv_output .= "\n";
// get table data
$db->setQuery("SELECT * FROM `$table_name`");
$rows = $db->loadObjectList();
$num_rows = count($rows);
if ($num_rows > 0) {
foreach($rows as $row) {
foreach($row as $col_name => $value) {
$csv_output .= $value.'; ';
}
$csv_output .= "\n";
}
}
$filename = substr($table_name, 3).'.csv';
$file = JPATH_SITE.DS.'tmp'.DS.$filename;
// write file to temp directory
if (JFile::write($file, $csv_output)) return $filename;
else return '';
}
private function __deliverFile($archive_filename) {
$filesize = filesize($archive_filename);
JResponse::setHeader('Content-Type', 'application/zip');
JResponse::setHeader('Content-Transfer-Encoding', 'Binary');
JResponse::setHeader('Content-Disposition', 'attachment; filename=ttvideo_'.date('Y-m-d').'.zip');
JResponse::setHeader('Content-Length', $filesize);
echo JFile::read($archive_filename);
}
/* creates a compressed zip file */
private function __zip($files, $destination = '') {
$zip_adapter = & JArchive::getAdapter('zip'); // compression type
$filesToZip[] = array();
foreach ($files as $file) {
$data = JFile::read(JPATH_SITE.DS.'tmp'.DS.$file);
$filesToZip[] = array('name' => $file, 'data' => $data);
}
if (!$zip_adapter->create( $destination, $filesToZip, array() )) {
global $mainframe;
$mainframe->enqueueMessage('Error creating zip file.', 'message');
}
}
}
?>
Then go to your default view.php and add a custom buttom, e.g.
// custom export to set raw format for download
$bar = & JToolBar::getInstance('toolbar');
$bar->appendButton( 'Link', 'export', 'Export CSV', 'index.php?option=com_ttvideo&task=export&format=raw' );
Good luck!
You can use Apache's mod_cern_meta to add HTTP headers to static files. Content-Disposition: attachment. The required .htaccess and .meta files can be created by PHP.
Another way to output CSV data in a Joomla application is to create a view using CSV rather than HTML format. That is, create a file as follows:
components/com_mycomp/views/something/view.csv.php
And add content similar to the following:
<?php
// No direct access
defined('_JEXEC') or die;
jimport( 'joomla.application.component.view');
class MyCompViewSomething extends JViewLegacy // Assuming a recent version of Joomla!
{
function display($tpl = null)
{
// Set document properties
$document = &JFactory::getDocument();
$document->setMimeEncoding('text/csv');
JResponse::setHeader('Content-disposition', 'inline; filename="something.csv"', true);
// Output UTF-8 BOM
echo "\xEF\xBB\xBF";
// Output some data
echo "field1, field2, 'abc 123', foo, bar\r\n";
}
}
?>
Then you can create file download links as follows:
/index.php?option=com_mycomp&view=something&format=csv
Now, you would be right to question the 'inline' part in the Content-disposition. If I recall correctly when writing this code some years ago, I had problems with the 'attachment' option. This link which I just googled now seemed familiar as the driver for it: https://dotanything.wordpress.com/2008/05/30/content-disposition-attachment-vs-inline/ . I've been using 'inline' ever since and am still prompted to save the file appropriately from any browsers I test with. I haven't tried using 'attachment' any time recently, so it may work fine now of course (the link there is 7 years old now!)

Categories