PHPExcel下载文件

5
我想下载一个由PHPExcel生成的Excel文件。我按照PHPExcel Force Download Issue中的代码操作,但无济于事。在记录接收到的数据后,我的控制台只显示这些符号�。然而,当我将$objWriter->save('php://output');更改为$objWriter->save('filename.xlsx');时,它会将文件下载到我的Web服务器根目录,没有任何下载文件的提示。以下是我的php文件的代码片段。
<?php
$con = mysqli_connect('localhost', 'root', '', 'test');
mysqli_select_db($con, 'test');

$qry = "SELECT * FROM lostitem";
$res = mysqli_query($con, $qry);

require_once '/Classes/PHPExcel.php';
include '/Classes/PHPExcel/Writer/Excel2007.php';

// Create new PHPExcel object
$objPHPExcel = new PHPExcel();
/** Determine filename **/
$filename = "report.xlsx";

/** Set header information **/
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $filename . '"');
header('Cache-Control: max-age=0');
$F=$objPHPExcel->getActiveSheet();
$Line=1;
$F->setCellValue('A'.$Line, 'Lost Item ID');
$F->setCellValue('B'.$Line, 'Lost Item Title');
$F->setCellValue('C'.$Line, 'Lost Item Description');
while($Trs=mysqli_fetch_assoc($res)){//extract each record
    ++$Line;
    $F->setCellValue('A'.$Line, $Trs['LostItemID']);
    $F->setCellValue('B'.$Line, $Trs['LostItemTitle']);
    $F->setCellValue('C'.$Line, $Trs['LostItemDescription']);//write in the sheet
    //++$Line;
}
// Redirect output to a client’s web browser (Excel5)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="'.$filename.'"');
header('Cache-Control: max-age=0');

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
exit;

?>

以下是我的angularjs代码片段:

$scope.getReport = function(type){
        if(type == 'lost'){
            $http.post("getLostItemReport.php")
                .success(function(data, status, headers, config){
                    console.log("Get report data: " + data);
                })
        }
      }

注意:我使用AngularJS $http.post调用php文件。
浏览器:Google Chrome 编辑:我已经尝试了来自PHPExcel 01simple-download-xlsx.php的示例php代码,结果也相同。
更新:我通过搜索关于接受Excel作为响应获取AngularJS的一些解决方案,但在下载后,似乎文件被损坏并且有类似于控制台中注销的无意义文本或符号。此外,文件名是随机文本和数字,而不是我在php代码中分配的文件名。以下是代码:
var blob = new Blob([data], {type: "application/vnd.ms-excel"});
                    var objectUrl = URL.createObjectURL(blob);

添加标题: https://dev59.com/DGoy5IYBdhLWcg3wa9Yj - Vladimir Ramik
已经尝试过了。你可以在我的代码中看到它们的问题。 - imationyj
1
那个“乱码”实际上是Excel文件... xls和xlsx都是二进制格式... 而且Angular不知道如何处理内容类型为application/vnd.ms-excelapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet的原始二进制流。 - Mark Baker
是的,我也发现实际上是Excel文件的问题。感谢您指出了关于“_angular不知道如何处理内容类型为application/vnd.ms-excelapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet的原始二进制流”的问题。我会尝试寻找解决这个问题的方法。 - imationyj
3个回答

2
我找到了一个使用AngularJS下载并且能够在运行时更改文件名的解决方案。我们需要下载FileSave.js并将其包含在index.html的头部中。代码片段如下:

main.js

$scope.fetchReport = function(){
            $http({
                url: 'path_to_php_file',
                method: 'POST',
                responseType: 'arraybuffer',
                headers: {
                    'Content-type': 'application/json',
                    'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
                }
            }).success(function(data){
                var blob = new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});
                saveAs(blob, file_name_to_be+'.xlsx');
            }).error(function(){
                //Some error log
            });
        }

index.html

<button class="btn btn-primary" ng-click="fetchReport()">Get Report</button>

PHP文件与问题中的相同,只需要在exit;之前添加几行代码。

header('Content-disposition: attachment; filename='.$filename);
header('Content-Length: ' . filesize($filename));
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Pragma: public');

//Replace php://output with $filename and add code below after that(before exit;)
readfile($filename);

注意:此功能仅适用于支持HTML5的浏览器。

那对我很有帮助,谢谢!如果我可以补充一下,应该在 header('Content-Length: ' . filesize($filename)); 之前调用 $objWriter->save($filename); - Pierre Roudaut

1

你的根目录里有Excel文件对吧?

那么,我认为你可以使用 header('Location: 你的Excel文件路径'); 这应该会帮助你下载文件。


$objWriter->save('filename.xlsx');之后,还有另一种选项,添加echo json_encode(readfile($file)); 在AngularJS代码中使用
$scope.getReport = function (type) {
if (type == 'lost') {
    $http({
        url: 'getLostItemReport.php',
        method: 'POST',
        responseType: 'arraybuffer',
        headers: {
            'Content-type': 'application/json',
            'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        }
    })
    .success(function (data, status, headers, config) {
        var blob = new Blob([data], {
            type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        });
        var objectUrl = URL.createObjectURL(blob);
        window.open(objectUrl);
    })
}

将您的header('Content-Type: application/vnd.ms-excel');设置为header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');

尝试这个。


$objWriter->save('filename.xlsx'); 之后。 - itssajan
你能提供代码 header('Location: path to your excel file'); 并将路径替换为实际路径吗? - itssajan
我已经尝试了您编辑过的解决方案。我的代码是echo json_encode(readfile('filename.xlsx'));,您提到的blob函数类型返回的xlsx文件已损坏,如果我将其更改为vnd.ms-excel,我可以打开文件,但内容是乱码文本。 - imationyj
尝试给出绝对路径,例如 header('Location: "http://localhost:8000/filename.xlsx"') - itssajan
你能看到Excel文件的权限设置吗?例如 chmod file.xlsx - itssajan
显示剩余7条评论

1
我有一个非常基本的解决方案,可以在我的网站上使用。希望这个方法能够奏效。
创建一个超链接,并将href设置为你的Excel文件,并使用下载属性。
<a href='file to excel' download='download'>Download Excel File</a>

当您点击此链接时,文件将开始下载。

不错!如果我仍然找不到任何解决方案,那将是我的项目的一个解决方法。我只需要先将文件生成到服务器上,然后单击链接下载文件,而不是动态生成并在之后下载(这是我现在问题的原因)。无论如何,感谢您的提示。 :) - imationyj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接