Skip to page content or skip to Accesskey List.
Search evolt.org
evolt.org login: or register

Work

Main Page Content

Using MySQL and PHP to Present Excel Spreadsheets

Rated 4.34 (Ratings: 11) (Add your rating)

Log in to add a comment
(14 comments so far)

Want more?

 
Picture of eli

Jay Blanchard

Member info | Full bio

User since: March 21, 2001

Last login: August 27, 2008

Articles written: 6

"Collinstwerp!"

"That's Collinsworth, sir," you say, meakly.

"Whatever Collinearth, I need to see some trending data on sales...NOW!"

"It's Collinsworth sir," you repeat

"Can I get that in my speadsheet thingie Collinsyurp?!?", he continues to yell.

"I'll get on it right away! mumbling*you pig-headed freak*mumbling," as you head for your cube.

Number crunchers just love spreadsheets, the numbers, the colors, the graphs, and all of the functions for bending and shaping the numbers to do their bidding. And they like them a certain way, usually as a pivot table where the columns represent groups of data, the rows represent groups of data, and at the intersection of a row and column is the number that they are looking for, as in this example;

  Water Pistols Balloons Party Packs Streamers Total Shipped Today
2002-03-01 270 352 368 360 1350
2002-03-02 250 212 374 310 1146
2002-03-03 167 208 421 311 1107
2002-03-04 165 223 404 297 1089
2002-03-05 115 214 409 301 1039
Total By Items 967 1209 1976 1279  

You need to make it as easy as possible, a one-click link to the data. What is a developer to do?

Set Up Some Test Data

Let's create a table, and some data to work with:

CREATE TABLE `tblProductToy` (
  `ID` int(11) NOT NULL auto_increment,
  `Toy` varchar(32) default NULL,
  `DateShipped` varchar(10) default NULL,
  `NumberShipped` int(11) default NULL,
  PRIMARY KEY  (`ID`)
)
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-01', '36');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-01', '12');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-01', '11');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-01', '14');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Balloon', '2002-03-01', '36');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-01', '36');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-03', '11');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-02', '14');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-04', '36');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-06', '12');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Balloon', '2002-03-03', '17');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Balloon', '2002-03-04', '13');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Party Pack', '2002-03-02', '14');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Party Pack', '2002-03-04', '36');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Party Pack', '2002-03-06', '12');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Party Pack', '2002-03-03', '17');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Party Pack', '2002-03-04', '13');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-01', '14');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Balloon', '2002-03-01', '36');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-01', '36');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-03', '11');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Water Pistol', '2002-03-02', '14');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Streamer', '2002-03-04', '36');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Streamer', '2002-03-06', '12');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Streamer', '2002-03-03', '17');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Streamer', '2002-03-04', '13');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Streamer', '2002-03-02', '14');
insert into tblProductToy (Toy, DateShipped, NumberShipped) values ('Streamer', '2002-03-04', '36');

If you select all of the data in the table it will look something like this;

mysql> select * from tblProductToy;
+----+--------------+-------------+---------------+
| ID | Toy          | DateShipped | NumberShipped |
+----+--------------+-------------+---------------+
|  1 | Water Pistol | 2002-03-01  |            36 |
|  2 | Water Pistol | 2002-03-01  |            12 |
|  3 | Water Pistol | 2002-03-01  |            11 |
|  4 | Water Pistol | 2002-03-01  |            14 |
|  5 | Balloon      | 2002-03-01  |            36 |
|  6 | Water Pistol | 2002-03-01  |            36 |
|  7 | Water Pistol | 2002-03-03  |            11 |
|  8 | Water Pistol | 2002-03-02  |            14 |
|  9 | Water Pistol | 2002-03-04  |            36 |
| 10 | Water Pistol | 2002-03-06  |            12 |
| 11 | Balloon      | 2002-03-03  |            17 |
| 12 | Balloon      | 2002-03-04  |            13 |
| 13 | Party Pack   | 2002-03-02  |            14 |
| 14 | Party Pack   | 2002-03-04  |            36 |
| 15 | Party Pack   | 2002-03-06  |            12 |
| 16 | Party Pack   | 2002-03-03  |            17 |
| 17 | Party Pack   | 2002-03-04  |            13 |
| 18 | Water Pistol | 2002-03-01  |            14 |
| 19 | Balloon      | 2002-03-01  |            36 |
| 20 | Water Pistol | 2002-03-01  |            36 |
| 21 | Water Pistol | 2002-03-03  |            11 |
| 22 | Water Pistol | 2002-03-02  |            14 |
| 23 | Streamer     | 2002-03-04  |            36 |
| 24 | Streamer     | 2002-03-06  |            12 |
| 25 | Streamer     | 2002-03-03  |            17 |
| 26 | Streamer     | 2002-03-04  |            13 |
| 27 | Streamer     | 2002-03-02  |            14 |
| 28 | Streamer     | 2002-03-04  |            36 |
+----+--------------+-------------+---------------+
28 rows in set (0.02 sec)

