Trying to generate a report form data base to be exported as an excel file, but I keep getting 0 results when there is data in the database. Can anyone take a look at the code and let me know what I have wrong. the code needs to go into a server that is running php 5.4+ from 4+
<?php
//set date
$date = date("m/d");
$course_report = $_POST['course_report'];
$course_info = explode('~',$course_report);
$course_info[0]; // course_id
$course_info[1]; // course_date
$select = "SELECT DISTINCT * FROM registrants WHERE (paid='Y' AND course_id = '$course_info[0]' AND course_date = '$course_info[1]')";
$result = mysqli_query($dbc, $select);
// first get the header row
while($row = mysqli_fetch_assoc($result)) {
$course = $row['course'];
$coursedate = $row['course_date'];
$export = mysql_query($select);
$fields = mysql_num_fields($export);
}
// Get header
$fields = isset($_POST['fields']);
for ($i = 0; $i < $fields; $i++) {
$header .= mysqli_field_name($export, $i) . "\t";
}
// Then get all the rows of data
$export = isset($_POST['export']);
while($row = mysqli_fetch_row($result)) {
$line = '';
foreach($row as $value) {
if ((!isset($value)) OR ($value == "")) {
$value = "\t";
} else {
$value = str_replace('"', '""', $value);
$value = '"' . $value . '"' . "\t";
}
$line .= $value;
}
$data .= trim($line)."\n";
}
$data = isset($_POST['data']);
$data = str_replace("\r","",$data);
// Check for blank data set
if ($data == "") {
$data = "\n(0) Records Found!\n";
}
// end building the data
$header = isset($_POST['header']);
$course = isset($_POST['course']);
$file_name = $course . "_downloaded_" . $date;
header("Content-type: application/x-msdownload");
//header("Content-Disposition: attachment; filename=Registrar_101.txt");
header("Content-Disposition: attachment; filename=$file_name.xls");
header("Pragma: no-cache");
header("Expires: 0");
print "$header\n$data";
// }
?>
This says it's only supposed to get one row, but it's actually going to get all rows.
// first get the header row
while($row = mysqli_fetch_assoc($result)) {
$course = $row['course'];
$coursedate = $row['course_date'];
$export = mysql_query($select);
$fields = mysql_num_fields($export);
}
Then for each row you're inexplicably re-exectuing the query with mysql_query()
and at this point I've stopped looking because you really need to clean up the logic here if the rest of the script is going to make any sense at all.
I'm not sure what you think is happening under "first get the header row". The query is retrieving records from the Registrants table. Where do you think a "header row" is coming from? Are you thinking that you are going to get a row back from the query with the column headers, i.e. the names of the fields? If so, that's not how it works.
Then within this loop you re-execute the query for every record. Why? What does that accomplish? Then you get the count of the number of fields from this inner query and put it in $fields. But you never use this value. After the loop, you promptly overwrite it.
Do you understand that isset() returns true or false? You seem to think it returns a string.
$_POST gets a value that was submitted on a form from a web page. You seem to be thinking that it's going to give you values from your query or something.
I'm not sure exactly what you're trying to accomplish, but I think the core of your program should look something like this:
<?php
//set date
$date = date("m/d");
$course_id = $_POST['course'];
$course_date = $_POST['course_date'];
// You really should use mysqli_real_escape_string to escape input strings,
// but let's skip that point for now
// Also, it's generally bad form to use "select *", as then you have no idea what
// fields you will get back. Better to list exactly what you want.
$select = "SELECT DISTINCT * FROM registrants WHERE (paid='Y' AND course_id = '$course_id' AND course_date = '$course_date')";
// This assume the db is already open as $dbc
$result = mysqli_query($dbc, $select);
// build header row
$header = '';
$field_count = mysqli_num_field($result);
for ($i = 0; $i < $field_count; $i++) {
$finfo = mysqli_fetch_field_direct($result,$i);
$name = $finfo->name;
$header .= $name . "\t";
// I'm not familiar with a mysqli_field_name function and couldn't find it in the docs.
// Whatever.
}
$data = $header . "\n";
// Then get all the rows of data
while($row = mysqli_fetch_row($result)) {
$line = '';
foreach($row as $value) {
if (!isset($value) OR $value == "") {
$value = "\t";
} else {
$value = str_replace('"', '""', $value);
$value = '"' . $value . '"' . "\t";
$line .= $value;
}
$data .= trim($line)."\n";
}
... and then whatever you need to do with this thing ...
Related
I have a website that I created for reports. There are basically 3 reports. I have a button on each page that calls another PHP page that will download the results of the query that fills the page into a CSV file. This works fine on one page, but on the other two it gives me an error when trying to open. It says:
The file format and extension of 'FileName' don't match. the file could be corrupted or unsafe. Unless you trust its source, don't open it. Do you want to open it anyway?
I click yes, then get this:
Excel has detected that 'FileName' is a SYLK file, but cannot load it. Either the file has errors or it is not a SYLK file format. Click OK to try to open the file in a different format.
I click OK and it opens fine.
Where as on the other page it just opens.
Here's most of the ExportToExcel.php
switch ($_POST['ExportToExcel'])
{
case "QDef":
$tsql = "select Id,QSrc,QName,QDef,isActive,RunReport,FilePath from pmdb.v_QDefs order by Id";
$hsql = "select Headings from TableHeadings where TableName = 'v_QDefs' and Headings != 'Edit' order by ID";
break;
case "TableUpdates":
$tsql = "select ID, TableName, UpdateDate from pmdb.TableUpdates order by UpdateDate";
$hsql = "select Headings from TableHeadings where TableName = 'TableUpdates' and Headings != 'Edit' order by ID";
break;
}
$filename = $_POST['ExportToExcel'];
header("Content-Type: application/x-csv");
header("Content-Disposition: attachment; filename=$filename.csv");
//define separators (defines columns in excel)
$sep = ",";
$br = "\r\n"; //line break
$getHeadings = $conn->query($hsql);
$rHeadings = $getHeadings->fetchALL(PDO::FETCH_ASSOC);
$headings = array();
$NumHeadings = count($rHeadings);
for ($i = 0;$i < $NumHeadings; $i++)
{
$headings[] = $rHeadings[$i]["Headings"];
}
//start of printing column names as names of SQL fields
foreach($headings as $Heading => $value)
{
echo "$value" . $sep;
}
//end of printing column names
echo $br; //separate the headers and the data
foreach($conn->query($tsql) as $row)
{
for ($i = 0;$i < $NumHeadings;$i++)
{
$CommentPos = strpos($rHeadings[$i]["Headings"],"comment");
$NewLines = array("\r\n","\n\r","\n","\r");
$UseValue = str_replace($NewLines, " ",$row[$i]);
$UseValue = str_replace('"', "'",$row[$i]);
$pos = strpos($UseValue,",");
if ($CommentPos === FALSE || $pos === FALSE || isset($UseValue))
{
echo '"' . $UseValue . '"' . $sep;
}
else
{
echo $UseValue . $sep . "Not quoted";
}
}
echo $br;
}
I have a include at the top that has the connection string for connecting to my MSSQL DB, which does work, or there'd be nothing displayed on the page to begin with.
I just con't figure out why the page doesn't work the same way for all reports when they are all calling the page the same way.
EDIT again
I tried several ideas from below and now I have this:
$filename = $_POST['ExportToExcel'] . '.csv';
$Opened = fopen($filename,'w');
header("Content-Type: text/csv; charset=utf-8'");
header("Content-Disposition: attachment; filename=$filename");
fputcsv($Opened,$headings);
foreach($conn->query($tsql) as $row)
{
fputcsv($Opened,$row);
}
fclose($Opened);
Which still gives me a blank spreadsheet. So obviously I'm still doing something wrong?
Nevermind, I updated the Headings for all the tables that I am trying to export so that the first column is no longer ID, but is instead Id. Since it's no longer all caps it is working fine without the fputcsv since that isn't doing anything for me anyhow.
$filename = $_POST['ExportToExcel'] . '.csv';
header("Content-Type: text/csv; charset=utf-8'");
header("Content-Disposition: attachment; filename=$filename");
//define separators (defines columns in excel)
$sep = ",";
$br = "\r\n"; //line break
$getHeadings = $conn->query($hsql);
$rHeadings = $getHeadings->fetchALL(PDO::FETCH_ASSOC);
$headings = array();
$NumHeadings = count($rHeadings);
for ($i = 0;$i < $NumHeadings; $i++)
{
$headings[] = $rHeadings[$i]["Headings"];
}
//start of printing column names as names of SQL fields
foreach($headings as $Heading => $value)
{
echo "$value" . $sep;
}
foreach($conn->query($tsql) as $row)
{
for ($i = 0;$i < $NumHeadings;$i++)
{
$CommentPos = strpos($rHeadings[$i]["Headings"],"comment");
$NewLines = array("\r\n","\n\r","\n","\r");
$UseValue = str_replace($NewLines, " ",$row[$i]);
$UseValue = str_replace('"', "'",$row[$i]);
$pos = strpos($UseValue,",");
if ($CommentPos === FALSE || $pos === FALSE || isset($UseValue))
{
echo '"' . $UseValue . '"' . $sep;
}
else
{
echo $UseValue . $sep . "Not quoted";
}
}
echo $br;
}
Pls, let someone help me with this code, When I export, it export the file but start with row2, the first row is excluded.it reads like , header, then row2,3,4 till the end of the row.
<?php
require_once("/includes/session.php");
require_once("/includes/db_connection.php");
require_once("/includes/functions.php");
// Table Name that you want
// to export in csv
$ShowTable = "staff_tab";
$today=date("dmY");
$FileName = "StaffRecord".$today.". csv";
$file = fopen($FileName,"w");
$sql = mysqli_query($connection,("SELECT * FROM $ShowTable LIMIT 500"));
$row = mysqli_fetch_assoc($sql);
// Save headings alon
$HeadingsArray=array();
foreach($row as $name => $value){
$HeadingsArray[]=$name;
}
fputcsv($file,$HeadingsArray);
// Save all records without headings
while($row = mysqli_fetch_assoc($sql)){
$valuesArray=array();
foreach($row as $name => $value){
$valuesArray[]=$value;
}
fputcsv($file,$valuesArray);
}
fclose($file);
header("Location: $FileName");
echo "Complete Record saves as CSV in file: <b style=\"color:red;\">$FileName</b>";
?>
Your call to $row = mysqli_fetch_assoc($sql); is pushing the internal pointer forward to row 2. Use mysqli_data_seek($sql, 0); to push it back to the start. http://php.net/manual/en/function.mysql-data-seek.php
...
$sql = mysqli_query($connection,("SELECT * FROM $ShowTable LIMIT 500"));
$row = mysqli_fetch_assoc($sql);
mysqli_data_seek($sql, 0); // return pointer to first row
// Save headings alon
$HeadingsArray=array();
...
maybe this could help as this will include all rows and set headers from the db headers. This would also force download the file without leaving the page.
$export = mysqli_query ($query) or die ( "Sql error : " . mysqli_error( ) );
// extract the field names for header
$fields = mysqli_num_fields ( $export );
for ( $i = 0; $i < $fields; $i++ )
{
$headers = mysqli_fetch_field($export);
$header .= $headers->name. "\t";
}
// export data
while( $row = mysqli_fetch_row( $export ) )
{
$line = '';
foreach( $row as $value )
{
if ( ( !isset( $value ) ) || ( $value == "" ) )
{
$value = "\t";
}
else
{
$value = str_replace( '"' , '""' , $value );
$value = '"' . $value . '"' . "\t";
}
$line .= $value;
}
$data .= trim( $line ) . "\n";
}
$data = str_replace( "\r" , "" , $data );
if ( $data == "" )
{
$data = "\nNo Record(s) Found!\n";
}
// allow exported file to download forcefully
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=Something.xls");
header("Pragma: no-cache");
header("Expires: 0");
print "$header\n$data";
I'm trying to get the following output from mysql for Google Line Chart API:
[["product","diameter","width"],["Product 1","2","4"],["Product 2","4","8"]]
I have set up several input checkboxes to send field names (e.g width,diameter) to the database via $_POST["info"] and retrieve the values from those fields. Here's the part that generates the data from mysql:
$result = $users->fetchAll();
$comma = "";
$data="";
$data[0] = array_merge(array(product),$info);
$i = 1;
foreach ($result as $r)
{
foreach($_POST["info"] as $p)
{
$d .= $comma.$r[$p]; // trying to get "$r["width"],$r["diameter"]"
}
$comma = ",";
$data[$i] = array($r["name"], $d);
$i++;
}
echo json_encode($data);
My desired output should be like this:
[["product","diameter","width"],["Product 1","2","4"],["Product 2","4","8"]]
But that code is generating duplicated results like this
[["product","diameter","width"],["Product 1","24"],["Product 2","24,4,8"]]
I guess I shouldn't be using the nested foreach to loop over $_POST. Can anyone tell me how to fix that?
Full PHP Code:
$info = $_POST["info"]; // It contains an array with values like width,diameter,thickness etc...
$comma = "";
foreach($info as $in)
{
$field .= "".$comma."b.".$in."";
$comma = ",";
}
$sql = "
SELECT {$field},a.user_id,a.name
FROM `product_detail` a INNER JOIN
`attr` b ON a.model = b.model
WHERE a.user_id = ?
GROUP BY a.model
";
$users = $dbh->prepare($sql);
$users->bindValue(1, $_SESSION["user_id"]);
$users->execute();
$result = $users->fetchAll();
$comma = "";
$data="";
$i = 1;
$data[0] = array_merge(array(product),$info);
foreach ($result as $r)
{
foreach($_POST["info"] as $p)
{
$d .= $comma.$r[$p];
}
$comma = ",";
$data[$i] = array($r["name"], $d);
$i++;
}
echo json_encode($data);
$_POST["info"] Content:
Array
(
[0] => diameter
[1] => width
)
try it like this:
$result = $users->fetchAll();
$data="";
$data[0] = array_merge(array(product),$info);
$i = 1;
foreach ($result as $r)
{
$d[]=$r["name"];
foreach($_POST["info"] as $p)
{
$d[]= $r[$p];
}
$data[$i] = $d;
$d=array(); //set $d to empty not to get duplicate results
$i++;
}
echo json_encode($data);
The end result you are looking for, is valid JSON. You should not try to manually generate that.
Instead you should make an array of arrays in php and use json_encode($array) to get the result you are looking for.
Also note that by injecting your POST variables directly in your query, you are vulnerable to sql injection. When accepting fields, you should check them against a white-list of allowed values.
Try the below solution:
$result = $users->fetchAll();
$data="";
$data[0] = array_merge(array(product),$info);
$i = 1;
foreach ($result as $r)
{
$d = array();
foreach($_POST["info"] as $p)
{
$d[] = $r[$p]; // trying to get "$r["width"],$r["diameter"]"
}
$data[$i] = array($r["name"]) +$d;
$i++;
}
echo json_encode($data);
I'm trying to export my MySQL query to MsExcel using PHP script, one execution of script I'm getting the following error:
Warning: mysql_field_name() expects parameter 1 to be resource, object given php file on line 161
The data is exporting, but headings (field names of the mysql of the table) are not exporting. Also, I expected to have every field on a separate cells, but its saved each row in one cell.
Here is the PHP Script:
$data = '';
$header = '';
$result = mysqli_query($GLOBALS['mysqli'], $export_sql) or die ("<b>Couldn't execute SQL query:</b> " . mysqli_error($GLOBALS['mysqli']));
$fields = mysqli_num_fields($result);
for ($i=0; $i < $fields; $i++) {
$header .= mysql_field_name($result, $i). "\t"; // line 161
}
while ($row = mysqli_fetch_row($result)) {
$line = '';
foreach ($row as $value) {
if ((!isset ($value)) || ($value == "")) {
$value = "\t";
} else {
$value = str_replace('"', '""', $value);
$value = '"'.$value.'"'."\t";
}
$line .= $value;
}
$data .= trim($line). "\n";
}
$data = str_replace("\r", "", $data);
if ($data == "") {
$data = "\n(0) Records Found!\n";
}
header ("Content-type: application/octet-stream");
header ("Content-Disposition: attachment; filename=Export.xls");
header ("Pragma: no-cache");
header ("Expires: 0");
print "$header\n$data";
Any suggestions to resolve the problem?
I am trying to export the data got from my database.
The problem is that the data comes with html codes.
I just want to export the data without html codes.
Note: My database doesn't have any html code.
$exported_db_datas (global array variable) is created like this:
while($row = mysql_fetch_array($resultset,MYSQL_ASSOC))
{
$resultsarray[$rowcount] = $row;
$exported_db_datas[$rowcount] = $row;
/*foreach($resultsarray[$rowcount] as $column)
{
$resultsarray2[$rowcount][] = $column;
}*/
$rowcount++;
}
Export codes :
$export_file = "export_phisto";
if ($format == "CSV")
{
$file = $export_file.".csv";
$separator = ",";
}
elseif ($format == "TAB")
{
$file = $export_file.".tab";
$separator = "\t";
}
elseif ($format == "TXT")
{
$file = $export_file.".txt";
$separator = "\t";
}
else// XLS
{
$file = $export_file.".xls";
$separator = "\t";
}
header("Content-Disposition: attachment; filename=\"$file\"");
header("Content-Type: text/plain");
$flag = false;
foreach($exported_db_datas as $row)
{
if(!$flag)
{
// display field/column names as first row
echo implode($seperator, array_keys($row)) . "\r\n";
$flag = true;
}
echo implode($seperator, array_values($row)) . "\r\n";
}
Note: Even if I don't use print $data, exported data has html codes of the web site without data.
How can I just export the data I get from database?
Example exported data is was here.
Use strip_tags
$exported_db_datas[$rowcount] = strip_tags($row);
just use strip_tags() in this line $exported_db_datas[$rowcount] = $row; like so: $exported_db_datas[$rowcount] = strip_tags($row);
PS: don't use the mysql_* extension, it was deprecated, see the red warning box here