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.
Related
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.
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');
I have a process where customer clicks if he wants a report to be generated and downloaded while creating a business unit. This report will be in pdf format.
Currently I am using Codeigniter and I use FPDF to generate pdf files.
The pdf opens well when it is requested. But
Problem:
1) PDF opens in the same tab. I would like the pdf to open up in new tab which I am kind of thinking how.
"_target" will help me open the pdf in new tab if it is a pdf link. But here it is server side generated pdf. Hence "_target" will not work so I am looking for alternative on this.
2) After the pdf generates, the next line of code is not read. The execution actually stops here. I would like to know how I can make the process continue even after outputting pdf file.
Example
$pdf->Output($exampleArray, 'D'); // exampleArray carries all data to PDF and helps output the pdf and D forces FPDF to download PDF rather than opening it. Instead of 'D' I can use 'I' but that will output the pdf in same tab.
$this->continueNextFunction(); // This function should run and open the views in it.
From the above example I would love to see either PDF downloaded or 'opened in new tab' followed by next line executed helping the page to redirect and open required views.
Also please let me know if further explanation is required. I tried my best to explain the situation here. I had looked on this over google but I have not really found any solution on this.
Any help regarding this will be greatly appreciated.
You should create the new tab before running the FPDF code.
Alternative you can save the pdf as a file and open a new tab with the correct header.
see this question: Show a PDF files in users browser via PHP/Perl
The code terminates with output by design, unless you save it to file or string.
$pdf->Output($filename,'F');
If you could elaborate on what you want to do after the output i might be able to help more.
Here is what we are doing and some thoughts:
The Output() method takes 2 arguments, name and dest. You are sending an array in for the name parameter, probably not what you want. The second, dest, will use the "D" as you have specified.
Output() sends headers and the data depending on the value you specify for dest. See below.
What that means is if you want to continue executing code, you are likely going to need to separate out the logic that generates this PDF into a new page, open that in the new tab using target="_new" like you were thinking, which then prompts the user to download or in that case you can use the "I" value and open it within the browser.
Output() from fpdf.php [lines 999-1036]:
switch($dest)
{
case 'I':
// Send to standard output
$this->_checkoutput();
if(PHP_SAPI!='cli')
{
// We send to a browser
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="'.$name.'"');
header('Cache-Control: private, max-age=0, must-revalidate');
header('Pragma: public');
}
echo $this->buffer;
break;
case 'D':
// Download file
$this->_checkoutput();
header('Content-Type: application/x-download');
header('Content-Disposition: attachment; filename="'.$name.'"');
header('Cache-Control: private, max-age=0, must-revalidate');
header('Pragma: public');
echo $this->buffer;
break;
case 'F':
// Save to local file
$f = fopen($name,'wb');
if(!$f)
$this->Error('Unable to create output file: '.$name);
fwrite($f,$this->buffer,strlen($this->buffer));
fclose($f);
break;
case 'S':
// Return as a string
return $this->buffer;
default:
$this->Error('Incorrect output destination: '.$dest);
}
How can I open and view a .doc file extension in my browser? The file is located on my server.
Two options: First is to just link to it, e.g. My Word Document, the second is to use an iframe and point it to the document. For this to work, however, most browsers require that the server sends a Content-disposition: inline header with the document. If you cannot configure your web server to do this, you can wrap the document in a bit of php:
<?php
header('Content-disposition: inline');
header('Content-type: application/msword'); // not sure if this is the correct MIME type
readfile('MyWordDocument.doc');
exit;
And then link to that script instead of your word document.
This isn't guaranteed to work though; the content-disposition header is just a hint, and any browser may choose to treat it as an attachment anyway.
Also, note that .doc isn't exactly portable; basically, you need Word to display it properly (Open Office and a few other Open Source applications do kind of a decent job, but they're not quite there yet), and the browser must support opening Word as a plugin.
If the .doc file format requirement isn't set in stone, PDF would be a better choice (the conversion is usually as simple as printing it on a PDF printer, say, CutePDF, from inside Word), or maybe you can even convert the document to HTML (mileage may vary though).
…
You will need a browser with a plugin for Office documents installed. I believe Microsoft Office will install one for at least Internet Explorer by default.
If you want to work without a plugin, then you will need to convert the document to another format — HTML for maximum compatibility. This isn't a trivial operation, especially for complex documents (or even those which just contain images).
$file = "$file_name.doc";
$len = filesize($file); // Calculate File Size
ob_clean();
header("Pragma: public");
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-Type:application/zip"); // Send type of file
$header="Content-Disposition: attachment; filename=$patient_name.zip;"; // Send File Name
header($header );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".$len); // Send File Size
#readfile($file);
You can use google docs instead as it is free and reliable
You can assign your file path to iframe.
e.g. iframe1.Attributes.Add("Src", "http://docs.google.com/gview?url=http://YOUR_FILE_PATH&embedded=true");
If your .doc file is accessable online, you can try Office Web Viewer service.
If your documents stored in Intranet, you can use Microsoft Office Web Apps Server. It allows users to view Word, PowerPoint, Excel documents via browser.
//Edit
$header="Content-Disposition: attachment; filename=$file_name.doc;"; // Send File Name
I want to read the pdf documents and display the content to the browser, without allowing the users to save a copy of the pdf.
How can i use fpdf for this purpose? So far, i could not figure out a way of reading a pdf document with fpdf, apart from creating a new pdf. Can anyone suggest an example of reading a pdf file, and if possible, how to disable the save as pdf option?
fpdf can't read pdf's. take a look at it's FAQ - 16 an 17 sound interesting and it loooks like there are addons to do this.
what you really can't ever avoid is to let the user save that pdf - it has to be sent to the browser at the clients machine, to display it, so there will always be a possibility to save it. a possibility would be to transform every page of the pdf to an image (using Imagemagick for example) and oly display these images, so the user can't copy the text from it and has no possibility to get the original pdf-document - but that will only annoy people.
If you have an existing PDF you want to display it inline rather than ask them to download it:
// Path to PDF file
$file = "blah.pdf";
// Show in browser
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit();
You don't need to use FPDF that's only a class that helps you create PDF's from scratch.
Also bare in mind there is nothing to stop a user from saving a PDF even when displaying inline.
Im not sure if this is possible, check the FPDI extension for FPDF here: http://www.setasign.de/products/pdf-php-solutions/fpdi/
To convert a pdf to html there a program for linux called pdftohtml. However be aware that the result of this will not create something that looks like the original pdf and in many cases (locked pdf's etc) it will fail. What is a possible solution is generating an image of each page using a program like ImageMagick, then place the html over on an invisible layer to allow for interaction. I'd still rather go for displaying the pdf inline if I were you though.