Download Excel file from database in PHP - php

I have a MariaDB database on a site I am making. In this database, I have a bunch of Excel files that are available for download. For simplicity, lets say I have 5 files. The first named 1.xls, the second named 2.xls, and so on.
How can I force a download from the database if a user types the text 4.xls into a form, then clicks a button? Thanks!

To force the download of your file, link to downloadfile.php?filenum=num
This will be the code in downloadfile.php:
header('Content-Type: application/xls');
header('Content-Disposition: attachment; filename='.$_GET[filenum].'.xls');
header('Pragma: no-cache'); //if the file change, user will always download the last version
readfile('/path/'.$_GET[filenum].'.xls');

Related

Trigger an action when a certain file URL is downloaded

I would like to trigger an action when Apache detects that a certain file URL has been started for download (or: successfully downloaded).
Example: when https://example.com/download/token_A6FZ523/myfile.zip is downloaded by a client, execute the following query to a SQLite database:
INSERT INTO downloads(date, tokenID) VALUES(CURRENT_TIMESTAMP, "A6FZ523");
Usage: then, in a PHP Dashboard, I can check who has downloaded the delivered files.
I could do this by:
running a script every minute on the server,
parsing the Apache logs /var/log/apache2/other_vhosts_access.log in search for a pattern download/token_.*/myfile.zip
execute the INSERT INTO query in this case
This seems rather complex and the fact of having to run the script every minute is not a nice solution.
What is a good solution to ask Apache to save to a SQLite database the information "The file associated to download token A6FZ523 has been downloaded by the client."?
Or maybe should PHP be used instead?
I think your problem lies in that you are directly fetching a file that is stored on the server, as opposed to using PHP to "serve" this file programatically. This isn't the first problem you will encounter with this method, you also can't check for security or get the file from external file storage (generally speaking, you don't store files directly on the web server these days!).
But, simple to do once you know how :)
Firstly, lets change the URL you download your file from to something like https://example.com/download.php?token=A6FZ523
So, we are sending a GET variable to a php script named "download.php". In that script you will have something like the following:
<?php
$token = $_GET['token'];
// Get the information about the file from the DB, something like:
// SELECT filename, size, path FROM files WHERE token = $token;
// Giving you $filename, $size and $path
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $filename);
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . $size);
echo file_get_contents($path);
// This will be on a completed download
// INSERT INTO downloads(date, tokenID) VALUES(CURRENT_TIMESTAMP, $token);
?>
When the download.php file is called, the token is taken and matched to a file's info in the DB. You then set headers which basically tells the browser "this is a file", your browser responds accordingly by implementing a file download as normal. You then read the contents of the file to the user. Once this has been completed, you can log the download via another DB call.
A big thing to say is that this script (obviously with the DB calls written in) should do the very basics for you, but there is a lot more to add depending on your usage scenario. Think security, input validation, where you store your files and sending a MIME type header.
Hopefully that should point you in the right direction though :)
If you have access to server and authority to install thins you could add mod_log_sql and have the apache save the log directly into a database table (it even parse the info for you) them in your dashboard you can just do simple queries. The "thing" here it seams that you are in need to get the name of the downloader, therefore you should add that "tokenID" to your URL and set the Apache to deny the url if tokenID is not present. You would need to parse the tokenID from url in the log thought.

PHP Postgtres Generate CSV File for Download

I have a postgresql database table and using PHP for the backend. On the user interface, I provide users with a way of generating reports. What I want to do is that when a user wishes to generate a report, a CSV file should be provided for download.
I already know how to generate a CSV file for results of a query, but now in this case I don't want the file to be saved on disk. Instead, it should be downloaded by the browser.
You simply need to provide a page for download...
#downloadCSV.php?reportID=1
header('Content-Type: text/plain');
header('Content-Disposition: attachment; filename="yourfile.csv"');
// do your postgresql query and put the result into $csv
echo $csv;
In this way you don't have to create a real file on your server
The second header Content-Disposition: attachment; forces the browser to download a file instead to show the content in a page

Rename a file with PHP right before it downloads without saving it to the server?

