Duplication of data in CSV export in PHP - php

I am doing a sql query which gets someones surname, forename, student ID and their Grade. However when I export this data to a CSV it duplicates each of these fields. I have checked the SQL query separately and can confirm it is not duplicating the data
$result = $stmt->fetchAll();
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=grades.csv');
$output = fopen('php://output', 'w');
fputcsv($output, ['Surname', 'Forename', 'Student ID', 'Actual Mark']);
foreach ($result as $row){
fputcsv($output, $row);
}
Here is an example output I get:

Related

FPUTCSV put an array with for loop

Hey what I am trying is populate csv with the values from my array. How can I do that ?
$sql = "SELECT accountNumber, Name,studentManager,contract,
nationality,university,major,Course,specialNotes,
Phone,email,birthday,uniAddress
FROM " . $dbname . "
WHERE id ='$id'";
$query2 = mysqli_query($conn, $sql);
$thisArray = mysqli_fetch_all($query2, MYSQLI_NUM);
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=userData.csv");
$fp = fopen('php://output', 'w');
foreach ($thisArray[0] as $row3) {
fputcsv($fp,$row3);
}
fclose($fp);
When you retrieve the data into $thisArray, it creates an array where each row is an array of all the field values. So when you use $thisArray[0] in the following line...
foreach ($thisArray[0] as $row3) {
This just picks up the first row of the data you've retrieved. $row3 will be each individual field and fputcsv is expecting it to be an array.
Just change that line to
foreach ($thisArray as $row3) {
and $row3 will be each row of data.
(Just so there is an answer for this)

CSV Export: Multiple Database Rows to Single Row

Hi,
The problem: I Have an Export from a Database, however it needs to extract data from two tables. I Achieve this with an inner join.
artikel is the table with the basic information. It contains the id, article number, name, type and package form.
article_content is the table which contains the text which is part of the article, however, there are multiple languages. Every Article has a row for each language.
The Export Code
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=artikeldatenbank-' . date("dmyhi") . '.csv');
$output = fopen('php://output', 'w');
$stmt = $db->prepare('SELECT artikel.id, artikel.artikel_nummer, artikel.artikel_name, artikel.artikel_packung, artikel.artikel_cat, article_content.article_text, article_content.article_recuse, article_content.article_spec FROM artikel INNER JOIN article_content ON article_content.article_id = artikel.artikel_nummer');
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc())
fputcsv($output, $row);
What I want to Achieve
I need every row from the article_content table by it's article in a single line, instead of multiple lines. Sorry for the links, but imgur doesn't let me upload these. (Don't know why)
What happens now (image): http://prntscr.com/ek86bn
What I Want (edited image): http://prntscr.com/ek87ct
What is the best way to achieve this? Is this possible on the way I do it now?
Skip the VIEW solution, Solve it by code, my suggestion is
$result = $stmt->get_result();
$artikeID = '';
$newRow = [];
while ($row = $result->fetch_assoc())
{
if($artikeID != $row['id'])
{
if(!empty($newRow))
{
fputcsv($output, $newRow);
$newRow = [];
}
$artikeID = $row['id'];
$newRow = $row;
}
else
{
$newRow['title-'.$row['id']] = $row['artikel_name'];
$newRow['content-'.$row['id']] = $row['article_text'];
}
}

Trying to export MySQL query as CSV using PHP

I'm getting a warning
Warning: mysql_fetch_assoc() expects parameter 1 to be resource, array
given
when trying to export a MySQL query result as CSV using PHP code like this:
public static function exportLocationCSV($id){
$sql =<<<EOF
SELECT col1, col2, col3
FROM table1
JOIN table2 ON table1.col0=table2.col0
WHERE table1.col0 = $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('Column 1', 'Column 2', 'Column 3'));
$query_export= self::$db_connection->query($sql);
$rows = array();
while($r = mysqli_fetch_assoc($query_export)){
$rows[] = $r;
}
// loop over the rows, outputting them
while ($row = mysql_fetch_assoc($rows)) fputcsv($output, $row);
}
You're mixing mysql_* and mysqli_* API's. mysql_fetch_assoc() will not work with the mysqli_ API. Your second while loop is the one using the wrong function call.
This line:
// loop over the rows, outputting them
while ($row = mysql_fetch_assoc($rows)) fputcsv($output, $row);
should be change to the correct function call:
// loop over the rows, outputting them
foreach($rows AS $row) fputcsv($output, $row);
mysql_fetch_assoc used to fetch a result row as an associative array here is more about mysql_fetch_assoc
what you are trying to do is to pass $rows which is array while mysql_fetch_assoc expecting you to pass mysql_query

Outputting Column titles in CSV Export

I have this query that exports to a csv file. It works fine the only thing i can't figure out is i need to export the column titles as well, and have them display as Full Name, UserName, Flag and Reason. Below is the code and it exports all the rows fine but I'm not sure how to export the column titles above the respected rows.
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=blackflag_bidders.csv");
header("Pragma: no-cache");
header("Expires: 0");
//SQL Query for Data
$sql = "SELECT ui.first_name, ui.last_name, u.username,
if(u.flag=1,'BLK', if(u.flag=2,'NAA','')) flag,
if(u.flag!=0, IFNULL(ui.note,''),'') reason
FROM user u
LEFT JOIN user_info ui ON ui.user_id=u.id
WHERE u.flag!=0;";
//Prepare Query, Bind Parameters, Excute Query
$STH = $sam_db->prepare($sql);
$STH->execute();
//Export to .CSV
$fp = fopen('php://output', 'w');
//fputcsv($fp);
while ($row = $STH->fetch(PDO::FETCH_NUM)) fputcsv($fp,$row);
fclose($fp);
One way would be to fetch the first result by associative, those associative indices are columns anyway. Apply array_keys to get those, then first add the headers, then the first fetched row, then loop the rest.
// first set
$first_row = $STH->fetch(PDO::FETCH_ASSOC);
$headers = array_keys($first_row);
// $headers = array_map('ucfirst', $headers); // optional, capitalize first letter of headers
fputcsv($fp, $headers); // put the headers
fputcsv($fp, array_values($first_row)); // put the first row
while ($row = $STH->fetch(PDO::FETCH_NUM)) {
fputcsv($fp,$row); // push the rest
}
fclose($fp);
The answer to this will depend upon whether you already know the column names or not. It seems like you do (e.g. you are already calling 'Select ui.firstname...')
If you do not, you can get the names by looking at this thread:
What is the Select statement to return the column names in a table
Once you have the names, you simply need to create a single row with the names and add them to file by modifying your code as:
//Export to .CSV
$columnNamesRow = "FirstName, LastName, UserName";
$fp = fopen('php://output', 'w');
fputcsv($fp, $columnNamesRow);
//fputcsv($fp);
while ($row = $STH->fetch(PDO::FETCH_NUM)) fputcsv($fp,$row);
fclose($fp);
You can get a column in CSV by simply displaying your results in Tabular form here in the page using <table> tag of HTML.
$result = "<table>";
while ($row = $STH->fetch(PDO::FETCH_NUM)){
$result .= "<tr><td>$row1</td><td>$row2</td><td>$row3</td></tr>";
}
$result .= "</table>";
fputcsv($fp, $result);
By $row1, $row2, I mean the values you get in your resultset

creating a CSV file from MySQL Table data in PHP

I have this code in 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=calls.csv');
// create a file pointer connected to the output stream
$output = fopen($_SERVER["DOCUMENT_ROOT"].'/file_dump/price_tariffs/calls.csv', 'w');
// output the column headings
fputcsv($output, array('Column 1', 'Column 2'));
// loop over the rows, outputting them
$sql="SELECT * from call_costs where sequence < '50' ";
$rs=mysql_query($sql,$conn);
while($result = mysql_fetch_array($rs)) {
fputcsv($output, $result["number"]);
}
its creating the file name calls.csv in the price_tariffs directory but its only adding the column 1 and column 2 and not the data from the while loop
i have check the loop and echoed data inside the loop which displays fine
fputcsv takes the second parameter as an array(), "and you already used fputcsv outside of the loop passing the second param as an array"[*] with two values inside.
Try to do the same inside your loop:
fputcsv($output, array($result["number"], $result["somethingelse"]));
[*]: edited, added enquoted sentence after clarifying in the comments below.
Select only the columns that you want:
$sql = "SELECT column1, column2 FROM call_costs WHERE sequence < '50'";
Then use mysql_fetch_assoc() to fetch each row as an associative array, and output that:
$rs=mysql_query($sql,$conn);
while($row = mysql_fetch_assoc($rs)) {
fputcsv($output, $row);
}
fputcsv()'s second argument is supposed to be an array of the values that should be put into fields in the CSV file.
since you're sending the data to the client directly, you should echo it instead of saving it to a file :) Open the php://output instead:
Try this (from powtacs answer:
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=calls.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'));
// loop over the rows, outputting them
$sql="SELECT * from call_costs where sequence < '50' ";
$rs=mysql_query($sql,$conn);
while($result = mysql_fetch_assoc($rs)) {
fputcsv($output, $result);
}
Also please note that mysql is depreciated, and you should use mysqli or PDO instead
Checkout the mysql_fetch_array in the php manual, so, we can say:
...
while($result = mysql_fetch_array($rs,MYSQL_NUM)) {
fputcsv($output, $result);
}
Just add the second optional parameter MYSQL_NUM to return numerical array and supply all of it as a parameter in fputcsv. By this way you will get all the raw's fields data in your csv file.

Categories