Downloading Excel files in Angular using File Saver

Previously, I had set up a PHP post form that would download an excel file upon clicking the button. The form data was also posted to the URL successfully using plain HTML and submit form.

This is the function in PHP that gets triggered when the form is posted:

public function downloadExcel($fileName = '', $addTimeStamp = true) {
    $fileName = (!$fileName) ? 'excel_download' : preg_replace('/\s+/', '_', $fileName);
    if ($addTimeStamp) {
        $fileName .= date('_d_m_Y_H_i_s');
    }
    $fileName .= '.xlsx';
    $this->setActiveSheetIndex(0);
    header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    header('Content-Disposition: attachment;filename="' . $fileName . '"');
    header('Cache-Control: max-age=0');
    header('Cache-Control: max-age=1');
    header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
    header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
    header('Cache-Control: cache, must-revalidate');
    header('Pragma: public');
    $objWriter = PHPExcel_IOFactory::createWriter($this, 'Excel2007');
    $objWriter->save('php://output');
}

Although it worked fine previously with the Request Headers set as shown here:

https://i.stack.imgur.com/HKwc1.png

The response now seems to be empty as indicated here:

https://i.stack.imgur.com/8kT5E.png

We are now transitioning our frontend to the Angular framework. Despite trying this method:

downloadTheExport() {
  this.downloadfile().subscribe((blob: any) => {
    const blobdownload = new Blob([blob], { type: "application/vnd.ms-excel;charset=utf-8" });
    saveAs(blobdownload, 'testdata.xls');
  });
}

