I am using spreadsheet_excel_writer(9.2) to download an excel file from a mysql (4.1.22) database. I have done this successfully on the same server, and this code is very similar, but on this occasion it isn't working. I get an excel file that has the data in it but all in one cell with all sorts of characters intermingled. Does anyone have any idea what the problem could be? I have been making alterations and re-testing for days now. I would really appreciate it if someone could spot something that I am not seeing.
<?php
require_once "/home/cloudare/php/Spreadsheet/Excel/Writer.php";
// Create workbook
$workbook =& new Spreadsheet_Excel_Writer();
// sending HTTP headers
$workbook->send('registration.xls');
// Create worksheet
$worksheet =& $workbook->addWorksheet('Registration Worksheet');
// Add DB connection script here
include("dbinfo.inc.php");
include("functions.inc.php");
$from=$_POST['from'];
$to=$_POST['to'];
mysql_connect(localhost,$username,$password);
#mysql_select_db($database) or die( "Unable to select database");
$query = "SELECT * FROM register WHERE date BETWEEN '$from' AND '$to'" ;
$result = mysql_query($query);
//$result = do_query($query,__LINE__);
// Loop through the data, adding it to the sheet
while($row = mysql_fetch_assoc($result))
{
$array[] = $row;
extract($row);
$worksheet->write($currentRow,0,$id);
$worksheet->write($currentRow,1,$name);
$worksheet->write($currentRow,2,$last);
$worksheet->write($currentRow,3,$title);
$worksheet->write($currentRow,4,$company);
$worksheet->write($currentRow,5,$phone);
$worksheet->write($currentRow,6,$mobile);
$worksheet->write($currentRow,7,$email);
$worksheet->write($currentRow,8,$cloud);
$worksheet->write($currentRow,9,$participant);
$worksheet->write($currentRow,10,$date);
// Remember Excel starts counting rows from #1!
$excelRow = $currentRow + 1;
$currentRow++;
}
$workbook->close();
?>
This is the resultant worksheet:
ÐÏࡱá;þÿ
þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
s#Gert
MrClann
Credogert#clanncredo.ie
2011-06-17°s#Jim
MaherDirectorTrigraph
01-6390050087-6261422jim#trigraph.ieð?
2011-06-17Às#MichaelMcKennaPrincipal
Consultant
SmartCloud#ì̘TBmmckenna#smartcloud.ieð?
2011-06-17Ðs#LiamConnolly
ConsultantCapricornVentis6¦ÊA#liam.connolly#capventis.comð?
2011-06-17às#MinhajShaikh
MrNCIapnaminhaj#hotmail.comð?
2011-06-17> ¶ Root
Entryÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿ
S_E_W is deadware. You should switch to PHPExcel at some point, especially if you want support for something newer than BIFF 5.0 files (Excel 5.0).
Check that your query is working correctly and produces a proper $row. And try to avoid extract() like the plague. It's almost as horrible an idea as register_globals was and lets you reproduce the exact same problems that register_globals caused in the first place. It's not much more work to type out $row['id'], $row['name'] etc..., and saves you the annoyance of overwriting other variables you were using for other purposes BEFORE doing the extract() call.
Related
I wrote a PHP script that generates XLs files from SQL queries on MariaDB using PhpSpreadSheet.
It works really fine most of the time, but I've got issues with my biggest extract: Excel tells me (when I try to open the files) that it is "corrupted". If I skip the alert and open it, all the expected rows are in the file (my Mac users can't open it at all).
Here are the results of my investigations and observations:
- for one given query, I can set a SQL "LIMIT" (max number of rows) to have a non-corrupted file again. For one given query, this LIMIT between ok and not-corrupted and corrupted files will always be the same number.
- for one given query, this "LIMIT" between corrupted and not corrupted files will be pretty much the same whether the IDs are sort ASCendig or DESCending (in the SQL query. This way, suppose it's not a specific character in one row that breaks the file. This conclusion is validated by the fact that if I exclude the rows around this limit, the problem remains. However, if I replace each value to be written in the cells of the XLs file by a big random string ("abcdefghijklm", slightly bigger than the average length of each cell from my request), the problem disappears.
I'm using PHP V7.0.33 (memory_limit 1024M) / Ubuntu16.04.1 / MariaDB.
There is no memory limit warning in the Apache2/log/error.log (no error at all)
<?php
//Initialization
require '/var/www/html/vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xls;
ob_clean();
//Getting data from DB
$connect = mysqli_connect("localhost", "user", "pass", "base","port");
$query = "SELECT * FROM ... WHERE ...";
$result = mysqli_query($connect, $query);
$filename="...";
//If data exist
if(mysqli_num_rows($result) > 0){
$spreadsheet = new Spreadsheet(); /*----Spreadsheet object-----*/
$Excel_writer = new Xls($spreadsheet); /*----- Excel (Xls) Object*/
$spreadsheet->setActiveSheetIndex(0);
$activeSheet = $spreadsheet->getActiveSheet();
$first = true;
$irow=0;
//Loop on each row
while($row = mysqli_fetch_array($result,MYSQLI_ASSOC)){
//Headers
if ($first) {
$irow++;
$icol=0;
foreach (array_keys($row) as &$value) {
$icol++;
$activeSheet->setCellValueByColumnAndRow( $icol,$irow, $value );
}
$first = false;
}
//DataBodyRange
$irow++;
$icol=0;
foreach (($row) as &$value) {
$icol++;
$activeSheet->setCellValueByColumnAndRow( $icol,$irow, $value );
}
}
//Finalizartion
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="'.$filename.'"');
header('Cache-Control: max-age=0');
$Excel_writer->save('php://output');
}
?>
Romain Dub,
I had pretty much the same problem.
Mine was slightly reversed. I wanted an xlsx but kept getting the error as you were. After my spreadsheet was created, I changed the extension to xls and I got the spreadsheet to open and when it opened, I found lines in the spreadsheet about a couple of undefined variables. If you need to resolve your error, possibly check your code for undefined variables being inserted into your spreadsheet.
Just an idea that may or may not be the solution to your problem.
My purpose is to read an excel (.xls) file and store it in the database as well as show the inputs of excel file in the browser.
I am facing problem while reading the file. I have integrated Excelfilereader.php
The program reads the excel file but while printing its output in (excel file content) in the browser, data print in zig-zag way.
Example:
studentid name class school course address [name of fields]
In Browser, the same fields are printed, but the data of studentID is printed under the name, data of name prints under class, but rest all are printed as it is. In first two columns are printed unaligned.
Code used to call Excelreader.php:
[mysql_query("insert into submit_form(parent_id,name,lab,submission,title,sampletype,file) values('','".$_POST['name']."','".$_POST['lab']."','".$_POST['submission']."','".$_POST['title']."','".$_POST['sampletype']."','".$uploadfile."')");
$insertid=mysql_insert_id();
$data = new Spreadsheet_Excel_Reader($_FILES['uploadfile']['name']);
//echo "Total Sheets in this xls file: ".count($data->sheets)."<br /><br />";
$html="<table border='1'>";
for($i=0;$i<count($data->sheets);$i++) // Loop to get all sheets in a file.
{
if(count($data->sheets[$i][cells])>0) // checking sheet not empty
{
//echo "Sheet $i:<br /><br />Total rows in sheet $i ".count($data->sheets[$i][cells])."<br />";
for($j=2;$j<=count($data->sheets[$i][cells]);$j++) // loop used to get each row of the sheet
{
$html.="<tr>";
for($k=1;$k<=count($data->sheets[$i][cells][$j]);$k++) // This loop is created to get data in a table format.
{
$html.="<td>";
$html.=$data->sheets[$i][cells][$j][$k];
$html.="</td>";
}
$data->sheets[$i][cells][$j][1];
$eid = $eid = mysqli_real_escape_string($connection,$data->sheets[$i][cells][$j][1]);
$age = mysqli_real_escape_string($connection,$data->sheets[$i][cells][$j][2]);
$gender = mysqli_real_escape_string($connection,$data->sheets[$i][cells][$j][3]);
$ethnic = mysqli_real_escape_string($connection,$data->sheets[$i][cells][$j][4]);
$cancer = mysqli_real_escape_string($connection,$data->sheets[$i][cells][$j][5]);
$sample = mysqli_real_escape_string($connection,$data->sheets[$i][cells][$j][6]);
$instrument = mysqli_real_escape_string($connection,$data->sheets[$i][cells][$j][7]);
$instrumenttype = mysqli_real_escape_string($connection,$data->sheets[$i][cells][$j][8]);
$query = "insert into submit_form(parent_id,name,lab,submission,title,patient,age,gender,ethnic,cancer,sample,instrument,instrumenttype,attach,sampletype,file) values('".$insertid."','".$_POST['name']."','".$_POST['lab']."','".$_POST['submission']."','".$_POST['title']."','".$eid."','".$age."','".$gender."','".$ethnic."','".$cancer."','".$sample."','".$instrument."','".$instrumenttype."','1','".$_POST['sampletype']."','".$uploadfile."')";
mysqli_query($connection,$query);
$html.="</tr>";
}
}][2]
You have mixed mysql_* calls with mysqli_* calls. Use only mysqli_* calls.
(And you should escape the $_POST[] columns, too. They are vulnerable to hackers.)
I want to download a file which includes the results of my mysql query but my problem is, the .txt file includes only the last result of my mysql query. It should includes actually 5 results like this:
http://user:password#server.com:8080
Can someone show me where here the problem is?
<?php
$result = mysql_query("SELECT serverurl FROM ibn");
echo mysql_error();
while ($row = mysql_fetch_array($result)) {
$result2 = mysql_query("SELECT streamport,streamname FROM streams");
echo mysql_error();
while ($row2 = mysql_fetch_array($result2)) {
$result3 = mysql_query("SELECT client_username,client_openpasswd FROM clients WHERE `client_id` = '$id' ");
echo mysql_error();
while ($row3 = mysql_fetch_array($result3)) {
$streamurl= $row['serverurl'];
$streamport = $row2['streamport'];
$streamuser= $row3['client_username'];
$streampassword= $row3['client_openpasswd'];
$streamchannel= $row2['streamname'];
echo "<p>http://$streamuser:$streampassword#$streamurl:$streamport</p>";
}
}
}
//Generate text file on the fly
header("Content-type: text/plain");
header("Content-Disposition: attachment; filename=bouquet.txt");
?>
Your basic output can be achieved by moving your calls to header() to the top of the script and emitting your data later. The header commands will only be effective if they're issued before any output is sent to the client.
You can demonstrate this with a simple script:
<?php
header("Content-type: text/plain");
header("Content-Disposition: attachment; filename=bouquet.txt");
echo "A line of text\n";
The remainder of your code is more problematic. It's not clear why you're doing this, but the effect of your code is to produce the cartesian product of the three tables. i.e. every row in every table is combined with every row in every other table. I doubt this is actually what you want, but...
You can achieve the same result more efficiently by using an SQL JOIN with no ON clause. Using that and concatenating the required fields you can do almost everything you want in a single SQL query:
select
concat('http://',
clientname,':',
clientopenpassword,'#',
serverurl,':',
streamsport)
as URL
from ibn, streams, clients where client_id=1
I'll leave converting this to a working PHP script as an exercise for the reader, but your code above provides a good template. Remember, only one query and one loop to fetch the result and emit it.
Note that mysql_*() is deprecated - use mysqli_*() for new code. You should also watch for possible SQL injection where you use $id in your query.
i have 150 rows and 40 columns in a sql table..i am displaying the entire table in a web page..now,what i want to do is create a link on that web page that will take the entire table and insert it in an excel file(dosn't matters if it creates a new excel file,or modifies sum exisiting one)...now i can do it manually by using(PHPExcel library)," objPHPExcel->setCellValue('C5', $v) "...but i would have to write this like 40 times(change '$v' variable in every statment) nd its inside a loop that will run 150 times..hence i dont wanna do it this way..
now i wanted to know if i can insert the table,row by row in the excel sheet..like when i insert a row,it will insert the entire cells of d row..that way it will be pretty easy..so i wanted to know if there any specific commands for doing this..
if not,wat other alternatives do i have of doing this..all i want to do is to export the entire sql table to an excel file using php..
So use the fromArray() method that PHPExcel thoughtfully provides that allows you to write a whole row or whole block of cells in one call from an array.
Looking at the examples and reading the documentation always helps
Additional note
Incidentally, $objPHPExcel->setCellValue('C5', $v) will only work if $objPHPExcel is a worksheet, most of the examples use $objPHPExcel for the workbook (ie the collection of worksheets) so don't get confused
EDIT
For fetching the results from your database, use
sqlsrv_fetch_array($tsql, SQLSRV_FETCH_ASSOC)
or
sqlsrv_fetch_array($tsql, SQLSRV_FETCH_NUMERIC)
EDIT 2
Check how the database is set to handle NULL returns; but using
$objPHPExcel->getActiveSheet()->fromArray($rows, 0, 'A'.$rowCNT);
should set all NULL values from the database result to 0 value in PHPExcel
The easiest way is to export a .csv file, which can also be read by excel.
All you have to do is create this page :
<?
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");
$link = mysql_connect('db', 'dblogin', 'dbpasswd');
#mysql_select_db('dbname') or die( "Unable to select database");
$query=mysql_query("SELECT * FROM whatever");
$j=0;
$nbField = mysql_num_fields($query);
while ($j < $nbField) {
echo mysql_field_name($query,$j).";";
$j++;
}
echo "\n";
while ($row = mysql_fetch_array($query, MYSQL_NUM)) { echo implode(";", $row)."\n"; }
?>
Then you insert a link pointing directly to this php page, it will download the csv file.
Trying to use Zend_Search_Lucene to search a MySql database and display the results. Running the following code and can't figure out why I'm not getting any info into my index. Quite new with PHP, MySql and Zend but I've spent the last week trying to figure this out on my own and have exhausted every resource I could find. Anyway, I echoed what's coming out of my database to make sure my query worked which seems to be OK. It also creates the index files just fine but when I've taken a look at it with the Luke Toolbox I get nothing but a list of the fields created filled with gooseggs. Just to make sure I'm using that correctly I found some code using Zend_Feed and ran that through Lukes and got all kinds of results. Also able to get results from that same code on my result test page but getting 0 when using the code below. Seems I can't get the database info indexed although the count tells me that 5 documents have been indexed (which is the number of rows I have in my database table) and I'm not getting any errors. The library script is just an autoloader script and where I set up my db connection which I've confirmed works as well. Although it's likely I'm missing the obvious or demonstrating what a novice I truly am, any help would be much appreciated.Thanks.
<?php>
require_once('scripts/library.php');
require_once ('Zend/Search/Lucene.php');
$index = Zend_Search_Lucene::create('./docindex');
$sql = ('SELECT * FROM news');
foreach ($db->query($sql) as $row){
echo $row ['author'];
echo $row['headline'];
echo $row ['source'];
}
foreach ($row as $document){
$document = new Zend_Search_Lucene_Document ();
$document->addField(Zend_Search_Lucene_Field::Text ('author', $docAuthor));
$document->addField(Zend_Search_Lucene_Field::Text ('headline', $docHeadline));
$document->addField(Zend_Search_Lucene_Field::Text ('source', $docSource));
$document->addField(Zend_Search_Lucene_Field::Unstored ('contents', $docStory));
$index->addDocument($document);
}
$index->commit();
echo $index->count()." documents have been indexed.\n";
?>
It looks like you had an extra foreach() that wasn't really doing anything and I couldn't see where your data variables were assigned, try this it should be pretty close:
<?php
require_once('scripts/library.php');
require_once ('Zend/Search/Lucene.php');
$index = Zend_Search_Lucene::create('./docindex');
$sql = ('SELECT * FROM news');
foreach ($db->query($sql) as $row) {
echo $row ['author'];
echo $row['headline'];
echo $row ['source'];
$document = new Zend_Search_Lucene_Document ();
//you use an unindexed field for the id because you want the
//id to be included in the search results but not searchable
$document->addField(Zend_Search_Lucene_Field::unIndexed('id', $row['id']));
$document->addField(Zend_Search_Lucene_Field::Text('author', $row ['author']));
$document->addField(Zend_Search_Lucene_Field::Text('headline', $row['headline']));
$document->addField(Zend_Search_Lucene_Field::Text('source', $row ['source']));
$document->addField(Zend_Search_Lucene_Field::Unstored('contents', $row['docStory']));
$index->addDocument($document);
}
$index->commit();
echo $index->count() . " documents have been indexed.\n";
?>