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'); }
Sample Input (“Risk Event” list of elements to generate PowerPoint file)
$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']);
Sample PowerPoint File Generated
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(); }); }
PowerPoint Error Message when downloading
Sample Output in Browser from API (The file contents)
Advertisement
Answer
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.
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(); }); }