I have a script that takes a SQL Statement and puts the query result into a CSV file. Right now it only the rows of the table, I want it to Put the headings of the table at the top. How would I do that with this current script?
Script...
<?php
include 'connect.php';
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment;filename="export.csv"');
header('Cache-Control: max-age=0');
$fpcsv = fopen('php://output', "a+");
$sqlstatement = $_GET['sqlstatement'];
$exportcsv_q = mysql_query($sqlstatement);
if (#mysql_num_rows($exportcsv_q) > 0) {
$campos = mysql_num_fields($exportcsv_q);
while ($exportcsv_r = mysql_fetch_row($exportcsv_q)) {
fputcsv($fpcsv, $exportcsv_r);
}
}
exit;
?>
If anyone out there has a mysqli version of this I would love to be able to switch this over.
First, the answer to your question: output the headers before your while loop:
if (#mysql_num_rows($exportcsv_q) > 0) {
// output headers here
fwrite($fpcsv, "header1,header2,foo,bar,..."); // <-- like this
// if you want, you could do it this way:
// fputcsv($fpcsv, array("header1", "header2", ...));
$campos = mysql_num_fields($exportcsv_q);
while ($exportcsv_r = mysql_fetch_row($exportcsv_q)) {
fputcsv($fpcsv, $exportcsv_r);
}
}
If you want to have the headers even if there is no data, just move that line outside your if block, as well.
Second, yes, you should stop using mysql_*; the mysql_* functions are outdated, deprecated, and insecure. Use MySQLi or PDO instead. How to do that is too broad for a single question here. If you get stuck on some aspect of it, ask a new question about that.
Third, swallowing/suppressing errors with # is considered bad practice and can lead to unexpected results. Use a proper try { ... } catch (...) {...} block instead so you can handle/log/report the error as needed.
Related
i'm trying to export from mysql to excel using PHPExcel, i create a button to start exporting proses. It's loading but return with blank white page, i check every line from the code and didn't found any problem. Calling data from table is normal, check it with echo. so i think there is a problem with exporting process, here is the code
require_once 'PHPExcel/PHPExcel.php';
$excel=new PHPExcel();
$excel->getProperties()->setCreator('Flora Sitinjak')
->setLastModified('Flora Sitinjak')
->setTittle('Laporan Pendapatan')
->setSubject('Pendapatan')
->setDescription('Laporan Semua Pendapatan')
->setKeywords('Data Pendapatan');
$exp=$excel->setActiveSheetIndex(0);
$exp->setCellValue('A1', "Tanggal");
$exp->setCellValue('B1', "EKS");
$exp->setCellValue('C1', "BIS");
$exp->setCellValue('D1', "EKO");
$exp->setCellValue('E1', "L.EKO");
$exp->setCellValue('F1', "Total");
$line=2;
$x=0;
for($i=1;$i<=$tgl[11];$i++){
$exp->setCellValue("A".$line, $i);
$carTL=count($arTL);
$gTGLO=substr($arTL[$x],-2);
if(empty($gTGLO)){
$x=0;
}else{
if($i==$gTGLO){
if(($x+1)>=$carTL){
$x=$carTL-1;
$exp->setCellValue("B".$line, $arLUEKS[$x]);
$exp->setCellValue("C".$line, $arLUBIS[$x]);
$exp->setCellValue("D".$line, $arUEKO[$x]);
$exp->setCellValue("E".$line, $arLEKO[$x]);
$exp->setCellValue("F".$line, $arTot[$x]);
}else{
$exp->setCellValue("B".$line, $arLUEKS[$x]);
$exp->setCellValue("C".$line, $arLUBIS[$x]);
$exp->setCellValue("D".$line, $arUEKO[$x]);
$exp->setCellValue("E".$line, $arLEKO[$x]);
$exp->setCellValue("F".$line, $arTot[$x]);
$x++;
}
}else{
$exp->setCellValue("B".$line, '-');
$exp->setCellValue("C".$line, '-');
$exp->setCellValue("D".$line, '-');
$exp->setCellValue("E".$line, '-');
$exp->setCellValue("F".$line, '-');
}
}
$line++;
}
$excel->getActiveSheet()->setTitle('Laporan');
$excel->setActiveSheetIndex(0);
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename="Data Laporan Pendapatan.xlsx');
header('Cache-Control: max-age=0');
$write=PHPExcel_IOFactory::createWriter($excel, 'Excel2007');
$write->save('php://output');
Every array like $arLUEKS[$x] is called from database and works, checked with echo
The output is a table with shows data a month from 1 to 31, if the data doesn't exist then it show a -
Anyone can solve this? please help me
I do not know what exactly could be wrong but here are some helpful things you can do that can help you identify your problem .
Turn on error reporting by adding these two to the top of your script
ini_set("display_errors",1);
error_reporting(E_ALL);
This may point you to the cause. Maybe the script is timing out or something
I'm new to PHPExcel, obviously.. I'm also pretty new to PHP in itself.
The website has multiple levels of authority for viewing/editing.
I've been working on a page for a website that gathers information stored in the SQL database and populates an excel template.
application.php contains all the database connections etc.
Basically, the problem I'm having is when I call on the array to populate cells it shows up as duplicates of the same array value. Not only that, but it crams them all onto the same column.
The Values I would need to populate are:
Part No. Description U/Price Q'ty Total
15666562003 Lamp Assembly $20.00 1 $20.00
Freight 131514 $12.35 1 $12.35
The data would show up like this:
Part No. Description U/Price Q'ty Total
Freight Freight 131514 131514 $12.35 $12.35 1 1 $12.35 $12.35
Any help would be much appreciated!!
<?php
include "./include/application.php";
require './Classes/PHPExcel.php';
error_reporting(E_ALL ^ E_NOTICE);
class CForm extends CApplication
{
function CForm()
{
$this->CApplication();
}
//**********************************************************
function Export($msg = "")
{
if ($_SESSION['aID'] == "" && $_SESSION['mID'] == "237" && $_SESSION['mID'] == "178" && $_SESSION['mID'] == "551")
{
$sWhere = " AND dID = '$_SESSION[mID]'";
}
$sql = "SELECT * FROM dl_warranty_claims
INNER JOIN dealers ON (dID = wDealerID)
WHERE 1 ".$sWhere." AND wID = '$_GET[id]'";
$res = $this->SQL($sql);
if (!($row = $this->FetchArray($res)))
{
print "You do not have access to view this report.";
exit();
}
error_reporting(E_ALL ^ E_NOTICE);
// Read the template file
$inputFileType = 'Excel2007';
$inputFileName = './templates/warrantyclaimtemplate2.xlsx';
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFileName);
// Adding data to the template
$objPHPExcel->getActiveSheet()->setCellValue('A3', ($row['wDealerName']));
$objPHPExcel->getActiveSheet()->setCellValue('B3', ($row['wID']));
$objPHPExcel->getActiveSheet()->setCellValue('C3', ($row['wCustomerName']));
$objPHPExcel->getActiveSheet()->setCellValue('D3', ($row['wModelName']));
$objPHPExcel->getActiveSheet()->setCellValue('E3', ($row['wChassisSN']));
$objPHPExcel->getActiveSheet()->setCellValue('F3', ($row['wEngineSN']));
$objPHPExcel->getActiveSheet()->setCellValue('G3', ($row['wDateDelivery']));
$objPHPExcel->getActiveSheet()->setCellValue('H3', ($row['wDateFailure']));
$objPHPExcel->getActiveSheet()->setCellValue('I3', ($row['wDateClaim']));
$objPHPExcel->getActiveSheet()->setCellValue('J3', ($row['wOperatingHours']));
$sql = "SELECT * FROM dl_warranty_parts
WHERE wpWarrantyClaimID = '$_GET[id]'";
$res = $this->SQL($sql);
while($rowp = $this->FetchArray($res))
{
$objPHPExcel->getActivesheet()->FromArray($rowp, NULL, 'A4');
}
// Write and save file
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.openxmlformats- officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename="warrantyclaimreport.xlsx"');
$objWriter->save('php://output');
}
}
?>
Your save statement
$objWriter->save('WarrantyClaim.xlsx');
is writing a file called WarrantyClaim.xlsx to disk (in the current working directory of your script).
Yet you have headers aying that you're going to send the output to the browser
Besides sending the correct headers for the filetype that you're writing:
Filetype Writer Content type
.xls Excel5 application/vnd.ms-excel
.xlsx Excel2007 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
saving to php://output will send the file to the browser
You also have a similar issue with your Reader: using the Excel5 Reader to read a .xlsx file when you should be using the Excel2007 Reader
For your latest question (please learn how to ask questions on SO, you don't simply edit a previous question when you have a new question, but should ask a new question)
Your $this->FetchArray() method appears to be returning both enumerated and associative data... I don't know exactly what the arguments are, but there should be some setting that allows you to specify either enumerated or associative, or a method call such as FetchAssoc() that will specifically return only an associative array
So I was hoping to be able to get by with a simple solution to read records from a database and save them to a text file that the user downloads. I have been doing this on the fly and for under 20,000 records, this works great. Over 20,000 records and I'm loading too much data into memory and PHP hits a fatal error.
My thought was to just grab everything in chunks. So I grab XX number of rows and echo them to the file and then loop to get the next XX rows until I'm done.
I am just echoing the results right now though, not building the file and then sending it for download, which I'm guessing I'll have to do.
The issue at this point succinctly is that with up to 20,000 rows, the file builds and downloads perfectly. With more than that, I get an empty file.
The code:
header('Content-type: application/txt');
header('Content-Disposition: attachment; filename="export.'.$file_type.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
// I do other things to check for records before, hence the do-while loop
$this->items = $model->getItems();
do {
foreach ($this->items as $k => $item) {
$i=0;
$tables = count($this->data['column']);
foreach ($this->data['column'] as $table => $fields) {
$columns = count($fields);
$j = 0;
foreach ($fields as $field => $junk) {
if ($quote_output) {
echo '"'.ucwords(str_replace(array('"'), array('\"'), $item->$field)).'"';
} else {
echo ''.$item->$field.'';
}
$j++;
if ($j<$columns) {
echo $delim;
}
}
$i++;
if ($i<$tables) {
echo $delim;
}
}
echo "\n";
}
} while($this->items = $this->_model->getItems());
Very large tables won't work that way.
You have to output the data as you read it from the database. If you need to sorted, then use the database ORDER BY for that purpose.
So more or less
// assuming you use a var such as $query to handle the DB
while(!$query->eof())
{
$fields = $query->read_next();
echo $fields; // with your formatting, maybe call a function...
}
The empty result is normal. If the memory is exhausted before any echo happens then nothing was sent to the browser.
Note also that PHP has a time limit (a watchdog) that you may need to tweak. The default is defined in your php.ini. You may set it to zero if you expect the tables to grow very much.
You should change your str_replace for addslashes(). This will probably free some memory.
Then I suggest you to save a file and use php file functions to do so: fopen() or file_put_contents().
I hope that might help you!
Actually, this might be simple fix. If PHP is running out of memory it's probably because the output buffer is filling before the file is sent. If so, simply flush() at regular intervals.
This will flush after each line:
do {
foreach(...) {
// assemble your output line here
}
echo "\n";
flush();
}
} while($this->items = $this->_model->getItems());
Flushing after each line might prove too slow, in which case add a counter and flush after every hundred, or whatever works best.
I have faced a problem whenever exporting a CSV file with PHP. I have a MYSQL query like
SELECT `interest_id`,`interest_name`,`interested_user_id` FROM `interest_list` WHERE `interest_name` LIKE '%fashion%'
But whenever I am trying to export one PHP file by making use of the above MySQL Query then my query is turning to
SELECT `interest_id`,`interest_name`,`interested_user_id` FROM `interest_list` WHERE `interest_name` LIKE 'úshion%'
SO that it returns no record.
Please tell me how can I solve the issue.
In the export file, I have written the code like:
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');
$output = fopen('php://output', 'w');
//executed code
fputcsv($output, $blankArray);
Now please help me.
Actually, I make the query in one file like:
$search_sql = "SELECT `interest_id`,`interest_name`,`interested_user_id` FROM `interest_list`";
if(isset($_REQUEST['search_user_btn'])){
if($_REQUEST['search_intr'] != '')
$search_sql .= " WHERE `interest_name` LIKE '%".$_REQUEST['search_intr']."%' ";
}
Then in the same file I write like:
<button>Export to CSV</button>
Finally In the export.php
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');
$output = fopen('php://output', 'w');
I am trying to get the value of $_REQUEST['qur']. But unable to get the original value of $_REQUEST['qur'].
I think Now it is making sense.
Please help....
You can't insert random strings in a URL because there're some characters that have a special meaning in URLs. In PHP, you can encode the value of a URL parameter with rawurlencode(). Similarly, you can't insert random characters in a HTML string for the same reason.
<?php
$url = 'export.php?report=interest&qur=' = rawurlencode($search_sql);
?>
<button>Export to CSV</button>
Whatever, passing SQL in the URL is call to get hacked.
I'm having a bit of trouble exporting a csv file that is created from one of my mysql tables using php.
The code I'm using prints the correct data, but I can't see how to download this data in a csv file, providing a download link to the created file. I thought the browser was supposed to automatically provide the file for download, but it doesn't. (Could it be because the below code is called using ajax?)
Any help greatly appreciated - code below, S.
include('../cofig/config.php'); //db connection settings
$query = "SELECT * FROM isregistered";
$export = mysql_query($query) or die("Sql error : " . mysql_error());
$fields = mysql_num_fields($export);
for ($i = 0; $i < $fields; $i++) {
$header .= mysql_field_name($export, $i) . "\t";
}
while ($row = mysql_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 = "\n(0) Records Found!\n";
}
//header("Content-type: application/octet-stream"); //have tried all of these at sometime
//header("Content-type: text/x-csv");
header("Content-type: text/csv");
//header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=export.csv");
//header("Content-Disposition: attachment; filename=export.xls");
header("Pragma: no-cache");
header("Expires: 0");
echo 'Download Exported Data'; //want my link to go in here...
print "$header\n$data";
In essence, you can't output the CSV file and the link to it in one go. (You need to introduce the concept of a page "mode" and activate the download mode via a ...pagename.php?mode=download or similar. You could then use PHP's switch statement to switch on $_GET['mode'] in your script.)
That said, the text/csv content type header you were using is correct, although you may also want to output the Content-Length and Content-Disposition headers. After you've output the file data, also be sure to stop any additional script processing via PHP's exit function.
Additionally, it would probably be a lot less hassle (and will certainly be faster/more memory efficient) to use MySQL SELECT ... INTO OUTFILE facility (if you have the permissions) rather than use PHP to gather the data.
You can't have text and a download on the same page. You need to have a link to the download area, which could just be a GET parameter leading to a function, which then does all the processing, displays headers, and echoes the content of the CSV.
For example, you could have Click here to download CSV, then in your code have if ($_GET['action'] === 'download'), get the data from the database, format it, send the headers, and echo the data. And then die(), because that part of the script can accomplish no more.
You should not put the link in the same file that generates the csv, as the link will not be in the csv itself!
Do something like:
Download CSV
and it should work
Three things to consider:
You're sending headers indicating that the user is going to be downloading a CSV file, but then you send create a link to download it? This isn't correct, you should be linking to this page, and then only outputting the CSV data itself after the headers.
MySQL has the ability to generate CSV output, and you should definitely take advantage of this instead of trying to do it yourself. You can use SELECT INTO ... OUTFILE to do this.
If you must create the CSV using PHP, please use fputcsv to do so. This will handle all the complications of CSV such as escaping and proper formatting. Since fputcsv writes to a file, you could either write it to a temporary file and then output it after you send your headers, or use the following trick to output it directly:
Do this after sending headers:
$fp = fopen('php://output', 'w');
while( $row = mysql_fetch_row( $export ) ) {
fputcsv($fp, $row);
}
I think the mySQL => CSV is common problem which is part of each PHP forum.
I have try to solve this issue in a common way and implement an free export
lib for PHP which is very similar to the Google AppInventor philosophie.
DragDrop and hide the coding stuff.
Use the lib and create your Export via Click&Point.
Common Demos: http://www.freegroup.de/software/phpBlocks/demo.html
Link to editor: http://www.freegroup.de/test/editor/editor.php?xml=demo_sql.xml
worth a look
Greetings
Andreas