【问题标题】:PHP downloading excel file becomes corruptPHP下载excel文件变得损坏
【发布时间】:2012-02-23 10:27:44
【问题描述】:

我有一个 Excel 文件,我希望用户能够从我的服务器下载该文件。我在这里查看了很多问题,但我找不到正确下载文件而不会损坏的方法。我假设它是标题,但我还没有它们的有效组合。这就是我现在拥有的,在我收到的损坏文件中,我可以看到我想要的电子表格的列名,但它都搞砸了。

$filename = '/var/www/web1/web/public/temporary/Spreadsheet.xls';        
header("Content-type: application/octet-stream");
header("Content-type: application/vnd-ms-excel");
header("Content-Disposition: attachment; filename=ExcelFile.xls;");
header("Pragma: no-cache");
header("Expires: 0");
readfile($filename);

编辑:解决方案我忘了补充说我正在使用 Zend,并且在尝试使用本机 php 方法时它损坏了文件。我完成的代码是在我的控制器中放置一个指向另一个操作的链接,并从那里下载文件

public function downloadAction(){
        $file = '/var/www/web1/web/public/temporary/Spreadsheet.xls';
        header('Content-Type: application/vnd.ms-excel');
    header('Content-Disposition: attachment; filename="Spreadsheet.xls"');
    readfile($file);

    // disable the view ... and perhaps the layout
    $this->view->layout()->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);


    }

【问题讨论】:

  • 下载我猜你的意思是在浏览器中显示?而不是直接下载文件
  • 输出 2 个内容标题是没有意义的——一个文件不能同时是两个东西。这就像在说“我是长颈鹿和鲸鱼!”。
  • 很长很长的路要走,对这类问题最常见的答案是:a) 在<?php ?> 标签之前/之后有前导/尾随空格/HTML您的脚本或文件中的 BOM,或者 b) 您忘记在 readfile() 之后调用 exit/die 并且在文件数据的末尾输出了更多内容。
  • @MarcCostello 我的意思是直接下载。
  • @DaveRandom 我在声明中遗漏了一个退出,这将阻止我将文件放在一起,但文件仍然损坏。

标签: php excel download corrupt


【解决方案1】:
$file_name = "file.xlsx";

// first, get MIME information from the file
$finfo = finfo_open(FILEINFO_MIME_TYPE); 
$mime =  finfo_file($finfo, $file_name);
finfo_close($finfo);

// send header information to browser
header('Content-Type: '.$mime);
header('Content-Disposition: attachment;  filename="download_file_name.xlsx"');
header('Content-Length: ' . filesize($file_name));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

//stream file
ob_get_clean();
echo file_get_contents($file_name);
ob_end_flush();

【讨论】:

  • 如何获得 finfo_open 功能?我必须下载任何文件?如果是,请分享链接? @Bhavesh Gangani
  • @lalithkumar finfo_ 函数内置于PHP >= 5.3.0
  • 哦,我的是版本问题..谢谢@Bhavesh Gangani
  • 更新 php 版本后,我在 php.ini 中添加了 ;extension=fileinfo.so。它适用于我。
【解决方案2】:

对于一个,只指定一次Content-Type。您可以使用excel-specific header,但通用的application/octet-stream 可能是更安全的选择,只是为了让它正常工作(真正的区别在于浏览器向用户显示的“你想用什么打开这个文件”,但基本浏览器也可以依赖扩展)

另外,请确保您指定 Content-Length 并转储您正在输出的文件的大小(以字节为单位)。浏览器需要知道文件有多大以及它期望接收多少内容(因此它不会在中间停止或打嗝不会中断文件下载)。

所以,整个文件应该包括:

<?php
  $filename = '/var/www/web1/web/public/temporary/Spreadsheet.xls';

  header("Content-Disposition: attachment; filename=ExcelFile.xls;");
  header('Content-Type: application/octet-stream');
  header('Content-Length: ' . filesize($filename));
  header("Pragma: no-cache");
  header("Expires: 0");

  @readfile($filename);

【讨论】:

  • 我同时使用了 ocetet-stream 并且都返回相同的东西。我丢失并退出语句,但文件仍然损坏。
  • @user:确认一下,文件(使用 FTP 客户端下载时)工作正常吗?只有当您尝试通过 PHP 将其作为下载文件传递时,它才会损坏?
  • 是的,我通过 ftp 下载它进行检查,它工作正常。如果这是一个问题,我也在使用 zend。
  • 我解决了这个问题。这是因为zend。但我需要使用你提到的 vnd.-msexcel。谢谢
【解决方案3】:

尝试这样做

 ob_get_clean();
 echo file_get_contents($filename);
 ob_end_flush();

【讨论】:

  • 是的,php 脚本在开头添加了一些空格,并且图像文件在下载时损坏,ob_get_clean() 修复了它。谢谢!
  • 我收到类似 ob_end_flush() 的错误消息:删除和刷新缓冲区失败。文件路径中没有要删除或刷新的缓冲区。请建议我该怎么做@Melvin Protacio
猜你喜欢
  • 2014-09-01
  • 2017-09-13
  • 1970-01-01
  • 2015-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-17
相关资源
最近更新 更多