downloadfile(){
  const formDataForExport: FormData = new FormData();
  formDataForExport.append('export', 'ALL');

  return this.http.post('http://localhost:8080/service/exportExcel.php', formDataForExport, {
    headers: { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' }
  });
}

When attempting to download in Angular, I noticed that the Content-Type request header was changed to

Content-Type: multipart/form-data; boundary angular
. Additionally, the response tab showed some data like this:

https://i.stack.imgur.com/8KYbX.png I am seeking guidance on how to enable downloading in Angular within this scenario.

Answer №1

It is accurate for the Content-Type specified in your Request header when posting formDataForExport via a PHP backend.

However, the method of handling the response appears to be incorrect. Below is a proposed solution that may help:

If you are using the fileSaver library, you can find it at the following link:

https://github.com/Hipparch/file-saver-typescript/blob/master/file-saver.ts

I recommend including the above script and utilizing it to handle various browser behaviors when saving files, as it is complex and not advisable to re-implement them.

downloadTheExport() {
  this.downloadfile().subscribe((resp: any) => {
    const fileSaver: any = new FileSaver();
    fileSaver.responseData = resp.body;
    fileSaver.strFileName = 'testdata.xls';
    fileSaver.strMimeType = 'application/vnd.ms-excel;charset=utf-8';
    fileSaver.initSaveFile();
  });
}

downloadfile() {
  const formDataForExport: FormData = new FormData();
  formDataForExport.append('export', 'ALL');

  return this.http.post('http://localhost:8080/service/exportExcel.php', formDataForExport, {
    headers: { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' },
    responseType: 'blob',
    observe: 'response'
  });
}

Answer №2

If you're looking to simply download a file from the assets folder, you can utilize this snippet of code:

<a href="./assets/files/document.pdf" target="_blank">Download File</a>

Ensure to specify the location in your angular.json file as shown below:

  "architect": {
       "build": {
          "options": {
        "assets": [
                      "src/assets/files"
                  ]
          }
       }
    }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular 2 testing encounters an issue with ViewUtils when setBaseTestProviders() is used

Encountering an issue when utilizing the 'setBaseTestProviders(..)' method, a console error arises. Our current version of Angular is 2.0.0-rc.1. The test located at (test/areas-list.component.spec.ts) looks like this: import {setBaseTestProv ...

Provide information to spyOn and return a specific value

I am attempting to mimic a call to a service that involves an HTTP call. My goal is to provide fabricated data in the mock and verify it during my test. This is how I have set up the scenario: beforeEach(() => { fixture = TestBed.createComponent(MhS ...

The issue of CSS not being applied to HTML content after being inserted via AJAX has been encountered

I've successfully implemented AJAX to retrieve specific page content from a database, but now I'm facing an issue: When it comes to the 'Contact' page, the form retrieved from the database (as HTML) is not applying the CSS styles I hav ...

Creating regular occurrences on Google Calendar with specific time slots

I am looking to include recurring events with specific start and end times. I have been working with the following code: $recurrence = "DTSTART;VALUE=DATE:{$start}\r\n" . "DTEND;VALUE=DATE:{$start2}\r\n" . "RRUL ...

How to Retrieve Superclass Fields in Angular 5 Component

I have a superclass that provides common functionality for components. export class AbstractComponent implements OnInit { public user: User; constructor(public http: HttpClient) { } ngOnInit(): void { this.http.get<User>(& ...

Display options in a dropdown menu according to the value selected in another dropdown menu on an edit form in Laravel

After discovering a solution on another website, I successfully implemented it. However, I am facing an issue when trying to use this setup in my edit form (ideally within the same form as my create form since they both share the same structure). On the ed ...

Web-based API for authentication system using Ionic framework and token-based login

I am developing a photo-sharing app that requires a login system. However, when attempting to log in, an error occurs stating that the value is not found. I am able to retrieve the value in services but struggling to get the email and password in login.pag ...

Unable to render ASP.NET Core 2 WebAPI and Angular application on the webpage

Following a tutorial, I created an ASP.NET Core 2 Web API. The API functions properly when accessed through the browser at: https://localhost;44313/api/liveconsole To design the Angular UI for my web API, I referred to another tutorial. After multiple at ...

Our application, Server? Mobile, is designed for Android devices and connects users to our web portal by displaying data such as text and images on

Currently in the process of developing an Android app that will showcase text details (captions and user information) along with images. Users will have the ability to upload and view data directly within the app. However, when it comes to setting up a web ...

Tips for resolving the setAttribute() function error message: "Argument of type 'boolean' is not assignable to parameter of type 'string'"

I am currently working on a function that dynamically updates the HTML aria-expanded attribute based on whether it is true or false. However, when I declare element as HTMLElement, I encounter an error stating Argument of type 'boolean' is not as ...

When using json_decode, be aware that it may convert lengthy numbers into scientific

Is there a way to prevent JSON from turning the trackingNumber into scientific notation when using json_decode? I want to access the data as an array without compromising the integer or rounding it. Can I loop through the RAW JSON without decoding it to ac ...

Is it possible in Angular to directly bind the emitted output of a component to a property?

My primary application component communicates with its sub components using @Output decorated properties on the subcomponent. The output properties utilize an EventEmitter<>(). Typically, these properties emit a simple boolean or number. I want to di ...

"Utilizing PHP with FTP and AJAX, or other comparable technologies

After successfully creating a PHP class for FTP server interaction (connecting, changing directories, uploading files, etc.), I am now eager to provide real-time updates to users about the actions happening on the server. For example, notifying them with m ...

What is the best way to handle invalid JSON data in PHP?

I've been attempting to parse the json data provided below, but unfortunately, I am consistently receiving an empty result. Here is the json data: $response = '{"Status":1,"CodigoErro":null,"SKYException":"","ResultString":"{\"DadosBasicos ...

Learning to display an error message by clicking the send button in an Angular 2 application

Despite my best efforts, I have struggled to find a solution. I have searched various websites, but everywhere they only show validations on touch or hide the button until the form is valid. How can I implement validations by simply clicking a button? Here ...

Exploring the significance of the static variable $_class declaration within the load_class function of CodeIgniter

While diving into the core features of CodeIgniter, I came across a query regarding the declaration of a variable. static $_classes = array(); As highlighted in this post, the purpose of this variable is to cache class objects. I'm confused because ...

Encountering difficulties when attempting to start a new project in Angular

I am encountering an issue while trying to create new in Angular, using version 6 and Node.js v8.11 Here is the console log: Unable to save binary /home/amit/demo/node_modules/node-sass/vendor/linux-x64-57 : { Error: EACCES: permission denied, mkdir ...

How to format a Date object as yyyy-MM-dd when serializing to JSON in Angular?

I have a situation where I need to display an object's 'birthDate' property in the format DD/MM/YYYY on screen. The data is stored in the database as YYYY-MM-DD, which is a string type. I am currently using bootstrap bsDatePicker for this ta ...

Ensuring the Safety of Usernames with JavaScript, PHP, and MySQL

I have come across several articles discussing the implementation of a feature on a registration page that automatically checks if a username is already in use in the database. However, I am concerned about the security implications of this approach. I fea ...

Firebase initialization unsuccessful due to incorrect directory placement

I've been encountering an issue while deploying my Angular 2 project to Firebase. The initial deployment was successful, but subsequent attempts only show the Firebase Hosting welcome page instead of my project in the URL. I've realized that even ...