I have recently made a website and have a members table in my sql. I have an admin page that has the ability to download that with column names; however I used to use INTO OUTFILE but that is not allowed on my host. I came up with this code to download the file:
if(file_exists('downloads/members_'.date("m-d-Y").'.csv') == true) {
header("Location: /downloads/members_".date("m-d-Y").".csv");
}
$output = fopen('downloads/members_'.date("m-d-Y").'.csv', 'w+');
fputcsv($output, array('memberID','username', 'password', 'email', 'active', 'resetToken', 'resetComplete', 'support', 'supportToken' ));
$rows = mysql_query("SELECT * FROM members;");
while ($row = mysql_fetch_assoc($rows)) fputcsv($output,$row);
header("Location: /downloads/members_".date("m-d-Y").".csv");
exit;
This just outputs the column names and I have never used fputcsv before and am a tad confused on what I am doing wrong. I get the file to download but not with the table in it.
[EDIT] I just tried it with a valid sql query and it does not work. updated code above. Also There is stuff in the members table.
Try this:
if (isset($_POST['download'])) {
$result = mysql_query("SELECT * FROM members", $connection);
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename=yourcsv.csv');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
$csvoutput = fopen('php://output', 'w');
$row = getRow($result);
$headers = array_keys($row);//columns from db e.g, memberID','username',...
fputcsv($csvoutput, $headers);
fputcsv($csvoutput, $row);
while ($row = getRow($result)) {
fputcsv($csvoutput, $row);
}
fclose($csvoutput);
exit;
}
Here is your getRow() function:
function getRow($res){
return mysql_fetch_assoc($res);
}
And in your html:
<input type="submit" name="download" value="Download CSV">
Here is realtime demo with sqllite3 database. Uncomment the create database and insert statement in order to see the working demo. I have tested and it is working fine. I hope this will help you.
Related
I am trying to write a simple PHP code to export to excel the data selected between two dates. On clicking the 'Export to Excel' button in the HTML page which will redirect to php file with the below code, my excel is not getting downloaded. Can someone tell me where the error is and what modification needs to be made. Tell me in the simplest way possible.
<?php
include ("conn.php");
if(isset($_POST["export"]))
{
$connect = mysqli_connect("localhost", "root", "", "cruddatabase");
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');
$output = fopen("php://output", "w");
fputcsv($output, array('ID Company Name','Company Type','Name','Email','Contact Number','Anniversary Date','Organisation Name','Meeting','Timeline For Conversation','Currency','Card','Locations'));
$query = "SELECT * FROM crudtable WHERE adate >= '$fdate' AND adate <= '$tdate' ORDER BY adate DESC";
$result = mysqli_query($con, $query);
while($row = mysqli_fetch_assoc($result))
{
fputcsv($output, $row);
}
fclose($output);
}
?>
I am having trouble debugging a php script that I use for downloading .pdf files.
The script works fine for one user but doesn't work for another giving blank page.
What I am pretty sure is:
the part responsible for downloading works fine for both users
The query works fine and gets correct data from the serwer
All of the files are in the same directory (and as I already wrote it works perfectly for the first user)
Please give me a hint on where the bug might be or how to find it.
Thanks so much in advance.
Here's my code:
.htacces :
<Directory /faktury/>
Order deny,allow
Deny from all
</Directory>
html :
<form action="downloadfv.php" method="post">
<input type="text" name="fv" id="fv" value="$rowvariable" hidden />
<button type="submit"">Download</button>
</form>
downloadfv.php :
<?php
session_start();
if(!isset($_SESSION['zalogowany']))
{
header('Location: logowanie.php');
exit();
}
require_once "connect.php";
mysqli_report(MYSQLI_REPORT_STRICT);
$polaczenie = new mysqli($host, $db_user, $db_password, $db_name);
mysqli_query($polaczenie, "SET CHARSET utf8");
mysqli_query($polaczenie, "SET NAMES `utf8` COLLATE `utf8_polish_ci`");
if (mysqli_connect_errno())
{
echo "Could not connect to server" . mysqli_connect_error();
}
$idogloszenia = htmlspecialchars($_POST['fv'], ENT_QUOTES,'UTF-8');
$sql = "SELECT * FROM faktury WHERE user='{$_SESSION['user']}' AND idogloszenia = '$idogloszenia' ORDER BY idogloszenia DESC LIMIT 1";
$result = $polaczenie->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$file = "./faktury/".$row["nazwapdf"].".pdf";
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
}
} else {
echo " <div class='itemsname'>
<span style='padding:10px; font-size:90%'><u>No invoice available.</u></span>
</div>";
}
$polaczenie->close();
?>
The script works fine. The bug was inside my test database. It ocurred that I've had duplicated rows with similar data in them and the query selected wrong rows.
So the script can be used although as #mehdi pointed out it is not secure.
Thank you #chris85 for your hints.
I have an export function on my website. It exports from a MySQL result query and lets it save the file as CSV locally on user's computer.
Export functionality is almost working, except for one thing. Inside the exported and saved CSV right after all the exported MySQL data at the end the PHP script also includes the entire form's code.
Not sure why.
Export form. Let's you pick what data to export using <select>. This whole code shows up in CSV file after all data:
<div class="btn-group-vertical btn-group-lg btn-block">
<span class="glyphicon glyphicon-step-backward"></span> Back
</div>
<hr />
<?php
// show potential errors / feedback (from registration object)
if (isset($obj1)) {
if ($obj1->errors) {
foreach ($obj1->errors as $error) {
echo $error;
}
}
if ($obj1->messages) {
foreach ($obj1->messages as $message) {
echo $message;
}
}
}
?>
<form name="exportcsvform" method="post" action="admin_export.php" role="form">
<div class="form-group">
<label for="export_data" class="sr-only">Choose:</label>
<select size="1" name="export_data" id="export_data" class="input-lg">
<option value="" selected="selected" disabled>Choose</option>
<?php $obj1->getData(); ?>
</select>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default btn-lg" name="export" id="export"><span class="glyphicon glyphicon-save"></span>Export</button>
</div>
<hr />
</form>
The PHP function that generates the CSV. It's inside a class, let's call it Class1:
private function exportData()
{
if(isset($_POST['export_data'])){
$this->db_connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if (!$this->db_connection->set_charset("utf8")) {
$this->errors[] = $this->db_connection->error;
}
if (!$this->db_connection->connect_errno) {
$export_data_id = $_POST['export_data'];
$sql =<<<EOF
SELECT col1, col2, col3
FROM table1
JOIN table2 ON table2.col0=table1.col0
WHERE table1.col0 = $export_data_id;
EOF;
// 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('col1','col2','col3'));
$query_export_data = $this->db_connection->query($sql);
$rows = array();
while($r = mysqli_fetch_assoc($query_export_data)){
$rows[] = $r;
}
// loop over the rows, outputting them
foreach ($rows as $r) fputcsv($output, $r);
}else{
// show error
}
}
}
Main PHP file that loads headers, content, footer and is also the action for the export form(admin_export.php):
<?php
// include the configs / constants for the database connection
require_once("config/db.php");
// load the login class
require_once("classes/Login.php");
// create a login object. when this object is created, it will do all login/logout stuff automatically
// so this single line handles the entire login process. in consequence, you can simply ...
$login = new Login();
// only administrators can see
if (login stuff) {
// require once classes here
require_once("classes/User.php");
$user = new User();
require_once("classes/Class1.php");
$class1 = new Class1();
include("includes/header.php");
// include views here
// include("views/admin_whatever_view.php");
include("views/admin_export_view.php");
include("includes/footer.php");
}else{
echo "<h1>Access denied</h1>";
include("views/go_back_view.php");
}
?>
Most likely it's because you need to flush the output buffer.
Here's a simple export CSV function based on an array taken from ExchangeCore blog. Looks like the only difference is the ob_* functions
public function outputCsv($fileName, $assocDataArray)
{
ob_clean();
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false);
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename=' . $fileName);
if(isset($assocDataArray['0'])){
$fp = fopen('php://output', 'w');
fputcsv($fp, array_keys($assocDataArray['0']));
foreach($assocDataArray AS $values){
fputcsv($fp, $values);
}
fclose($fp);
}
ob_flush();
}
I'm new in PHPExcel library and this is my first experience. I'm trying to export MySQL data to Ms Excel by formatting before. I've implemented a procedure that simply formats headings of the table with bold fonts and saves them with all relevants data to the spreadsheet. However, when I run the procedure, it displays the following error:
Fatal error: Call to undefined function getRow() in C:\Xampp\htdocs\test.php on line 182
Here is the PHP code:
require_once 'PHPExcel.php';
require_once 'PHPExcel/IOFactory.php';
require_once 'PHPExcel/Writer/Excel2007.php';
// create mysql query
$query_export = "SELECT * FROM `table1` ORDER BY `date` ASC";
// execute query
$result = mysqli_query($GLOBALS['mysqli'], $query_export) or die ("<b>Couldn't execute SQL query:</b> " . mysqli_error($GLOBALS['mysqli']));
try {
$sheet = new PHPExcel();
// set metadata
$sheet->getProperties()->setCreator('www.example.com')
->setLastModifiedBy('www.example.com')
->setTitle('Report on Table')
->setKeywords('report tables etc.');
// set default settings
$sheet->getDefaultStyle()->getAlignment()->setVertical(
PHPExcel_Style_Alignment::VERTICAL_TOP);
$sheet->getDefaultStyle()->getAlignment()->setHorizontal(
PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$sheet->getDefaultStyle()->getFont()->setName('Calibri');
$sheet->getDefaultStyle()->getFont()->setSize(12);
// get reference to active spreadsheet in workbook
$sheet->setActiveSheetIndex(0);
$activeSheet = $sheet->getActiveSheet();
// populate with data
$row = getRow($result); // line 182
$colHeaders = array_keys($row);
$col = 'A';
$rownum = 1;
// set column headings
foreach ($colHeaders as $header) {
$activeSheet->setCellValue($col . $rownum, $header);
$activeSheet->getStyle($col . $rownum)->getFont()->setBold(true);
$activeSheet->getColumnDimension($col)->setAutoSize(true);
$col++;
}
// populate individual cells with data
do {
$col = 'A';
$rownum++;
foreach ($row as $value) {
$activeSheet->setCellValue($col++ . $rownum, $value);
}
} while ($row = getRow($result));
// setting headers
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename=Export.xlsx');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
$writer = PHPExcel_IOFactory::createWriter($sheet, 'Excel2007');
$writer->save('php://output');
exit();
} catch (Exception $e) {
$error = $e->getMessage();
}
// display error
if (isset($error)) {
echo "<p>" .$error. "</p>";
}
// free resultset
mysqli_free_result($result);
// close db connection
$GLOBALS['mysqli']->close();
exit();
Any help is appreciated.
UPDATE
The following tutorial is used to create above mentioned code:
http://www.youtube.com/watch?v=L6MQQvBi-ks
I believe you need to define getRow or use something like this:
http://php.net/manual/en/mysqli-result.fetch-row.php
I have problem with writing csv file using fputcsv. Its putting the page html also into the csv file. Whats wrong with my code ?
//Excel header
header("Content-Disposition: attachment; filename=\"Delivery_Reports.csv\";" );
header("Content-type: application/vnd.ms-excel");
$out = fopen("php://output", 'w');
$flag = false;
// $result = mysql_query("SELECT * FROM senderids ") or die('Query failed!');
//$sel="SELECT number as MobileNumber ,snum as Sender , msg as Subject ,crdate as Date ,status FROM savemsg WHERE userID='".$_SESSION['id']."' ".$str." ORDER BY sn DESC ";
$result = mysql_query("SELECT `count`, `dnd`, `credit`, `sender_id`, `to`, `message`, `status` FROM `reports` WHERE `unq_id` = '$dlr_id'");
while(false !== ($row = mysql_fetch_assoc($result))){
if(!$flag){
$list = array(
"Total"=>"Total",
"DND"=>"DND",
"Credits"=>"Credits",
"From"=>"From",
"To"=>"To",
"Message"=>"Message",
"Status"=>"Status"
);
// display field/column names as first row
fputcsv($out, array_keys($list), ',', '"');
$flag = true;
}
// array_walk($row, 'cleanData');
fputcsv($out, array_values($row), ',', '"');
}
fclose($out);
You can't guarantee, from within a snippet of code, that nothing else will be output. If the code before this snippet is using output buffering, you can discard the HTML using ob_end_clean. If the code after this snippet is causing the problem, you can simply call die to keep it from running at all. However, if the code before this snippet is outputting HTML directly to the browser, or the code after it outputs HTML and absolutely has to run, then you'll have to modify that code in order to solve your problem.
As Tim mentioned, print, echo and outputting to the pseudo-file php://output do exactly the same thing.
You can also use the keyword continue just before you close the file (fclose($f);). This also works lovely.
You can also use exit; after fclose($out); which stopped the output from scraping my html.
I know it's an old question but it gets found in Google so adding this.
If the HTML is being output by the CMS such as WordPress etc. before you try to create the file, it might help to add ob_clean(); and ob_start(); before you output the header.
For example:
function create_csv($records, $columns){
ob_clean();
ob_start();
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="Export.csv"');
$fp = fopen('php://output', 'w+');
// Generate the file content.
fclose($fp);
die();
}