【问题标题】:laravel5.3 generate download (.txt) on the flylaravel5.3 即时生成下载(.txt)
【发布时间】:2016-10-17 10:50:49
【问题描述】:

动态生成下载(在我的情况下是 .txt 文件)的最佳方式是什么?我的意思是之前没有将文件存储在服务器上。为了理解这里是我需要完成的事情:

public function getDesktopDownload(Request $request){

        $txt = "Logs ";

        //offer the content of txt as a download (logs.txt)
        $headers = ['Content-type' => 'text/plain', 'Content-Disposition' => sprintf('attachment; filename="test.txt"'), 'Content-Length' => sizeof($txt)];

        return Response::make($txt, 200, $headers);
}

【问题讨论】:

    标签: php download header laravel-5.3 on-the-fly


    【解决方案1】:

    试试这个

    public function getDownload(Request $request) {
        // prepare content
        $logs = Log::all();
        $content = "Logs \n";
        foreach ($logs as $log) {
          $content .= $logs->id;
          $content .= "\n";
        }
    
        // file name that will be used in the download
        $fileName = "logs.txt";
    
        // use headers in order to generate the download
        $headers = [
          'Content-type' => 'text/plain', 
          'Content-Disposition' => sprintf('attachment; filename="%s"', $fileName),
          'Content-Length' => sizeof($content)
        ];
    
        // make a response, with the content, a 200 response code and the headers
        return Response::make($content, 200, $headers);
    }
    

    【讨论】:

    • 如果文件大小超过 php 允许的内存,这将失败,所以如果 php 有 128MB 内存并且文件大小大于 128 mb,那么它将给出关于内存耗尽的致命错误,所以改为使用流式响应可以解决大文件问题。它将分块发送文件。检查下面的答案。
    • @Pratik Boda 我在上面编辑了代码,问题是,我下载的文件只包含字母“L”。知道哪里出了问题吗?
    • @wichtel 只是为了尝试删除 foreach 循环并添加 $txt = "this is test";然后再试一次。生成相同的 o/p
    • @wichtel 问题现在发生在我身上,有解决方案吗? foreach 循环没有问题,我的字符串在其中完美生成,但我在 .txt 文件中只有一个字母。
    • 我发现无论字符串有多长,“Content-Length”始终为 1。知道为什么吗?
    【解决方案2】:

    您可以使用流响应将内容作为下载文件发送

    动态生成下载(在我的情况下是 .txt 文件)的最佳方式是什么?我的意思是之前没有将文件存储在服务器上。为了理解这里是我需要完成的事情:

    use Symfony\Component\HttpFoundation\ResponseHeaderBag;
    use Symfony\Component\HttpFoundation\StreamedResponse;
    

    使用上面的类,然后准备内容

    $logs = Log::all();
    
    $txt = "Logs \n";
    
    
    foreach ($logs as $log) {
        $txt .= $logs->id;
        $txt .= "\n";
    }
    

    然后发送内容流作为下载

    $response = new StreamedResponse();
    $response->setCallBack(function () use($txt) {
          echo $txt;
    });
    $disposition = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'logs.txt');
    $response->headers->set('Content-Disposition', $disposition);
    
    return $response;
    

    【讨论】:

    • 不错的解决方案!但对我来说,它会下载一个 logs.txt.html 文件。无论如何要接收一个纯 .txt 文件?
    • 我明白了。您必须像这样将内容类型添加到标题中: $response->headers->set('Content-Type', 'text/plain');
    • 如果 $txt 变量包含超过您的内存限制,这也会给出内存不足错误。您应该做的是每次迭代都返回部分日志文件。
    【解决方案3】:
    $images = DB::table('images')->get();
    $content = "Names \n";
    foreach ($images as $image) {
      $content .= $image->name;
      $content .= "\n";
    }
    
    $fileName = "logs.txt";
    
    $headers = [
      'Content-type' => 'text/plain', 
      'Content-Disposition' => sprintf('attachment; filename="%s"', $fileName),
      'Content-Length' => strlen($content)
    ];   
    return Response::make($content, 200, $headers);
    use  strlen function in content-length if you use sizeof its always print one char in text document.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-17
      • 2017-12-27
      • 2011-06-10
      • 1970-01-01
      • 2013-01-14
      • 2019-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多