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.
Related
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 have written the following code to extract a column from a Mysql Table to a CSV file.
When I ran the script it throws the following error.
Warning: fputcsv() expects parameter 2 to be array, boolean given in
on this line fputcsv($data, $row); Is it problem with the PDO?
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=".date('m.d.Y').'.csv');
header("Pragma: no-cache");
header("Expires: 0");
define('STOREDIR','upload/csv');
define('ABPATH', dirname(__file__) . '/'); //do not modify this
$stmt = $con->prepare("SELECT fname from abcgroup where group_id='2'");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_BOUND);
$stmt->bindColumn('fname', $fname);
$filename = ABPATH.STOREDIR.date('m.d.Y').'.csv';
$data = fopen($filename, 'w');
while ($row = $stmt->fetch()) {
fputcsv($data, $row);
}
fclose($data);
When you use PDO::FETCH_BOUND, $stmt->fetch() returns either true or false, not the row of results. The results are stored in the variables bound with $stmt->bindColumn. So you need to use:
fputcsv($data, array($fname));
But you could just use PDO::FETCH_ASSOC or PDO::FETCH_NUM so that $row will contain the array of columns. Then you can use it in fputcsv() as you have.
Because you're using PDO::FETCH_BOUND, your call to fetch() won't return a data row. It will only return true if success and bind the column content to your variables. From the manual:
PDO::FETCH_BOUND: returns TRUE and assigns the values of the columns in your result set to the PHP variables to which they were bound with the PDOStatement::bindColumn() method
If you want to put the contents of fname in your CSV, use this instead:
fputcsv($data, [$fname]);
Or use a different fetch style to have the row array, such as PDO::FETCH_ASSOC.
$stmt = $con->prepare("SELECT fname from abcgroup where group_id='2'");
Here is the problem
Check the above line ( table name and other details of your table and database like column name and row etc... )
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.
I've created a small input form for a custom sql query using php. I've been able to output the results to a csv form, however I'm having some trouble including the headers in the output file.
I've had no trouble creating an array of the header rows, but I'd like to be able to create the headers out of the query itself.
This is what I've used:
$output = fopen('php://output', 'w');
//get query data
$qs = $_GET['custom'];
$rs = mysqli_query($dbc, $qs)
or die ('Error querying database');
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=query.csv');
$csv = fopen('php://output', 'w');
while ($row = mysqli_fetch_assoc($rs)) {
fputcsv($csv, $row);
}
fclose($csv);
What I want is a way of inputting the rows from the select before the content of the query (which comes through fine).
I know this will work for set headers if I put it in before the first fputcsv line:
fputcsv($csv, array('col1', 'col2', 'col3', [etc...] ));
but it is only because I define the fields in the array.
What I'm looking for is way to identify the columns in the query and use them as column headers.
I've been attempting to do something with a query that would just get the column names, and then feed that as an array but I can't seem to get it to work. Something like this:
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'database_name'
and column_name in ($query)
where the $query variable is similar to the $qs query above, but alas no luck. Does anyone know how to do this? Thanks in advance.
fputcsv($csv, array_keys($row)); at the beginning?
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);
}