下载的文件由Content-type标头而不是实际的文件内容组成

时间:2014-08-13 02:37:33

标签: php http-headers content-type

[NB。主要编辑:同样的问题,但有更多信息]

我正在尝试创建一个

的PHP脚本
  1. 生成.xlsx文件
  2. 邀请用户下载。
  3. 第1部分正常(服务器上生成的文件正确)。第2部分不是。

    我有两个文件来完成这项工作。第一个是XLSXExport.php,代码如下:

    <?php
    function exportDataToXLSX()
    {
       require_once(dirname(__FILE__)."/_inc/lib/PHPExcel/Classes/PHPExcel.php");
       require_once(dirname(__FILE__)."/_inc/lib/PHPExcel/Classes/PHPExcel/Writer/Excel2007.php");
    
       $outputFileName = 'query.xlsx'; //TODO hash pour le nom
       $outputFilePath = dirname(__FILE__).'/_store/'.$outputFileName;
       $outputFileType = 'Excel2007';
    
       //Creates a PHPExcel object
       $objPHPExcel = new PHPExcel();
    
       //– Les Données
       $objPHPExcel->setActiveSheetIndex(0);
       $activeSheet = $objPHPExcel->getActiveSheet();
       $activeSheet->setCellValueByColumnAndRow(1, 1, "Test");
    
       //– On sauvegarde notre fichier (Format Excel 2007)
       $objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
       $objWriter->save($outputFilePath);
    
       header("Content-Disposition: attachment; filename=\"" . basename($outputFilePath) . "\"");
       header("Content-Type: application/force-download");
       header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8');
       header("Content-Length: " . filesize($outputFilePath));
       header("Connection: close");
    
       @readfile($outputFilePath);
       exit();
    }
    
    exportDataToXLSX();
    ?>
    

    第二个文件只包含第一个文件:

    <?php
       require_once('XLSXExport.php');
    ?>
    

    当我启动第一个文件时,一切顺利:我被要求保存/打开一个xlsx文件,该文件在右侧单元格中有“Test”值。

    当我启动第二个文件时,我要求打开/保存的文件是一个损坏的文件,似乎是由发送的HTML标头组成的。

    输出文件的示例(不是精确地来自这个最小示例,但是来自原始文件的最小示例)可以在这里找到:https://mega.co.nz/#!HgpVDSAZ!tIYORzqX8GkFqiRQgWNTH_0J8zC0JyBfSLVejskqh-E

    代码有什么问题?

2 个答案:

答案 0 :(得分:1)

上次更新:

我想我设法重现了你的错误。这是我得到的错误

  

Excel无法打开文件'test.xlsx',因为文件格式或文件   扩展无效。验证文件是否已损坏   并且文件扩展名与文件格式匹配。

这是文件的内容;正如你所看到的,只是你得到的相同内容。

enter image description here

首先,制作两个全新的文件;来自此处http://ideone.com/GVVPVb的第一个副本的内容,而第二个文件的内容位于http://ideone.com/9rVueZ。首先不要添加任何其他行。运行它,一切都应该没问题。

换句话说,你可能在<?php之前或?>之后有一个空格,一个UTF-8字节顺序标记,可能是先前的错误,警告或通知,像{{{{} 1}},printprint_rechovar_dump代码之前的任何原始<html>区域或在<?php代码之前生成输出的任何内容


[以前的编辑]

尝试这样的事情(刚刚测试过)

<?php

也可以添加以下其中一项,但即使没有它们也可以使用

header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=\"" . basename($filename) . "\"");
header("Content-Type: application/force-download");
header("Content-Length: " . filesize($filename));
header("Connection: close");

@readfile($filename); // or try echo $filename; 
exit();

您可以添加以下内容以防止从cashe(IE case)加载

header("Content-Type: application/octet-stream");
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8');

编辑:

由于您的输出实际上是CSV文件,因此可以使用header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 来构建它

fputcsv()

答案 1 :(得分:1)

问题可能是因为apache / php在标题之前向浏览器发送“somethings”。 你在php标签之前/之后的第二个文件中有空字符吗?

您应该查看您的error_log,检查是否有关于无法发送标头的php投诉。

此外,如果打开output_buffering,请尝试将其关闭(如果打开,php将不会对标头之前的输出提出异议,但是“空”字符将在标头之后发送,导致文件出现损坏下载)