How are we going to turn this into something that looks like our example above?

Do It At The Data Level

What you need to know about first of all is a handy little thing called a crosstab query. Using a crosstab you can output the data from the database into a table format with almost everything you need to deliver a spreadsheet. Here is the full crosstab query for this table to show how many of each item were shipped on a particular date;

SELECT DateShipped,
SUM(IF(Toy = 'Water Pistol', NumberShipped, 0)) AS "Water Pistols",
SUM(IF(Toy = 'Balloon', NumberShipped, 0)) AS "Balloons",
SUM(IF(Toy = 'Party Pack', NumberShipped, 0)) AS "Party Packs",
SUM(IF(Toy = 'Streamer', NumberShipped, 0)) AS "Streamers"
FROM tblProductToy
GROUP BY DateShipped

If you run this query against the data we created above you will get the following results;

+-------------+---------------+----------+-------------+-----------+
| DateShipped | Water Pistols | Balloons | Party Packs | Streamers |
+-------------+---------------+----------+-------------+-----------+
| 2002-03-01  |           159 |       72 |           0 |         0 |
| 2002-03-02  |            28 |        0 |          14 |        14 |
| 2002-03-03  |            22 |       17 |          17 |        17 |
| 2002-03-04  |            36 |       13 |          49 |        85 |
| 2002-03-06  |            12 |        0 |          12 |        12 |
+-------------+---------------+----------+-------------+-----------+

Pretty slick, eh? It works like this, first we get the data we wish to group by, SELECT DateShipped. Then we do something that looks complicated, but in reality is quite simple. For each product in the table we write a line of SQL that looks like this, SUM(IF(Toy = 'Water Pistol', NumberShipped, 0)) AS "Water Pistols". What does this line do? Let's break it down;

  • SUM( will total the information that we tell it to, in this case the values returned by the IF statement
  • IF(Toy = 'Water Pistol', determines if this column value exists
  •  NumberShipped, gets the value from this column if  Toy = 'Water Pistol' is true
  •  0)) makes the value zero if Toy = 'Water Pistol' is false
  •  AS "Water Pistols" gives the result column a name

Of course, FROM tblProductToy tells the query which table, and GROUP BY DateShipped groups the records together by date with the proper totals. If you wanted to count the shipments of each item per day change NumberShipped to 1 in each of the SUM...IF statements. There are many functions available to MySQL as well as many other database management packages that will allow you to do things like average results or use conditional expressions to generate results.

We still don't have some of the numbers we need though, such as "Total Shipped Today" so lets change our query, adding the line sum(NumberShipped) as "Total Shipped Today" ;

SELECT DateShipped,
SUM(if(Toy = 'Water Pistol', NumberShipped, 0)) AS "Water Pistols",
SUM(if(Toy = 'Balloon', NumberShipped, 0)) AS "Balloons",
SUM(if(Toy = 'Party Pack', NumberShipped, 0)) AS "Party Packs",
SUM(if(Toy = 'Streamer', NumberShipped, 0)) AS "Streamers",
SUM(NumberShipped) AS "Total Shipped Today"
FROM tblProductToy
GROUP BY DateShipped

Running this query gives us the following results;

+-------------+---------------+----------+-------------+-----------+---------------------+
| DateShipped | Water Pistols | Balloons | Party Packs | Streamers | Total Shipped Today |
+-------------+---------------+----------+-------------+-----------+---------------------+
| 2002-03-01  |           159 |       72 |           0 |         0 |                 231 |
| 2002-03-02  |            28 |        0 |          14 |        14 |                  56 |
| 2002-03-03  |            22 |       17 |          17 |        17 |                  73 |
| 2002-03-04  |            36 |       13 |          49 |        85 |                 183 |
| 2002-03-06  |            12 |        0 |          12 |        12 |                  36 |
+-------------+---------------+----------+-------------+-----------+---------------------+

