【问题标题】:Unable to download file (PPTX) in AngularJS无法在 AngularJS 中下载文件(PPTX)
【发布时间】:2020-04-15 21:11:12
【问题描述】:

场景

我想让现有的 PHP 脚本动态生成 PPTX(Microsoft PowerPoint 文件)(风险缓解事件摘要),可通过 API 调用访问,以专门导致 AngularJS 前端下载文件。

到目前为止,我的脚本包含一个名为 generatePresentation 的函数 (下面的实际名称)。它可以在浏览器中打开脚本并 使用 PhpPresentation 生成库生成动态生成的文件。

问题如下。

如何让 PowerPoint 顺利下载且没有任何问题?

我们将不胜感激。

现有的 PowerPoint 下载功能

public function generateRiskSummaryPresentation()
{
   header("Content-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation");
   header("Content-Disposition: attachment; filename=RiskSummary.pptx");
   $oWriterPPTX = IOFactory::createWriter($this->riskPPT,'PowerPoint2007');
   $oWriterPPTX->save('php://output');
}

示例输入(生成 PowerPoint 文件的“风险事件”元素列表)

$minHigh = .55;
$maxLow = .30;
    
$events = 
[
    [    
        'title' => 'Risk Identification',
        'owner' => 'Jabagchourian, Vahe',
        'baseline-date' => '2019-03-01',
        'baseline-likelihood' => 5,
        'baseline-consequence-T' => 4,
        'baseline-consequence-S' => 5,
        'baseline-consequence-C' => 5,
        'actual-date' => '2019-03-01',
        'actual-likelihood' => 5,
        'actual-consequence-T' => 5,
        'actual-consequence-S' => 5,
        'actual-consequence-C' => 5,
        'schedule-date' => ' ',
        'schedule-likelihood' => ' ',
        'schedule-consequence-T' => ' ',
        'schedule-consequence-S' => ' ',
        'schedule-consequence-C' => ' '
    ],
    [
        'title' => 'Test Procedure',  
        'owner' => 'Jabagchourian, Harry',
        'baseline-date' => '2019-03-02',
        'baseline-likelihood' => 4,
        'baseline-consequence-T' => 3,
        'baseline-consequence-S' => 5,
        'baseline-consequence-C' => 5,
        'actual-date' => '2019-03-02',
        'actual-likelihood' => 4,
        'actual-consequence-T' => 4,
        'actual-consequence-S' => 5,
        'actual-consequence-C' => 3,
        'schedule-date' => ' ',
        'schedule-likelihood' => ' ',
        'schedule-consequence-T' => ' ',
        'schedule-consequence-S' => ' ',
        'schedule-consequence-C' => ' '
    ],
    [
        'title' => 'Publish Report',  
        'owner' => 'Jabagchourian, Vahe',
        'baseline-date' => '2019-03-10',
        'baseline-likelihood' => 4,
        'baseline-consequence-T' => 3,
        'baseline-consequence-S' => 4,
        'baseline-consequence-C' => 4,
        'actual-date' => '2019-03-10',
        'actual-likelihood' => 4,
        'actual-consequence-T' => 4,
        'actual-consequence-S' => 3,
        'actual-consequence-C' => 3,
        'schedule-date' => ' ',
        'schedule-likelihood' => ' ',
        'schedule-consequence-T' => ' ',
        'schedule-consequence-S' => ' ',
        'schedule-consequence-C' => ' '
    ],
    [
        'title' => 'Review Report',   
        'owner' => 'Jabagchourian, Harry',
        'baseline-date' => '2019-03-14',
        'baseline-likelihood' => 4,
        'baseline-consequence-T' => 3,
        'baseline-consequence-S' => 3,
        'baseline-consequence-C' => 3,
        'actual-date' => '2019-03-14',
        'actual-likelihood' => 3,
        'actual-consequence-T' => 2,
        'actual-consequence-S' => 3,
        'actual-consequence-C' => 4,
        'schedule-date' => ' ',
        'schedule-likelihood' => ' ',
        'schedule-consequence-T' => ' ',
        'schedule-consequence-S' => ' ',
        'schedule-consequence-C' => ' '
    ],
    [
        'title' => 'Adjustments',
        'owner' => 'Jabagchourian, Vahe',
        'baseline-date' => '2019-03-15',
        'baseline-likelihood' => 3,
        'baseline-consequence-T' => 3,
        'baseline-consequence-S' => 1,
        'baseline-consequence-C' => 2,
        'actual-date' => ' ',
        'actual-likelihood' => ' ',
        'actual-consequence-T' => ' ',
        'actual-consequence-S' => ' ',
        'actual-consequence-C' => ' ',
        'schedule-date' => '2019-03-18',
        'schedule-likelihood' => 3,
        'schedule-consequence-T' => 3,
        'schedule-consequence-S' => 1,
        'schedule-consequence-C' => 2
    ],
    [
        'title' => 'Adjustments',
        'owner' => 'Jabagchourian, Vahe',
        'baseline-date' => '2019-03-16',
        'baseline-likelihood' => 2,
        'baseline-consequence-T' => 1,
        'baseline-consequence-S' => 2,
        'baseline-consequence-C' => 1,
        'actual-date' => ' ',
        'actual-likelihood' => ' ',
        'actual-consequence-T' => ' ',
        'actual-consequence-S' => ' ',
        'actual-consequence-C' => ' ',
        'schedule-date' => '2019-03-19',
        'schedule-likelihood' => 2,
        'schedule-consequence-T' => 1,
        'schedule-consequence-S' => 2,
        'schedule-consequence-C' => 1
    ]
];
        
        
    if (isset($_GET['events']))
    {
        echo json_encode($events);
        die();
    }      
 //var_dump($events);                                                                      
    $today = date('Y-m-d');  
    $startDate = $events[0]['baseline-date'];
    $endDate = max($today, $events[count($events)-1]['baseline-date'], $events[count($events)-1]['schedule-date'], $events[count($events)-1]['actual-date']); 

生成的示例 PowerPoint 文件

AngularJS 下载功能

ctrl.getRiskReport = function(){
    $http.get('api/risk/' + ctrl.risk.riskid + '/report', 
    {responseType:'arraybuffer'})
      .then(function (response) {
         var file = new Blob([(response)], {type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation'});
         var downloadLink = angular.element('<a style="display:none"></a>');
         downloadLink.attr('href',window.URL.createObjectURL(file));
         downloadLink.attr('target', '_blank');
         downloadLink.attr('download', 'RiskSummary.pptx');
         downloadLink[0].click();
    });
}

下载时出现 PowerPoint 错误消息

浏览器中 API 的示例输出(文件内容)

【问题讨论】:

标签: php angularjs api downloadfile phppresentation


【解决方案1】:

我有非常相似的问题, 我只需将选项 {responseType: 'blob'} 放在我的 axios 请求中即可解决它。

【讨论】:

  • @JoseV,感谢您提出这个解决方案,因为我意识到我在 http get api 中使用了错误的响应类型
【解决方案2】:

使用以下三个函数(前两个用于对字符串进行编码解码)有助于成功下载文件。

链接到需要使用前两个功能的解决方案。

https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#Solution_5_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8

PHP

public function generateRiskSummaryPresentation()
{
   //header("Content-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation; charset=utf-8");
   header("charset=utf8");
   //header("Content-Disposition: attachment; filename=RiskSummary.pptx");
   $oWriterPPTX = IOFactory::createWriter($this->riskPPT,'PowerPoint2007');
   return $oWriterPPTX->save('php://output');    
}

JS

function Base64Encode(str, encoding = 'utf-8') {
    var bytes = new (typeof TextEncoder === "undefined" ? TextEncoderLite : TextEncoder)(encoding).encode(str);        
    return base64js.fromByteArray(bytes);
}

function Base64Decode(str, encoding = 'utf-8') {
    var bytes = base64js.toByteArray(str);
    return new (typeof TextDecoder === "undefined" ? TextDecoderLite : TextDecoder)(encoding).decode(bytes);
}

ctrl.getRiskReport = function(){
    $http.get('api/risk/' + ctrl.risk.riskid + '/report', 
    {responseType:'arraybuffer'})
      .then(function (response) {
         var file = new Blob([response.data], {type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', charset: 'utf-8'});
         var downloadLink = angular.element('<a style="display:none"></a>');
         downloadLink.attr('href',window.URL.createObjectURL(file));
         downloadLink.attr('target', '_blank');
         downloadLink.attr('download', 'RiskSummary.pptx');
         downloadLink[0].click();
    });
 }

【讨论】:

  • 单独的响应不起作用,所以我在 blob 中使用了 response.data,因为响应只是一个 JSON
猜你喜欢
  • 1970-01-01
  • 2018-01-22
  • 2020-03-16
  • 1970-01-01
  • 2015-06-23
  • 2017-07-01
  • 2018-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多