Yii2 - 下载损坏的文件
Yii2 - download corrupted file
我正在开发现有产品,我正在尝试解决下载 xlsx 文件的问题。
当我通过文件管理器下载文件时,文件没问题。但是当我通过 Yii 应用程序下载文件时,文件已损坏。
这是我的代码
public function actionCallLog($hash, $filename)
{
var_dump(
$hash, $filename
);
ignore_user_abort(true);
set_time_limit(0);
$path = "/var/www/html/uploads/call_log/".$hash.'/';
$dl_file= basename($filename).'.xlsx';
if (!file_exists($path.$dl_file)) {
$dl_file= basename($filename).'.csv';
}
$fullPath = $path.$dl_file;
if ($fd = fopen ($fullPath, "r"))
{
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext)
{
case "xlsx":
header('Content-Description: File Transfer');
header("Content-type: application/xlsx");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
case "csv":
header('Content-Description: File Transfer');
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
// add more headers for other content types here
default;
header('Content-Description: File Transfer');
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
break;
}
header("Content-length: $fsize");
header("Cache-control: private");
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Expires: 0');
header('Pragma: public');
while(!feof($fd))
{
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
exit;
}
有人知道问题出在哪里吗?
谢谢
尝试添加响应格式
\Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
对于 xlsx,内容类型应为
'application/vnd.ms-excel'
尝试关闭所有 header 指令(以及“echo $buffer;”,因为屏幕上可能有很多)并查看打开 url 用于文件下载。
如果损坏的文件有一定大小,您的代码实际上可能会发出警告或生成其他输出,这些输出将成为文件的一部分,因为它也会被回显。显然,您的代码输出的额外纯文本会将正确的 xlsx 变成损坏的文件。您可以通过在 text-editor 中打开损坏的文件来获取该文本,因为它会以纯文本形式显示在其中(可能在开头)。
我正在开发现有产品,我正在尝试解决下载 xlsx 文件的问题。 当我通过文件管理器下载文件时,文件没问题。但是当我通过 Yii 应用程序下载文件时,文件已损坏。
这是我的代码
public function actionCallLog($hash, $filename)
{
var_dump(
$hash, $filename
);
ignore_user_abort(true);
set_time_limit(0);
$path = "/var/www/html/uploads/call_log/".$hash.'/';
$dl_file= basename($filename).'.xlsx';
if (!file_exists($path.$dl_file)) {
$dl_file= basename($filename).'.csv';
}
$fullPath = $path.$dl_file;
if ($fd = fopen ($fullPath, "r"))
{
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext)
{
case "xlsx":
header('Content-Description: File Transfer');
header("Content-type: application/xlsx");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
case "csv":
header('Content-Description: File Transfer');
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
// add more headers for other content types here
default;
header('Content-Description: File Transfer');
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
break;
}
header("Content-length: $fsize");
header("Cache-control: private");
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Expires: 0');
header('Pragma: public');
while(!feof($fd))
{
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
exit;
}
有人知道问题出在哪里吗?
谢谢
尝试添加响应格式
\Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
对于 xlsx,内容类型应为
'application/vnd.ms-excel'
尝试关闭所有 header 指令(以及“echo $buffer;”,因为屏幕上可能有很多)并查看打开 url 用于文件下载。
如果损坏的文件有一定大小,您的代码实际上可能会发出警告或生成其他输出,这些输出将成为文件的一部分,因为它也会被回显。显然,您的代码输出的额外纯文本会将正确的 xlsx 变成损坏的文件。您可以通过在 text-editor 中打开损坏的文件来获取该文本,因为它会以纯文本形式显示在其中(可能在开头)。