Asked  7 Months ago    Answers:  5   Viewed   40 times

I'm struggling with an odd error. I have a simple web app that grabs stuff from a DB then outputs it as a downloadable csv file. It works on firefox and chrome, but IE fails to recognize it as a csv file (thinking it is a html fle) and when I click save I get the error, "Unable to download {name of file} from {name of site}. Unable to open this internet site. ..."

Code:

session_start();

//some logic goes here...  

//generate csv header  
header("Content-type: application/octet-stream");  
header("Content-Disposition: attachment; filename=exportevent.csv");  
header("Pragma: no-cache");  
header("Expires: 0");  

echo "Event: " . $event_title . "n";  

//print the column names  
echo "Last Name, First Name, Company n";  

while($row = mysql_fetch_assoc($result))  
{  
    echo $row['atlname'] . ',' . $row['atfname'] . ',' . $row['atcompany'] . "n";      
}

I've played around with the content-type a whole bunch, but that had no effect.

Update: I've tried text/csv, application/vnd.ms-excel (and variations of this), text/plain, and some others that I now forget with no luck.

This is IE8 btw.

Update 2: The connection is over SSL.

 Answers

59

Don't we love IE? :)

Try using those headers:

  header("Pragma: public");
  header("Expires: 0");
  header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  header("Cache-Control: private",false);
  header("Content-Type: application/octet-stream");
  header("Content-Disposition: attachment; filename="exportevent.csv";" );
  header("Content-Transfer-Encoding: binary"); 

I think that the octet-stream content type forces IE to download the file.

Wednesday, March 31, 2021
 
Magnanimity
answered 7 Months ago
17

just use File.getName()

File f = new File("C:\Hello\AnotherFolder\The File Name.PDF");
System.out.println(f.getName());

using String methods:

  File f = new File("C:\Hello\AnotherFolder\The File Name.PDF");  
System.out.println(f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf("\")+1));
Wednesday, June 9, 2021
 
turson
answered 5 Months ago
21

Make sure your rvm is up to date: rvm get latest

And then run this: rvm uninstall 1.8.7 && CC=/usr/bin/gcc-4.2 rvm install 1.8.7

Basically you must tell rvm which gcc compiler to use (CC=/usr/bin/gcc-4.2)

Then you should be able to install the pg gem as normal.

Monday, August 2, 2021
 
Mike
answered 3 Months ago
12

This is my solution in case someone else is looking for a solution. now it works with FF, Chrome , and IE

var csv = JSON2CSV(json_obj);            
var blob = new Blob([csv],{type: "text/csv;charset=utf-8;"});

if (navigator.msSaveBlob) { // IE 10+
navigator.msSaveBlob(blob, "csvname.csv")
    } else {
        var link = document.createElement("a");
        if (link.download !== undefined) { // feature detection
            // Browsers that support HTML5 download attribute
            var url = URL.createObjectURL(blob);
            link.setAttribute("href", url);
            link.setAttribute("download", "csvname.csv");
            link.style = "visibility:hidden";
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }           
    }

Now I just need to figure out if there is a way to have the save as screen pop up instead of automatically saving the file. If anybody knows the answer to that please share. For now my users will have to use this functionality.

Thanks all for all the great answers, you guys are awesome.

Monday, August 2, 2021
 
Atomble
answered 3 Months ago
54

I think you might need a space after attachment;:

header("Content-Disposition: attachment; filename=$filename");

If that doesn't work, check out some of the points in this article, including:

  • On IE 6.0, things mostly work, but if you ALSO setup Cache-Control: no-cache, your suggested filename (and type!) will be IGNORED. A bummer if you have to choose between security and convienence. Of course, security wins.
  • On nearly all versions of IE, including 6.0, sometimes the browser will use the filename in the address bar instead of the Content-Disposition Header, and with IE5.5SP2 you're expected to change the UseCDFileName registry key, see Q303750. This was fixed with IE6.0SP1.

EDIT: Here's the code I use, directly copied from my application's source. Let me know if this works any better...

function forceDownload($filename,$mime=false,$downloadName=false)
{
    if(file_exists($filename) && is_readable($filename))
    {
        if(!$mime)      $mime = DFStdLib::determineMimeType($filename);

        if(!$expire)    $expire = DFStdLib::HOUR_IN_SECONDS;

        if(!$downloadName) $downloadName = basename($filename);

        header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($filename)).' GMT', true, 200);
        header('Cache-Control: no-cache',true);
        header('Pragma: Public',true);
        header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT',true);
        header('Content-Length: '.filesize($filename),true);
        header("Content-Type: {$mime}",true);
        header("Content-disposition: attachment; filename=$downloadName",true);
        readfile($filename);
        exit();
    }
    else
    {
        header('HTTP/1.1 404 Not Found',true,404);
        echo "<html><head><title>Not Found</title></head><body>The file was not found.</body></html>";
        exit();
    }
}

Usage for your case would be:

forceDownload('/example.pdf','application/pdf','quickquote.pdf');

Also you'll need to change DFStdLib::HOUR_IN_SECONDS to 3600 and write your own determineMimeType function, or delete that line and make the $mime argument required...

Thursday, August 5, 2021
 
pocketfullofcheese
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :