Laravel + Vue.js - 下载的 docx 文件已损坏

Laravel + Vue.js - downloaded docx file is corrupted

提问人:E R 提问时间:11/4/2023 更新时间:11/5/2023 访问量:25

问:

我为我的项目使用 Laravel 10.x 和 Vue.js 3.x 以及 PHPWord 包。我想下载生成的 docx 文件。下载成功,但我无法打开文件 - 它已损坏。

我尝试添加ob_end_clean(),因为它在许多关于从Laraval存储下载损坏文件的问题和答案中提到,但问题没有解决。 我还使用 scp 下载了生成的文件,它没有损坏。因此,问题显然出在响应中的某个地方,而不是使用模板和保存文件。

Vue.js

const getFile = async () => {
   try {
      let response = await axios.get('api/docx', { responseType: 'blob' });
      let blob = new Blob([response.data]);
      let link = document.createElement('a');
      link.href = window.URL.createObjectURL(blob);
      link.download = 'test.docx';
      document.body.appendChild(link);
      link.click();
   } catch (e) {
      alert(e);
   }
}

拉拉维尔

public function getFile() {
   $doc = new TemplateProcessor(storage_path() . '/app/public/test_template.docx');
   $doc->setValue('random_text', 'Foo');
   $doc->saveAs(storage_path() . '/app/public/test.docx');
   
   ob_end_clean();
   $headers = array('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
   return response()->download(storage_path() . '/app/public/test.docx', 'test.docx', $headers);
}
Laravel 下载 vuejs3 docx 损坏

评论


答:

0赞 Denis Sinyukov 11/5/2023 #1
    $writer = \PhpOffice\PhpWord\IOFactory::createWriter($this->word, 'Word2007');

    $fileName = 'example.docx';

    $response = new StreamedResponse(
        fn() => $writer->save('php://output')
    );

    $response->headers->set('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');
    $response->headers->set('Content-Disposition', 'attachment;filename="' . $fileName .'"');
    $response->headers->set('Cache-Control','max-age=0');
    $response->headers->set('Content-Description','File Transfer');

    return $response;

Vue的

function download(response, fileName) {
  if (!response?.data) return;
  const url = window.URL.createObjectURL(response.data);
  const link = document.createElement('a');
  link.href = url;
  link.setAttribute('download', `${fileName}.docx`)
  document.body.appendChild(link)
  link.click()
 }