PHP export CSV Table from Database - php

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);
?>

Related

Enabling PHP errors when creating a CSV file from database

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);

Force a .txt file to download after creating list of mysql result

I want to download a file which includes the results of my mysql query but my problem is, the .txt file includes only the last result of my mysql query. It should includes actually 5 results like this:
http://user:password#server.com:8080
Can someone show me where here the problem is?
<?php
$result = mysql_query("SELECT serverurl FROM ibn");
echo mysql_error();
while ($row = mysql_fetch_array($result)) {
$result2 = mysql_query("SELECT streamport,streamname FROM streams");
echo mysql_error();
while ($row2 = mysql_fetch_array($result2)) {
$result3 = mysql_query("SELECT client_username,client_openpasswd FROM clients WHERE `client_id` = '$id' ");
echo mysql_error();
while ($row3 = mysql_fetch_array($result3)) {
$streamurl= $row['serverurl'];
$streamport = $row2['streamport'];
$streamuser= $row3['client_username'];
$streampassword= $row3['client_openpasswd'];
$streamchannel= $row2['streamname'];
echo "<p>http://$streamuser:$streampassword#$streamurl:$streamport</p>";
}
}
}
//Generate text file on the fly
header("Content-type: text/plain");
header("Content-Disposition: attachment; filename=bouquet.txt");
?>
Your basic output can be achieved by moving your calls to header() to the top of the script and emitting your data later. The header commands will only be effective if they're issued before any output is sent to the client.
You can demonstrate this with a simple script:
<?php
header("Content-type: text/plain");
header("Content-Disposition: attachment; filename=bouquet.txt");
echo "A line of text\n";
The remainder of your code is more problematic. It's not clear why you're doing this, but the effect of your code is to produce the cartesian product of the three tables. i.e. every row in every table is combined with every row in every other table. I doubt this is actually what you want, but...
You can achieve the same result more efficiently by using an SQL JOIN with no ON clause. Using that and concatenating the required fields you can do almost everything you want in a single SQL query:
select
concat('http://',
clientname,':',
clientopenpassword,'#',
serverurl,':',
streamsport)
as URL
from ibn, streams, clients where client_id=1
I'll leave converting this to a working PHP script as an exercise for the reader, but your code above provides a good template. Remember, only one query and one loop to fetch the result and emit it.
Note that mysql_*() is deprecated - use mysqli_*() for new code. You should also watch for possible SQL injection where you use $id in your query.

PHP create a complex CSV file

I am in need to create a CSV file getting the data from a mySQL DB.
The fact is that I want the CSV tp be corrected labeled and not just writing the data like this:
id,name,url
1,thisismyname,thisismyurl
I need the CSV file to look well ordered and each data inserted in the relative column.
Also with the function I am going to add below I can only grab the data from the DB and write it to the CSV file as it is. But I need to work with the data and have the CSV labeled in this way:
Campaign Name:
Name of the campaign
Campaign Url:
Url of the campaign
Tot visits:
Tot of visits
Tot unique visits:
Tot of unique visits
id name url
1 thisname this url
2 thisname this url
3 thisname this url
4 thisname this url
5 thisname this url
This is the PHP code I have so far..I need to understand how to achieve a correct structure of the CSV with PHP and adding the lines in it the exact way I want..
Thanks for your help!
function genCSV($filename, $attachment = true, $headers = true) {
// send response headers to the browser
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename=' . $filename);
$fp = fopen('php://output', 'w');
$query = "SELECT * FROM campaigns";
$result = mysql_query($query) or die(mysql_error());
if ($headers) {
// output header row (if at least one row exists)
$row = mysql_fetch_assoc($result);
if ($row) {
fputcsv($fp, array_keys($row));
// reset pointer back to beginning
mysql_data_seek($result, 0);
}
}
while ($row = mysql_fetch_assoc($result)) {
fputcsv($fp, $row);
}
fclose($fp);
}
Here is a much less elegant solution than the one proposed by #Tom Regner.
I needed to backup certain database tables (all those with a given prefix) but not others. This method, though somewhat slow, allows you to select exactly which tables and which columns from those tables are copied. It was originally written to allow each piece of data to be AES encrypted before being entered into the file but there are other uses for it. As written here, the result is a CSV file with the first line containing the list of columns for the table and the rest containing the data in CSV. It will stand adaptation to output the result of any sql into CSV, if you like.
Obviously: mysqlidb = mysqli databse resource, backups/ = directory to put finished files in.
FWIIW, here is the code:
$sql="SHOW TABLES LIKE 'yourtable%'";
$result = $mysqlidb->query($sql);
$tableresult=$mysqlidb->query($sql);
while($tables=$tableresult->fetch_assoc())
{
$keys=array_keys($tables);
$tablename=$tables[$keys[0]];
echo "Writing $tablename <BR>";
$file=fopen("backups/$tablename.enc","w");
$cols=array();
$sql="SHOW COLUMNS FROM $tablename";
$result=$mysqlidb->query($sql);
while($row=$result->fetch_assoc())
{
$cols[]=$row['Field'];
}
fputcsv($file,$cols);
$sql="SELECT * FROM $tablename";
$result=$mysqlidb->query($sql);
while($row=$result->fetch_assoc())
{
fputcsv($file,$row);
}
fclose($file);
}

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