Very handy. Again, if we were counting total shipments we could replace SUM(NumberShipped) as "Total Shipped Today" with COUNT(*). Try making the replacements and see what happens.

Crosstabs enable you to get pretty complete information from your database where this kind of table is concerned, but it may not give you all you need, at least not without running another query like this one, which totals each item for the complete range of records and provides a total number of items shipped;

SELECT SUM(IF(Toy = 'Water Pistol', NumberShipped, 0)) AS "Total Water Pistols",
SUM(IF(Toy = 'Balloon', NumberShipped, 0)) AS "Total Balloons",
SUM(IF(Toy = 'Party Pack', NumberShipped, 0)) AS "Total Party Packs",
SUM(IF(Toy = 'Streamer', NumberShipped, 0)) AS "Total Streamers",
SUM(NumberShipped) AS "Total Shipped"
FROM tblProductToy

Which returns;

+---------------------+----------------+-------------------+-----------------+---------------+
| Total Water Pistols | Total Balloons | Total Party Packs | Total Streamers | Total Shipped |
+---------------------+----------------+-------------------+-----------------+---------------+
|                 257 |            102 |                92 |             128 |           579 |
+---------------------+----------------+-------------------+-----------------+---------------+

Or we can "turn the table";

SELECT Toy,
SUM(IF(DateShipped = '2002-03-01', NumberShipped, 0)) AS "March 1, 2002",
SUM(IF(DateShipped = '2002-03-02', NumberShipped, 0)) AS "March 2, 2002",
SUM(IF(DateShipped = '2002-03-03', NumberShipped, 0)) AS "March 3, 2002",
SUM(IF(DateShipped = '2002-03-04', NumberShipped, 0)) AS "March 4, 2002",
SUM(IF(DateShipped = '2002-03-05', NumberShipped, 0)) AS "March 5, 2002",
SUM(IF(DateShipped = '2002-03-06', NumberShipped, 0)) AS "March 6, 2002",
SUM(NumberShipped) AS "Total Shipped"
FROM tblProductToy
GROUP BY Toy;

Getting these results;

+--------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+
| Toy          | March 1, 2002 | March 2, 2002 | March 3, 2002 | March 4, 2002 | March 5, 2002 | March 6, 2002 | Total Shipped |
+--------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+
| Balloon      |            72 |             0 |            17 |            13 |             0 |             0 |           102 |
| Party Pack   |             0 |            14 |            17 |            49 |             0 |            12 |            92 |
| Streamer     |             0 |            14 |            17 |            85 |             0 |            12 |           128 |
| Water Pistol |           159 |            28 |            22 |            36 |             0 |            12 |           257 |
+--------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+

This doesn't give us a total shipped each day though and we only want to run one query to the database for these results. That means that we will have to do some calculations in our one-click link to the spreadsheet. We'll handle this in PHP, with a couple of "Stupid IE Tricks" thrown in for good measure.

PHP To The Rescue

Within our PHP code we can place raw HTTP headers (see PHP Header Function, Hypertext Transfer Protocol - HTTP/1.1, and other associated links) prior to any output from the PHP in order that the output might be utilized by applications, such as Microsoft® Excel.

&lt;?php<br>
header(&quot;Content-Type: application/vnd.ms-excel&quot;);<br>
header(&quot;Expires: 0&quot;);<br>
header(&quot;Cache-Control: must-revalidate, post-check=0, pre-check=0&quot;);<br>
?&gt;

The first header line sets up the application type, in this case Microsoft® Excel. The second header line essentially tells the browser not to cache the information. The third header line makes sure that subsequent calls to the server are revalidated/authenticated. For further detail about HTTP headers I will refer you to the above links.

Once we have connected to the MySQL server and selected the database we wish to use we can issue our crosstab query.

&lt;?php<br>
$qx = "SELECT DateShipped, ";<br>
$qx .= "SUM(if(Toy = 'Water Pistol', NumberShipped, 0)) AS "Water Pistols", ";<br>
$qx .= "SUM(if(Toy = 'Balloon', NumberShipped, 0)) AS "Balloons", ";<br>
$qx .= "SUM(if(Toy = 'Party Pack', NumberShipped, 0)) AS "Party Packs", ";<br>
$qx .= "SUM(if(Toy = 'Streamer', NumberShipped, 0)) AS "Streamers", ";<br>
$qx .= "SUM(NumberShipped) AS "Total Shipped Today" ";<br>
$qx .= "FROM tblProductToy ";<br>
$qx .= "GROUP BY DateShipped ";<br>
?&gt;

