Search code examples
phpangularjsphppresentation

Unable to download file (PPTX) in AngularJS


Scenario

I want to make an existing PHP script dynamically generating a PPTX (Microsoft PowerPoint File) (Risk Mitigation Event Summary) accessible via an API call to specifically cause AngularJS front end to download the file.

So far my script contains a function called generatePresentation (actual name below). It works opening the script in a browser and produces dynamically generated file using PhpPresentation generation library.

The question is as follows.

How do I make the PowerPoint successfully download without any problems?

Any Help Would Be Appreciated.

Existing PowerPoint Download Function

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');
}

 
    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']); 

AngularJS download function

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();
    });
}

Solution

  • Use of the following three functions (first two are for encoding decoding a string) helped achieve a successful downloadable file.

    Link to Solution which requires use of the first two functions.

    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();
        });
     }