I need csv output with column headers and comma delimited data. The fputcsv function is working right except that it places a "Validation" comment at the top of the output file:
<!-- Validated at 2016-04-17 00:32:00 -->
This line causes the file to fail when updating my data. If I remove the comment, the file works. Does anyone know how to generate fputcsv output without the comment line?
Here is code
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=gmail.csv');
$output = fopen('php://output', 'w');
fputcsv($output, array('Name', 'Given Name', 'Family Name', 'Group Membership', 'E-mail 1 - Value'));
// Connect to host and open db
include('includes/connect.php');
//Set Date range. Determines current renewal year for Select statement
$year = date('Y') - 1;
$group = date('Y')." member";
/* Select specified member data */
$sql = "SELECT firstLast, firstName, lastName, email, status, gmail, payDate
FROM membership, memberDues
WHERE payDate >= '$year-10-01' AND ID = memberID
ORDER BY lastName, firstName";
$result = mysqli_query($dbCnx, $sql);
while ($row = mysqli_fetch_assoc($result)) {
$gmailArray = array( $row['firstLast'], $row['firstName'], $row['lastName'], "$group", $row['email'] );
fputcsv($output, $gmailArray);}
I discovered the problem. My security include (which I hadn't looked at in a few years), inserts that Validation line if user has permission to view the page. I guess it's useful to review old bits of plug&play code every so often to help trouble shoot these types of annoyances.
Related
This question already has answers here:
Why is fputcsv producing duplicate columns?
(2 answers)
Closed 2 years ago.
I'm not understanding the output I get from this query. Each column is being duplicated, so instead of getting the 7 columns requested, I'm getting 14, each next to its duplicate, but with no header. Here is my code:
<?php
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=netID2807.csv');
// create a file pointer connected to the output stream, usually downloads
$output = fopen('php://output', 'w');
// output the column headings
fputcsv($output, array('Callsign', 'First Name', 'Last Name', 'Time In', 'Time Out', 'County', 'State'));
// go get the data
require_once "dbConnectDtls.php"; // Access to MySQL
$sql = "SELECT callsign, Fname, Lname, logdate, timeout, county, state
FROM NetLog
WHERE netID = 2807";
foreach($db_found->query($sql) as $row) {
fputcsv($output, $row);
}
?>
Why are all my columns being duplicated, and how do I fix it?
It looks like your fetch is defaulting to retrieve both associative and numeric-indexed arrays, so it outputs both to the file. You could try specifying that it is only to retrieve either one or the other. I can't see how your data is actually fetched, that must be in your include file.
If you're on mysqli, fetch_array() defaults to MYSQLI_BOTH which will do as your comment suggests. Instead, specify MYSQLI_ASSOC or MYSQLI_NUM when the data is retrieved.
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);
?>
I'm fairly new to PHP and this is my first-ever stackoverflow question:
I want to make it easy for a user to know when data has changed since they last downloaded a CSV file from the application I'm building. The CSV export works and I can determine whether there are any rows whose timestamp is after the timestamp stored in an export log table. My problem is that I cannot figure out how to store the timestamp in the log table. When a user clicks the link to export the file, the code below executes to produce the file. The very last four lines are my attempt to make the log entry. $con is valid and works and my method works in a regular PHP page, but I can't figure out how to make it work in the CSV download page and I don't know of any other way to make the entry when the user clicks to download. I am open to ideas for the best way to do this.
I really appreciate your time -- thanks in advance!
<?php
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=speakers.csv");
header("Pragma: no-cache");
header("Expires: 0");
require_once("../scripts/dbcon.inc.php");
require_once("../scripts/presentersessions.inc.php");
$query = "SELECT DISTINCT sp.person_id, CONCAT(p.person_display_name, ' ', p.person_last_name) person_name, '' session_titles, p.person_bio FROM person p INNER JOIN presenters sp ON p.person_id = sp.person_id ORDER BY p.person_last_name, p.person_display_name";
$result = mysqli_query($con, $query) or die('failed query: '.$query);
$num_rows = mysqli_num_rows($result);
$output = fopen("php://output", "w");
fputcsv($output, array("Item ID (Optional)","Name","Sub-Title (i.e. Location, Table/Booth, or Title/Sponsorship Level)","Description (Optional)","Location/Room"));
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
#echo '"","'.htmlspecialchars($row['person_display_name']).' '.htmlspecialchars($row['person_last_name']).'","'.htmlspecialchars($row['session_title']).'","'.htmlspecialchars($row['person_bio']).'"\n"';
$person_id = $row['person_id'];
$row['person_name'] = $row['person_name'];
$row['session_titles'] = presenter_sessions($conference_id, $person_id);
$row['person_id'] = '';
fputcsv($output, $row);
}
date_default_timezone_set('US/Eastern');
$export_timestamp = date("Y-m-d H:i:s");
$query_insert_log_entry = "INSERT INTO export_log (export_type, export_timestamp, person_id) VALUES ('$export_type', '$export_timestamp', {$_SESSION['valid_accbo_person_id']})";
$result_insert_log_entry = mysqli_query($con, $query_insert_log_entry);
make sure you set this vaiable $export_type and $_SESSION['valid_accbo_person_id'] is accessible on this page.
I think the problem is in this line -
$query_insert_log_entry = "INSERT INTO export_log (export_type, export_timestamp, person_id) VALUES ('$export_type', '$export_timestamp', {$_SESSION['valid_accbo_person_id']})";
remove those single quote from variables like below -
$query_insert_log_entry = "INSERT INTO export_log (export_type, export_timestamp, person_id) VALUES ('{$export_type}', '{$export_timestamp}', '{$_SESSION['valid_accbo_person_id']}')";
I found a similar question but there was no solution due to lack of information.
I have the code below which outputs data from the connected MySQL DB to a formatted CSV file in the following format…
First Name:Surname:GCNumber:Dept:Start Date:Introduction:Theory:Fire Safety:Governance:
John:Smith:123456:HR:03/08/2013:Pass:Pass:Fail:Pass:
Jane:Watson:123445:IT:03/08/2013:Pass:Fail:Pass:Pass:
Mark:Byron:123442:IT:03/08/2013:Fail:Fail:Not Done:Not Done:
: = used just to show each column
It just outputs all the rows and columns that are in the database in the same structure, and renaming the column headers to be more friendly when imported into excel.
What I need is to change to format of this output to the following…
First Name:Surname:GCNumber:Dept:Email:Start Date:Module:Status:
John:Smith:123456:HR:03/08/2013:Introduction:Pass:
John:Smith:123456:HR:03/08/2013:Theory:Pass:
John:Smith:123456:HR:03/08/2013:Fire Safety:Fail:
John:Smith:123456:HR:03/08/2013:Governance:Pass:
Jane:Watson:123445:IT:03/08/2013:Introduction:Pass:
Jane:Watson:123445:IT:03/08/2013:Theory:Fail:
Jane:Watson:123445:IT:03/08/2013:Fire Safety:Pass:
Jane:Watson:123445:IT:03/08/2013:Governance:Pass:
Mark:Byron:123442:IT:03/08/2013:Introduction:Fail:
Mark:Byron:123442:IT:03/08/2013:Theory:Fail:
Mark:Byron:123442:IT:03/08/2013:Fire Safety:Not Done:
Mark:Byron:123442:IT:03/08/2013:Governance:Not Done:
: = used just to show each column
So Rather than one entry for each person, and results of each module they have done I need it to be a separate entry for each module that person has done.
In total there are more fields to this DB and 35 modules but I've cut this down for illustration purposes here.
Being a bit of a newbie with PHP etc I'm struggling to get my head around how to do this.
Is this possible or would it be easier to try and change the structure of the DB to be in the desired format?
Any help or pointers in the right direction would be great.
Tony
<?php
function exportMysqlToCsv($table,$filename = 'db-snapshot.csv')
{
$sql_query = "select fldFirstname as 'First Name',
fldSurname as 'Surname',
fldGMCNumber as 'GCNumber',
fldDestDept as 'Dept',
fldStartDate as 'Start Date',
fldModule1 as 'Introduction',
fldModule2 as 'Theory',
fldModule3 as 'Fire Safety',
fldModule4 as 'Governance'
from $table";
// Gets the data from the database
$result = mysql_query($sql_query);
$f = fopen('php://temp', 'wt');
$first = true;
while ($row = mysql_fetch_assoc($result)) {
if ($first) {
fputcsv($f, array_keys($row));
$first = false;
}
fputcsv($f, $row);
} // end while
$size = ftell($f);
rewind($f);
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Length: $size");
// Output to browser with appropriate mime type, you choose ;)
header("Content-type: text/x-csv");
// header("Content-type: text/csv");
// header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=$filename");
fpassthru($f);
exit;
}
?>
You can use UNIONS for this:
SELECT fldFirstname as 'First Name', fldSurname as 'Surname',
fldGMCNumber as 'GCNumber', fldDestDept as 'Dept',
fldStartDate as 'Start Date', fldEndDate as 'End Date',
'Introduction' as 'Module', fldModule1 as 'Status' FROM records
UNION
SELECT fldFirstname,fldSurname,fldGMCNumber,fldDestDept,fldStartDate,fldEndDate,
'Theory',fldModule2 FROM records
UNION
SELECT fldFirstname,fldSurname,fldGMCNumber,fldDestDept,fldStartDate,fldEndDate,
'Fire Safety',fldModule3 FROM records
UNION
SELECT fldFirstname,fldSurname,fldGMCNumber,fldDestDept,fldStartDate,fldEndDate,
'Governance',fldModule4 FROM records
ORDER BY Surname, `First Name`, Module;
SQL Fiddle example
I would use a pivot on my query to the DB. Check under
If I have a MySQL table looking something like this
So you would basically create a table with rows describing your module:
Module
1 | Introduction
2 | Theory
3 | Fire Safety
4 | Governance
Then join it to table above and use a "Case" syntax to achieve your request.
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);
}