Which is great if we know that out list of toys is static. What if they are not? We can do two queries in PHP, using the results of one query to complete the second query. This will always give us all of the products available to analyze.

&lt;?php<br>
//query for toy list<br>
$qtoy = "SELECT DISTINCT Toy ";<br>
$qtoy .= "FROM tblProductToy ";<br>
$qtoy .= "ORDER BY Toy ";<br>
<br>
$dbtoy = mysql_query($qtoy, $dbconnect);<br>
<br>
//query for crosstab<br>
$qx = "SELECT DateShipped ";<br>
while($rowx = mysql_fetch_object($dbtoy)){<br>
$qx .= ", SUM(IF(Toy = '$rowx->Toy', NumberShipped, 0)) AS Toy ";<br>
}<br>
$qx .= ", SUM(NumberShipped) AS \"Total Shipped\" ";<br>
$qx .= "FROM tblProductToy ";<br>
$qx .= "GROUP BY DateShipped ";<br>
?&gt;

One of the convenient things about doing this little project is the fact that Excel "understands" tables formatted in HTML, which is how we are going to output the table. You can output the information as comma seperated values (CSV) or other formats as well. Sending the output in HTML format also gives us the chance to easily apply style information, either from CSS or inline.

Here is the entire code for crosstab.php;

<?php
header("Content-Type:  application/vnd.ms-excel");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");

//connect to and select database
if(!($dbconnect = mysql_pconnect("127.0.0.1", "user", "password"))){
	print("Failed to connect to database!\n");
	exit();
	}
if(!mysql_select_db("test", $dbconnect)){
	print("Failed to select database!\n");
	exit();
	}

//query for toy list
$qtoy = "SELECT DISTINCT Toy ";
$qtoy .= "FROM tblProductToy ";
$qtoy .= "ORDER BY Toy ";

if(!($dbtoy = mysql_query($qtoy, $dbconnect))){
	print("MySQL reports: " . mysql_error() . "\n");
	exit();
	}

//query for crosstab
$qx = "SELECT DateShipped ";
while($rowx = mysql_fetch_object($dbtoy)){
		$qx .= ", SUM(IF(Toy = '$rowx->Toy', NumberShipped, 0)) AS Toy ";
	}
$qx .= ", SUM(NumberShipped) AS \"Total Shipped\" ";
$qx .= "FROM tblProductToy ";
$qx .= "GROUP BY DateShipped ";

//print($qx);

if(!($dbx = mysql_query($qx, $dbconnect))){
	print("MySQL reports: " . mysql_error() . "\n");
	exit();
	}
?>
<table border="1">
<tr>
<td bgcolor="#FFFFCC"></td>
<? php
mysql_data_seek($dbtoy, 0);
	while($rowx = mysql_fetch_object($dbtoy)){
		print("<td bgcolor=\"#FFFFCC\">");
		print("$rowx->Toy");
		print("</td>");
		}
?>
<td bgcolor="#00FFFF"><strong>Total By Date</strong></td>
</tr>
<?php
while($dbrow = mysql_fetch_row($dbx)){
	print("<tr>");
	$col_num = 0;
	foreach($dbrow as $key=>$value){
		if($dbrow[$col_num] > 0){
			print("<td>$dbrow[$col_num]</td>");
			}
		else {
			print("<td> </td>");
			}
		$col_num++;
		}
	print("</tr>\n");
	}
//total the columns
print("<tr bgcolor=\"#CCCCCC\">");
print("<td><strong>Total By Record</strong></td>");
	$alpha = b;
	$numeric = 2;
	$rows = mysql_num_rows($dbx)+1;
	for($i=1; $i < mysql_num_fields($dbx); $i++){
		print("<td><strong>=sum($alpha$numeric:$alpha$rows)</strong></td>");
		$alpha++;
		}
print("</tr>\n");
?>
</table>

For those of you who jumped ahead, cut-n-pasted the code (you know who you are!) things came out differently than you had planned. You actually got the HTML table;

Balloon Party Pack Streamer Water Pistol Total By Date
2002-03-01 72     159 231
2002-03-02   14 14 28 56
2002-03-03 17 17 17 22 73
2002-03-04 13 49 85 36 183
2002-03-06   12 12 12 36
Total By Record =sum(b2:b6) =sum(c2:c6) =sum(d2:d6) =sum(e2:e6) =sum(f2:f6)

