I'm no php expert (a mere beginner) but need some help!
After hours searching Google and trying out about 100 different scripts, I finally found one that does what I need - almost.
Basically, my site has a button marked 'Export to Excel'. Visitor to site clicks button and a download begins containing all data from a specified table.
I found this on here - PHP code to convert a MySQL query to CSV
which does exactly what I want except the user sees the following error when trying to open the file:
Error - 'The file you are trying to open, 'export.xls', is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Wo you want to open the file now?'
User clicks 'Yes' and file opens with all data! Brilliant! Except users will not open the file with this error.
I would be very grateful if someone knows a way to fix this.
Many thanks
TT
Or, you could just change the script in the above solution to return a file with the .csv extension. .csv files are associated with Excel, so they should open directly.
Ok, this results from a feature specified by Excel 2007 called Extension Hardening. You can turn it off, but that can only be done client-side. If you click "OK" or "Yes" the file should open anyway. Check this blog post for more info.
EDIT: What this means is that Excel is finding that the file is of a different type (say HTML or CSV) that what is specified by the file extension. Therefore Excel wants to warn you that this file is not what it says it is. Unless you are going to create native Excel files on the server then prompt the user to download them, there is no getting around this error except for each user to turn off Extension Hardening on their own computer.
if you make the first letters “ID” of a text file Excel incorrectly
assumes you are trying to open an SYLK file.
Meaning if the first row & column value is "ID", Excel will throw this warning. Just change it from "ID" to anything else.
Credit: http://alunr.com/excel-csv-import-returns-an-sylk-file-format-error/
Dim objXL As Excel.Application
Dim objWkb As Excel.Workbook
Set objXL = New Excel.Application
'turn off excel warnings
objXL.DisplayAlerts = False
'Open the Workbook
Set objWkb = objXL.Workbooks.Open(fpath)
functions sendFile($filename,$content_type="application/ms-excel") {
header('Content-type: '.$content_type);
header('Content-disposition: Attachment; filename=' . $filename);
readfile($filename);
}
I had the same problem so I looked at the following link: PHP code to convert a MySQL query to CSV
I modified one of the answers to get the headers to work.
include('DBFILE.PHP');
$select="SELECT * FROM SOMETable";
$result = mysqli_query($conn, $select);
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
//This is what I changed...
$headers ="";
while ($property = mysqli_fetch_field($result)) {
$headers.= $property->name.",";
}
$headers.="\n";
//////
$fp = fopen('php://output', 'w');
if ($fp && $result) {
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="export.csv"');
header('Pragma: no-cache');
header('Expires: 0');
fputcsv($fp, $headers);
while ($row = $result->fetch_array(MYSQLI_NUM)) {
fputcsv($fp, array_values($row));
}
die;
}
I Tested this and it works like a charm, you just need to add your db connection or include the db.php file that you have.
you can change the name of the file if you edit the following line
header('Content-Disposition: attachment; filename="export.csv"');
Change export to what ever name you like.
Related
This is one I just can't figure out: I have successfully built an upload feature on a web page to upload files to a MySQL Database. When I go on the server and open them via phpMyAdmin, they all look fine... txt, jpg, pdf, etc.
Yet, after putting together THIS thing (below) to download it, I get a strange problem: All of the text documents (and all other types of files, after I change the extension to 'txt') contain HTML code of the page itself, followed by the original content!
Also, different browsers display differently after the POST. When trying to download a txt file, IE will show the correct data in the ECHO on the page itself (no downloading) with an error message just before it:
Warning: Header may not contain more than a single header, new line detected. in C:\wamp\www\ace\dmain.php on line 82.
Line 82 is 'header("Content-length...'
Neither Firefox nor Chrome show anything. They just allow me to download it.
Here's the code:
<?php
if (isset($_POST['downloadid'])) {
$fileid = $_POST['downloadid'];
try {
$sql = "SELECT * FROM `datastore` WHERE `id` = '".$fileid."'";
$results = $pdo->query($sql);echo $sql;
while ($row = $results->fetch()) {
$filename = $row['filename'];
$mimetype = $row['mimetype'];
$filedata = $row['filedata'];
header("Content-length: strlen($filedata)");
header("Content-type: $mimetype");
header("Content-disposition: download; filename=$filename"); //disposition of download forces a download
echo $filedata;
// die();
} //of While
} //try
catch (PDOException $e) {
$error = '<br>Database ERROR fetching requested file.';
echo $error;
die();
} //catch
} //isset
?>
This:
header("Content-length: strlen($filedata)");
Is not going to produce what you expect. If you look at the headers in wireshark, or another method to view the request you will see that it does not contain an integer.
Use this instead:
header("Content-length: ".strlen($filedata));
After agonizing over fixing it in-place (that is, on the same page with the rest of the html and code), I decided to move it to a dedicated PHP page. After that, it worked fine.
Thanks for the comments!
here is good example and complete source
I am working on a web application (php, javascript, html) that holds a large amount os user information. It is designed for temporary jobs.
The thing is, I have three tables (mysql) with information about the users. One for the address and other things, other for driver license, certificates, ..., and the last one for user experience.
What I want to do, is have a "print" button that generates a txt file with all that data in one file. The thing is that I alredy have an idea of how to do it.
1) retrieve all the information for the tables in a join with username.
2) I already had the function to "resource_to_array" for building an array with all the data
3) I could just go for each column of the array and saving the information that I want
But what I am asking is for experience doing something like this. This is the first time for me, and I want it to make it good and scalable for the future.
How will be a good way to do implement it? also, how could I create a plain text with all that information? (this part is in where I have more doubts about)
I know that maybe is a weird question..but I do not want code, I just want a vision for the implementation. Also, is there is a library os something similar that do what I want to do
Thank you very much.
First of all make a link that will generate text file.
Print
Now, in print.php you have to put your logic.
Execute the join Query for fetching the data.
Fetch "array" for building an array with all the data.
Get the element from the array that you want to save in text file.
Now logic is here, Use file handling for creating the text file with save data.
Logic is here(print.php) :
<?php
$conn = new mysqli("host-name","username","password","database-name");
$query = "....";
$result = $conn->query($query);
$rs = $result->fetch_array(MYSQLI_BOTH);
while($rs = $result->fetch_array(MYSQLI_BOTH))
{
$data = $rs['column-name']; // data you want to save in text file
$f = fopen("save.txt", 'a');
fwrite($f, $data);
fclose($f);
}
$filename = "save-data.txt"; // name of the file you want to download on clicking the link
$file = "save-data.txt";
$type = filetype($file);
// Send file headers
header("Content-type: $type");
header("Content-Disposition: attachment;filename=$filename");
header("Content-Transfer-Encoding: binary");
header('Pragma: no-cache');
header('Expires: 0');
// Send the file contents.
set_time_limit(0);
readfile($file);
?>
Sidenote: The a switch appends to file. If you do not wish to keep adding to it, use the w switch:
$f = fopen("save.txt", 'w');
I hope it will help you.
So the process that I have goes like this. A user can pick a date range to view the data that he wants/needs. A Download is then available if he wants to download the file.
When doing a wide range the page throws off a connection error.
Firefox - The connection was reset
Chrome - No Data Received
The code that I use to generate the CSV is
<?php
$res = // the array generated by a mysql query
$text=strtotime("Now");
$filesave=fopen('Downloads/CallLogs'.$text.'.csv','w');
foreach ($res as $display)
{
fputcsv($filesave,$display);
}
//Force download the file. you can correct me if this is the improper way of doing it :)
header('Content-Type: application/download');
header('Content-Disposition: attachment; filename="CallLogs'.$text.'.csv"');
$fp = fopen("Downloads/CallLogs".$text.".csv", "r");
fpassthru($fp);
fclose($fp);
?>
Thanks in advance...
Is it possible to export a PHP MySQL Excel sheet to a specified path such as USB Flash Drive.
Its because I'm using php as Point of Sale and all What i want now is once you click on a Button- it will collects records from MySQL database and exports it as excel or csv file to a USB Flash Drive.
I've tried to Google it out, but I can't seem to find anything.
Thank You.
You need to write the file. To write to usb drive you just need to specify correct file path. If you're on *nix it would be like /media/USB/ on linux or /Volumes/USB/ on Mac. For Windows it would be like F:/.
so rough example is like
$a = array('1','2','3'); //This is imaginable row from MySQL
$f = fopen('F:/mycsv.csv', 'w');
fputcsv($f, $a);
fclose($f);
Manual for fputcsv is here.
If needed, you can ask user for a file path in any way supported by your application.
Not a simple process to save it as excel, but relatively straightforward to write a csv.
$temp = tempnam(sys_get_temp_dir(),'tmp');
$handle = fopen($temp,'w');
$query = $pdo->prepare("select * from table");
$query->execute();
$row=$statement->fetch();
$keys=array_keys($row);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename=export_'.date('dmY').'.csv');
fputcsv($handle,$keys);
while($row){
fputcsv($handle,$row);
$row=$statement->fetch();}
echo file_get_contents($temp);
fclose($handle);
This creates a temporary file in your temp folder, you write the csv to that and then give it csv headers and echo it out which gives the user a save file box.
I call $row once before the loop to get the table columns with array_keys and output those first and then loop through with a while calling $row=$statement->fetch() at the end of the loop.
I have installed PEAR, Spreadsheet_Excel_Writer and OLE. The sample program is executed successfully but when I try to read the file it shows garbage values. I also tried $workbook->setVersion(8); and $worksheet->setInputEncoding('UTF-8');
I am using this tutorial and Google lot for this problem.
http://www.sitepoint.com/article/getting-started-with-pear/3/
Thanks in advance.
I try to use PEAR only when I really need to...you can easily generate an excel spreadsheet( assuming it's just data) with something like this:
$header = "Last Name\tFirst Name\tAge\tJob\n"; // new line is start of new row, tab is next column
//ideally you would get this from a DB and just loop through it and append on
$row1 = "Smith\tBob\t25\tManager\n";
$row2 = "Anderson\tTrent\t32\tCEO\n";
$excel = $header.$row1.$row2;
$xlsfile = "excel_example".date("m-d-Y-hiA").".xls";
header('Content-type: application/vnd.ms-excel');
header("Content-Disposition: attachment; filename=$xlsfile");
echo $excel;
that's just a tab seperated value file though and you're sending headers suggesting the browser treat that data as an excel file. so there's no formatting of data which the poster may require.