I have an Adobe Illustrator file (AI) that we currently have a link to on a website which then downloads the file to your computer.
The link looks something like this...
http://domain.com/crm/index.php?entryPoint=fileupload_download&id=22440435-e8ee-bd6f-7612-533b2cd7690f&field=fuaifile_c&type=D1_Designs
What I need to do is rename this file as it downloads.
So I am asking if it is possible to pass this download through another PHP file right before it downloads which would allow me to change the filename on the fly that the user downloads. I cannot change the filename on the server but when it downloads I would like to be able to add some ID numbers to the filename on the fly if this is possibble? Any ideas how to accomplish this without having to resave the image on the server with a new name?
What you are looking for is the Content-Disposition header, as specified in RFC 2183:
Content-Disposition: attachment; filename=example.ai
You can set this header using the PHP header() function.
It's ugly, and assumes these aren't "large" files that would exceed your memory_limit, but
$data = file_get_contents($original_url);
header('Content-disposition: attachment; filename="new name with id numbers');
header("Content-type: application/octet-stream");
echo $data;
You could always enhance this to do byte serving - suck 10k from original url, spit out 10k to user, etc...
Just set the Content-Disposition:
header('Content-Disposition: attachment; filename="downloaded.pdf"');
(Example taken from PHP docs: http://www.php.net/manual/en/function.header.php).
Adding id:
$id = generateIdFromSomewhere();
header('Content-Disposition: attachment; filename="downloaded'.$id.'.pdf"');

Print word files with PHP

I am using PHP to create a program to accept data from a form and then create 20 different DOC files which can be downloaded on click. I have done all this and if you click the usrl to 20 files, it gives pop up to save this files as word files. Now I am working on printing all these files using one click from the program itself without saving them. This data comes from DB so it is dynamic. Is it possible to print these word files using one click. Also some documents can have multiple copies.
You can't print Word files directly from browser unless user has a word processor extension for browser like Zotero. An other option is to convert your doc file to PDF, HTML or image format. wvWare is a software you can do this with. see: http://wvware.sourceforge.net/
To create word files with PHPWord. see: http://phpword.codeplex.com/
With this you can save your doc(x) files and add the links to your php page.
Or you can directly download file when opening a PHP page by creating custom headers:
<?php
header('Content-Type: application/vnd.ms-word');
header('Content-Disposition: attachment;filename="myfile.docx"');
header('Cache-Control: max-age=0');
// Code that generates DOC
// output the file to the browser
$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007');
$objWriter->save('php://output');
exit;
?>
See forum thread here: https://phpword.codeplex.com/discussions/225901
One Top of your php or any html code
<?php
header("Content-Type: application/vnd.ms-word");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("content-disposition: attachment;filename=Report.doc");
?>

Dynamic creation of a doc/docx document on the users desktop

My site is HTML/Javascript with AJAX calling server-side PHP. I want to allow the user to click an icon and create a report from MySQL data and then save this on the client's desktop without doing a page reload.
Options for creating a doc, as I can gather it, appear to be as follows. (I gather it needs to be done server-side, rather than with Javascript.) I'm not sure where the file ends up in each case. Please feel free to correct my misunderstandings :)
Method 1 - this appears only to create a .doc file. I'm not sure where the file gets put.
$fp = fopen("method1.doc", 'w+');
$str = "<B>This is the text for the word file created through php programming</B>";
fwrite($fp, $str);
fclose($fp);
Method 2 - this also appears to create a .doc file.
$word = new COM("word.application") or die ("couldnt create an instance of word");
echo "loaded , word version{$word->version}";
$word->visible = 1;
$word->Documents->Add();
$word->Selection->TypeText("Sample text.");
$word->Documents[1]->SaveAs("method2.doc");
$word->Quit();
$word->Release();
$word = null;
Method 3 - also a .doc file, I think.
header('Content-type: application/vnd.ms-word');
header("Content-Disposition: attachment;Filename=method3.doc");
echo "<html>";
echo "<body>";
echo "<b>My first document</b>";
echo "</body>";
echo "</html>";
Method 4 - PHPWord
Method 5 - PHPDocx
I've tested 1 & 2 in my home dev environment, but I can't find the files! What's the best way forward, please?
Thanks :)
BTW, I know there are relevant posts here, here and here, but none really answers the question.
If you want to have an icon, and when the icon is clicked it makes a download without page reload, then you just have to make a link to the icon that bring to a script that start a download using the appropriate headers.
Example :
header ('Pragma: no-cache');
header('Content-Disposition: attachment; filename="'.$File.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: public');
header('Content-Description: File Transfer');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.$Len);
Doing this, the download will start, but the page where the user has clicked will not be changed, neither reloaded.
If you want to generate dynamic DOCX files to be downloaded, I recommend to use OpenTBS. This library can generate a DOCX (and XLSX, PPTX, ODT, ODS, ...) using templates. It has a function that let you send the result directly as a download, without temporary files, or let you save is in the server side.
Methods 1 & 2 create document on the server side somewhere in filesystem (after that you need to transfer it to the client).
Method 3 creates document as a response to client request - depending on settings browser will either save it or open in window (or ask 'Save/Open/Cancel?').
I personally would have made java applet or flash application which will have access to your local filesystem. It can load document from server and save to local file system without page reloads.

Categories