I am trying to export to an xlsx file from a MSSQL query in PHP. I don't have access to the servers that my website is hosted on so i can't use anything that isn't already built into PHP. I'm using PHP 5.4. So far I've created a <a></a> that references a php page that should pull data from my MSSQL DB. Instead it gives me a blank file, in xls format. When I open it it throws an error about not having a stylesheet.css file in the downloads folder then opens a blank xls workbook. Here's my ExportToExcel.php file:
$tsql = "select ID, TableName, UpdateDate from pmdb.TableUpdates order by UpdateDate";
//echo $tsql . "<br>";
$getqueries = $conn->query($tsql);
//echo "<BR>";
//var_dump($getqueries);
$result = $getqueries->fetchALL(PDO::FETCH_ASSOC);
$filename = "TableUpdates";
//var_dump($tsql);
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header("Content-Disposition: attachment; filename=$filename.xls");
/*******Start of Formatting for Excel*******/
//define separators (defines columns in excel & tabs in word)
$sep = "\t"; //tabbed character
$br = "\r\n"; //line break
//start of printing column names as names of SQL fields
//$max = sqlsrv_num_fields($result);
/* for ($i = 0; $i < $max; $i++) {
echo sqlsrv_field_metadata($result,$i) . "\t";
}
print("\n"); */
foreach( sqlsrv_field_metadata( $result ) as $fieldMetadata ) {
foreach( $fieldMetadata as $name => $value) {
echo "$value" . $sep;
}
}
echo $br;
//end of printing column names
//start while loop to get data
while($row = sqlsrv_fetch($result))
{
$schema_insert = "";
for($j=0; $j<sqlsrv_num_fields($result);$j++)
{
if(!isset($row[$j]))
$schema_insert .= "NULL".$sep;
elseif ($row[$j] != "")
$schema_insert .= "$row[$j]".$sep;
else
$schema_insert .= "".$sep;
}
$schema_insert = str_replace($sep."$", "", $schema_insert);
$schema_insert = preg_replace("/\r\n|\n\r|\n|\r/", " ", $schema_insert);
$schema_insert .= "\t";
print(trim($schema_insert));
print "\n";
}
I got most of this from other questions, but none of them had an answer either.
EDIT
I have gotten a little further. I can now print the data to excel, though it still throws the errors
The file format and extension of . . . don't match . . .
and
Problems During Load: Missing file: C:\Users\username\Downloads\StyleSheet.css
,but everything prints in one column. It is comma separated, but all values are in the same column. Here's the new portion of the code:
//define separators (defines columns in excel & tabs in word)
$sep = ","; //tabbed character
$br = "<br>"; //line break
$hsql = "select Headings from TableHeadings where TableName = 'TableUpdates' order by ID";
$getHeadings = $conn->query($hsql);
$rHeadings = $getHeadings->fetchALL(PDO::FETCH_ASSOC);
$headings = array($rHeadings[0]["Headings"],$rHeadings[1]["Headings"],$rHeadings[2]["Headings"]);
//start of printing column names as names of SQL fields
foreach($headings as $Heading => $value)
{
echo "$value" . $sep;
}
echo $br;
for ($i = 0;$i < 3;$i++)
{
for($l = 0;$l < 3;$l++)
{
if ($l == 0)
{
echo $result[$i]["ID"] . $sep;
}
elseif ($l == 1)
{
echo $result[$i]["TableName"] . $sep;
}
else
{
echo $result[$i]["UpdateDate"];
}
}
echo $br;
}
How can I get this to echo each value and then move to the next cell? It does have commas, but looks like this:
ID,TableName,UpdateDate,
1,pmdb.MaterialTracking,2016-07-08 13:45:05.963
2,pmdb.OSP_OPR_Report,2016-07-08 13:45:45.883
3,pmdb.COEI_OPR_Report,2016-07-08 13:45:47.920
I have fixed the header so that Excel knows that it's a csv file that it's opening. I no longer get either error.
header("Content-Type: application/x-csv");
header("Content-Disposition: attachment; filename=$filename.csv");
I still don't have any other libraries, so there is not going to be any formatting, just a csv file.
Related
I am using PHP with SQLSRV in an attempt to export a table to Excel. I used this method with MySQLi with no problem.
Regardless, here is the code I am using to export to Excel:
<?php
include("../include/database.php");
global $ts;
$ts = date('mdY-His');
session_start();
$sql = "SELECT
[BOL_DATE]
,[BOOKING_NUM]
,[BOL_NUM]
,[VOYAGE]
....
FROM DETAIL
WHERE
// bunch of other stuff not necessary to show";
header("Content-Type: application/xls");
header("Content-Disposition: attachment; filename=fulldetails-".$ts.".xls");
header("Pragma: no-cache");
header("Expires: 0");
header("Content-Transfer-Encoding: binary ");
$sep = "\t"; //tabbed character
if($result = $dbc->sqlsrv_query($sql)) // <- error is here
{
while( $finfo = sqlsrv_fetch_array($sql, SQLSRV_FETCH_ASSOC) )
{
printf($finfo->name . $sep);
}
}
print("\n");
while( $finfo = sqlsrv_fetch_array($sql, SQLSRV_FETCH_ASSOC) )
{
$schema_insert = "";
for($j = 0; $j < sqlsrv_num_fields($result); $j++)
{
if(!isset($row[$j]))
$schema_insert .= "NULL".$sep;
elseif ($row[$j] != "")
$schema_insert .= "$row[$j]".$sep;
else
$schema_insert .= "".$sep;
}
$schema_insert = str_replace($sep."$", "", $schema_insert);
$schema_insert = preg_replace("/\r\n|\n\r|\n|\r/", " ", $schema_insert);
$schema_insert .= "\t";
print(trim($schema_insert));
print "\n";
}
?>
The error I am getting upon firing this process, the Excel sheet shows this error:
Fatal error: Call to a member function sqlsrv_query() on a non-object in C:\server\htdocs\main\reports\reports.php
Which is pointing to the part above where I labeled "error is here".
On the line above where I pointed the error out, I even changed it to this:
if($result = sqlsrv_query($dbc, $update))
But when the results are exported, the excel sheet is blank.
How can I edit my code to make this work?
I am using PHP to export data from a grid view to an Excel spreadsheet. For some reason, there are blank rows at the top.
As you can see in the image above, the headers begin printing at row 9, and of course the data starts to print afterward, that which I did not show.
My code works and does what I need it to do. I am just trying to figure out why it is printing blank rows at the top.
Here is the code:
<?php
$ts = date('mdY-His');
session_start();
$where = $_SESSION['where']; // this is the parameters passed from another file
$sql = "SELECT * FROM mainTable WHERE " . $where . " ORDER BY CON_STATUS;";
$result = mysql_query($sql) or die("<script language='javascript'>
window.alert('There was no data to send')
window.location.href='../home.php'
</script>");
header("Content-Type: application/xls");
header("Content-Disposition: attachment; filename=importdetails-".$ts.".xls");
header("Pragma: no-cache");
header("Expires: 0");
header("Content-Transfer-Encoding: binary");
$sep = "\t";
for($i = 0; $i < mysql_num_fields($result); $i++)
{
echo mysql_field_name($result, $i) . "\t";
}
print("\n");
while($row = mysql_fetch_row($result))
{
$schema_insert = "";
for($j = 0; $j < mysql_num_fields($result); $j++)
{
if(!isset($row[$j]))
$schema_insert .= "NULL".$sep;
elseif ($row[$j] != "")
$schema_insert .= "$row[$j]".$sep;
else
$schema_insert .= "".$sep;
}
$schema_insert = str_replace($sep."$", "", $schema_insert);
$schema_insert = preg_replace("/\r\n|\n\r|\n|\r/", " ", $schema_insert);
$schema_insert .= "\t";
print(trim($schema_insert));
print "\n";
}
?>
As stated, my code works, besides the printing of the blank rows at the top of the spreadsheet. If you see anything in my code that will remove the blank rows, that would be greatly appreciated.
I haven't tested this, but it looks to me like a problem with your line
for($j-0; $j < mysql_num_fields($result); $j++)
Noting that you are not setting $j=0, but subtracting 0 from $j
Working on creating a CSV file and wondering how I can get the column name in the first row. Right now I think it's trying to echo the Column name but getting 0'nulls. I am also wondering if it's possible to put each of the values in each cell, I can do it manually in excel but that is troublesome.
This is the code:
$result=sqlsrv_query($conn,$sql) or die("Couldn't execute query:<br>" . sqlsrv_error(). "<br>" . sqlsrv_errno());
$file_ending = "csv";
$reals=array();
//header info for browser
header("Content-Type: application/csv");
header("Content-Disposition: attachment; filename=test.csv");
header("Pragma: no-cache");
header("Expires: 0");
/*******Start of Formatting for Excel*******/
//define separator (defines columns in excel & tabs in word)
$sep = "\t"; //tabbed character
$i=0;
foreach( sqlsrv_field_metadata( $result ) as $fieldMetadata ) {
echo $fieldMetadata["Name"]+"\t";
if($fieldMetadata["Type"]=="real")//$fieldMetadata["Type"]=== SQL_REAL
{
$reals[] = $i;
}
$i++;
}
print("\n");
//end of printing column names
//start while loop to get data
while($row = sqlsrv_fetch_array($result))
{
$schema_insert = "";
for($j = 0; $j < sqlsrv_num_fields($result); $j++)
{
if ($row[$j] != "") {
if (in_array($j, $reals)) {
$schema_insert .= str_replace(".",",", $row[$j]) . $sep;
} else {
$schema_insert .= $row[$j] . $sep;
}
}
else
$schema_insert .= "" . $sep;
}
$schema_insert = preg_replace("/\r\n|\n\r|\n|\r/", " ", $schema_insert);
$schema_insert .= "\t";
print(trim($schema_insert));
print "\n";
}
Would this work ? Since sqlsrv_fetch_array return an associative array with the name of the field as key we can take that to input as the first row.
$result=sqlsrv_query($conn,$sql) or die("Couldn't execute query:<br>" . sqlsrv_error(). "<br>" . sqlsrv_errno());
$file_ending = "csv";
$reals=array();
//header info for browser
header("Content-Type: application/csv");
header("Content-Disposition: attachment; filename=test.csv");
header("Pragma: no-cache");
header("Expires: 0");
/*******Start of Formatting for Excel*******/
//define separator (defines columns in excel & tabs in word)
$sep = "\t"; //tabbed character
$firstRow = true;
//start while loop to get data
while($row = sqlsrv_fetch_array($result))
{
if($firstRow)
{
$names = array_keys($row);
$namesToPrint = '';
foreach($names as $idx => $name)
{
if($idx % 2 != 0)
{
$namesToPrint .= $name.',';
}
}
$namesToPrint = substr($namesToPrint, 0, -1);
print $namesToPrint."\n";
$firstRow = false;
}
$schema_insert = "";
for($j = 0; $j < sqlsrv_num_fields($result); $j++)
{
if ($row[$j] != "") {
if (in_array($j, $reals)) {
$schema_insert .= str_replace(".",",", $row[$j]) . $sep;
} else {
$schema_insert .= $row[$j] . $sep;
}
}
else
$schema_insert .= "" . $sep;
}
$schema_insert = preg_replace("/\r\n|\n\r|\n|\r/", " ", $schema_insert);
$schema_insert .= "\t";
print(trim($schema_insert));
print "\n";
}
I am working on creating excel from my SQL server, the problem is that the row is in one cell. I want the output to be on each cell in the same row. That will make it easier to edit and sum data.
This is the query and the output in the sql server:
Output in the Excel file:
Code:
$sql = "
SELECT measurements.title as Tittel, routines.value as Verdi, convert(VARCHAR(10), routines.time, 108) as Tid, pools.name as Basseng, emps.user_name as Ansatt
FROM routines, measure_routine, measurements, pools, emps
WHERE routines.id = measure_routine.routine_id
AND measure_routine.measure_id = measurements.id
AND (measurements.title Like 'T_%') AND measure_routine.pool_id=pools.id AND routines.emp_id=emps.id
AND pools.name = 'Hovedbasseng'
ORDER BY routines.date, routines.time;
";
$result=sqlsrv_query($conn,$sql) or die("Couldn't execute query:<br>" . sqlsrv_error(). "<br>" . sqlsrv_errno());
$file_ending = "xls";
$reals=array();
//header info for browser
header("Content-Type: application/csv");
header("Content-Disposition: attachment; filename=test.csv");
header("Pragma: no-cache");
header("Expires: 0");
/*******Start of Formatting for Excel*******/
//define separator (defines columns in excel & tabs in word)
$sep = "\t"; //tabbed character
$i=0;
foreach( sqlsrv_field_metadata( $result ) as $fieldMetadata ) {
echo $fieldMetadata["Name"]+"\t";
if($fieldMetadata["Type"]=="real")//$fieldMetadata["Type"]=== SQL_REAL
{
$reals[] = $i;
}
$i++;
}
print("\n");
//end of printing column names
//start while loop to get data
while($row = sqlsrv_fetch_array($result))
{
$schema_insert = "";
for($j = 0; $j < sqlsrv_num_fields($result); $j++)
{
if ($row[$j] != "") {
if (in_array($j, $reals)) {
$schema_insert .= str_replace(".",",", $row[$j]) . $sep;
} else {
$schema_insert .= $row[$j] . $sep;
}
}
else
$schema_insert .= "" . $sep;
}
$schema_insert = str_replace($sep."$", "", $schema_insert);
$schema_insert = preg_replace("/\r\n|\n\r|\n|\r/", " ", $schema_insert);
$schema_insert .= "\t";
print(trim($schema_insert));
print "\n";
}
?>
Do this:
Open phpMyadmin
Log in
open table you want to grab
click export
choose file type you want to export it as
Working on converting my mysql php code to sqlsrv, but having issue finding the same functions.
This is the code:
$result=sqlsrv_query($conn,$sql) or die("Couldn't execute query:<br>" . sqlsrv_error(). "<br>" . sqlsrv_errno());
$file_ending = "xls";
$reals=array();
//header info for browser
header("Content-Type: application/xls");
header("Content-Disposition: attachment; filename=$filename.xls");
header("Pragma: no-cache");
header("Expires: 0");
/*******Start of Formatting for Excel*******/
//define separator (defines columns in excel & tabs in word)
$sep = "\t"; //tabbed character
//start of printing column names as names of MySQL fields
/*for ($i = 0; $i < sqlsrv_num_fields($result); $i++) {
$type = sqlsrv_field_metadata($result,$i);
echo sqlsrv_field_metadata($result,$i) . "\t";
if ($type == "real")
{
$reals[] = $i;
}
}
*/
$i=0;
foreach( sqlsrv_field_metadata( $result ) as $fieldMetadata ) {
echo $fieldMetadata["Name"]+"\t";
if($fieldMetadata["Type"]=="real")//$fieldMetadata["Type"]=== SQL_REAL
{
$reals[] = $i;
}
$i++;
}
print("\n");
//end of printing column names
//start while loop to get data
while($row = sqlsrv_num_rows($result))
{
$schema_insert = "";
for($j=0; $j<sqlsrv_num_fields($result);$j++)
{
if(!isset($row[$j]))
$schema_insert .= "NULL".$sep;
elseif ($row[$j] != ""){
if (in_array($j, $reals)){
$schema_insert .= str_replace(".",",","$row[$j]").$sep;
} else {
$schema_insert .= "$row[$j]".$sep;
}
}
else
$schema_insert .= "".$sep;
}
$schema_insert = str_replace($sep."$", "", $schema_insert);
$schema_insert = preg_replace("/\r\n|\n\r|\n|\r/", " ", $schema_insert);
$schema_insert .= "\t";
print(trim($schema_insert));
print "\n";
}
I am unsure what the field_type and field_name is equlent in sqlsrv, but this didn't work:
for ($i = 0; $i < sqlsrv_num_fields($result); $i++) {
$type = sqlsrv_get_field($result,$i);
echo sqlsrv_get_field($result,$i) . "\t";
if ($type == "real")
{
$reals[] = $i;
}
}
I am an ASP.Net developer with very little knowledge about PHP. May be something like below will be useful to you. Just check once.
$stmt = sqlsrv_prepare( $conn, $sql );
$result=sqlsrv_query($conn, $sql);
$i=0;
foreach( sqlsrv_field_metadata( $stmt ) as $fieldMetadata ) {
echo $fieldMetadata["Name"]+"\t";
if($fieldMetadata["Type"]=="real")//$fieldMetadata["Type"]=== SQL_REAL
{
$reals[] = $i
}
$i++;
}
I have not run it before posting here, please let me know in case it's not working.
sqlsrv_field_metadata() can provide the information you need, see Microsofts documentation
The type should be 7 (SQL_REAL) for real or 6 (SQL_FLOAT) for float.