This is where the "Stupid IE Trick" comes in, but more about that later. Let's look at the code that sets up the ability to be able to total columns of data within the spreadsheet.

print("&lt;tr bgcolor=\"#CCCCCC\"&gt;");<br>
print("&lt;td&gt;&lt;strong&gt;Total By Record&lt;/strong&gt;&lt;/td&gt;");<br>
$alpha = b;<br>
$numeric = 2;<br>
$rows = mysql_num_rows($dbx)+1;<br>
for($i=1; $i < mysql_num_fields($dbx); $i++){<br>
print("&lt;td&gt;&lt;strong&gt;=sum($alpha$numeric:$alpha$rows)&lt;/strong&gt;&lt;/td&gt;");<br>
$alpha++;<br>
}<br>
print("&lt;/tr&gt;\n");<br>

Each calculation in an Excel spreadsheet using relative positioning of the cells requires an alphanumeric combination within the function to specify the cell information (i.e. =sum(f2:f6)). Since we are dynamically generating our query we cannot be sure how many rows or columns may be involved, therfore we have to find a way to calculate these alphanumeric combinations.

First we set some variables, $alpha = b; and $numeric = 2;. Why these values? Because the first column and row (A and 1) of the spreadsheet haave data in them other than quantities of items. Next we get the number of rows returned by the query and add 1 to it to make up for the row where the toy names are presented. Next we get the number of fields (from left-to-right) in the query, and starting at 1 (because of our offset for the column with the date in it), we loop through each field and increment the letter in the alphanumeric combo. It is all put together in this line;

print("&lt;td&gt;&lt;strong&gt;=sum($alpha$numeric:$alpha$rows)&lt;/strong&gt;&lt;/td&gt;");

that gives Excel the information that it needs to properly calculate each column in the query. As you can see, being able to use functions available to Excel can be quite a powerful tool.

But It's Not A Spreadsheet!

Now, for that "Stupid IE Trick"! *drum roll* ....
There is a bug in Internet Explorer that causes the browser to fail on recognition of some HTTP headers, including Excel. But we are still looking for that "one-click pony", so how do we overcome this problem? Thanks to input from thelist a solution was gained through the use of a phantom link, a link that fools Internet Explorer about the content type of the information. The URL to the spreadsheet needs to be like this;

&lt;a href=&quot;http://yourservername/crosstab.php/crosstab.xls&quot;&gt;

By linking this way the PHP will get processed properly and the phantom crosstab.xls will say to Internet Explorer that Excel type information is coming.

Etcetera...

Once a user has gotten his spreadsheet he can save it, modify it, manipulate the numbers, do graphs, or do any number of other things (without changing data in the database) that will satisfy any number-cruncher's heart.

This article has just barely scratched the surface of the flexibility and power of being able to present data in a pivot table format within Microsoft® Excel. There may be ways to streamline and refine this code as well, offering more possibilities for using spreadsheets generated from live data. You can use an HTML form to accept input (such as date ranges or product types) to generate more specific spreadsheets. It is possible to use macros within the spreadsheet to present the data in different formats. And I suspect that it is possible to generate data for other spreadsheet programs.

"Good work Collinsgirth"

"It's Collinsworth, sir"

A long time code-jockey Jay enjoys music (especially horn bands like Tower of Power, and for those in the know...drum corps), furniture building, physics, and philosophy. His latest projects include several mission-specific web-based project tracking systems.

Jay lives in Central Texas, but has never forgotten his South Louisiana heritage. His daughter, Kaitlyn, is his pride and joy. She is learning web development.

badblue

Submitted by Junglee on May 26, 2002 - 09:33.

nice article !
i have seen this free p2p webserver product (its probably the smallest PHP capable web server ) called badblue which renders excel / word documents natively into html , and works pretty well...

login or register to post comments

Code Error

Submitted by eli on August 20, 2002 - 13:37.

It has been pointed out that there is a small syntax error in the PHP code. At this section;

Remove the space between the "?" and "php" in the opening PHP tag.
<?php
mysql_data_seek
($dbtoy, 0);
    while(
$rowx = mysql_fetch_object($dbtoy)){
        print(
"<td bgcolor=\"#FFFFCC\">");
        print(
"$rowx->Toy");
        print(
"</td>");
        }
?>

login or register to post comments

Check MySQL errors

Submitted by shotgun on September 13, 2002 - 09:58.

Tired of getting "Could not make Query" or some other stupid non-intuitive error? Then use this query function (MySQL, but could be ported for other databases) to view the specific error of the query.
function mysql_query_eval($sql) {

        $mysql_eval_result = mysql_query($sql) or $mysql_eval_error = mysql_error();
        if ($mysql_eval_error) {
                print "mysql_error: $mysql_eval_error\n";
                return FALSE;
        }
        else {
                return $mysql_eval_result;
        }
}

login or register to post comments

Check MySQL errors

Submitted by shotgun on December 31, 2002 - 07:28.

Tired of getting "Could not make Query" or some other stupid non-intuitive error? Then use this query function (MySQL, but could be ported for other databases) to view the specific error of the query.

function mysql_query_eval($sql) {

        $mysql_eval_result = mysql_query($sql) or $mysql_eval_error = mysql_error();
        if ($mysql_eval_error) {
                print "mysql_error: $mysql_eval_error\n";
                return FALSE;
        }
        else {
                return $mysql_eval_result;
        }
}

login or register to post comments

Simple SQL to Excel Dump

Submitted by danzarrella on January 24, 2003 - 10:13.

Here's my simple solution: php excel

login or register to post comments

enter number to excel file as string or text

Submitted by BS on October 29, 2003 - 00:26.

It is wonderful to read the article "Using MySQL and PHP to Present Excel Spreadsheets" and the related links! I wonder if anyone have any idea for the following problems: 1) how to use PHP to enter a string like "1234567890123" to excel file and let it still be a string, like "1234567890123", not as a number like "1.23456E+12"; 2) how to use PHP to enter a string like "0903" or "09/03" as a string to excel file, and let it remain what is is, like "0903" or "09/03", not as "903" or "9 March". Thanks in advance for any idea!

login or register to post comments

numbers as text

Submitted by eli on October 29, 2003 - 03:50.

To do what you are asking just add a single quote to the beginning of the number in question. Excel will generally not display the single quote, and it will then treat the cell as text.

login or register to post comments

single quote displayed when enter number as text

Submitted by BS on October 29, 2003 - 05:19.

Thank you Eli for your message! I try to add a single quote at the beginning, at the end, or at both end. The number was treated as text, but the single quote is always displayed there with the number. I am using Excel2000. Is there any other way to enter the number as text to Excel (without having single quote or other character appended)? Thanks again!

login or register to post comments

what about excel sheets with multiple tabs?

Submitted by splodester on December 22, 2004 - 10:37.

is there a way to make a final output of excel spreadsheet that then has several different tables on separate sheet tabs?

login or register to post comments

To enter number to excel file as string or text

Submitted by doubtfire on March 3, 2005 - 12:17.

When creating excel file from PHP, you can append a "Non-break space" (&nbsp;) to the number. Exel will display it exactly what the text is.

login or register to post comments

Headers

Submitted by spanglerco on April 18, 2006 - 13:56.

It typically makes debugging so much easier if you don't send headers until after mysql queries are done. If you send the headers at the beginning, the errors will be sent as an excel worksheet instead of text/html.

login or register to post comments

linking

Submitted by ruffain on May 5, 2006 - 09:57.

When i replace this line print ("=sum($alpha$numeric:$alpha$rows)"); $alpha++; with this print ("<a href="http://myservername/crosstab.php/crosstab.xls">"); $alpha++; I get the word total but it doesn't show any totals. can someone help me out a little and tell me whats wronge. Thanks in advance Ruffain

login or register to post comments

Couple Questions

Submitted by wendy on March 5, 2007 - 03:13.

is there a way to make a final output of excel spreadsheet that then has several different tables on separate sheet tabs? And is there any other way to enter the number as text to Excel (without having single quote or other character appended)? Wendy Carlyle

login or register to post comments

An even better way

Submitted by Sander on July 21, 2008 - 20:43.

Hey there, This method is great, but not very flexible. I was looking for information on this as I found this: http://code.google.com/p/php-excel/ . You can use XML to format your Excel-file. To see how you can create such a file, open a regular Excel-file and under Save As.., choose for XML-worksheet. It works great and gives you great flexibility as I noticed ;) Microsoft has also a article on this: http://technet.microsoft.com/en-us/magazine/cc161037.aspx

login or register to post comments

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.orgEvolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.