Exporting Excel files in Angular on the client side

Using Angular v4, I am trying to figure out how to create an Excel spreadsheet based on an object within a component. The goal is to enable users to download the Excel file by clicking a button, all performed client-side. My data is in JSON format and I want to convert it into an Excel file that can be customized in terms of style. Is this feasible? If so, what is the approach?

Edit: Looking for a solution without using JavaScript libraries; seeking to accomplish this with TypeScript and Angular only.

Answer №1

yourinfo= jsonData

GenerateCSVData(objArray) {
            var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
              var str = '';
            var row = "";

            for (var index in objArray[0]) {
                //Converting each value to string and comma-separated
                row += index + ',';
            }
            row = row.slice(0, -1);
            //Appending Label row with line break
            str += row + '\r\n';

            for (var i = 0; i < array.length; i++) {
                var line = '';
                for (var index in array[i]) {
                    if (line != '') line += ','

                    line += array[i][index];
                }
                str += line + '\r\n';
            }
            return str;
        }

in your html:

<button (click)="save()">export data</button>

in component:

save(){    
 var csvData = this.GenerateCSVData(yourinfo);
                        var a = document.createElement("a");
                        a.setAttribute('style', 'display:none;');
                        document.body.appendChild(a);
                        var blob = new Blob([csvData], { type: 'text/csv' });
                        var url= window.URL.createObjectURL(blob);
                        a.href = url;
                        a.download = 'Results.csv';/* file name*/
                        a.click();
                        return 'done';
}

Hope it works for you

Answer №2

After making a small modification by replacing "," with ";", Vishwanath's answer successfully worked for me. Here is how the implementation would look like in Typescript:

ConvertToCSV(objArray: any) {
    const array = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray;
    let str = '';
    let row = '';

    for (const index of Object.keys(objArray[0])) {
      row += `${index};`;
    }
    row = row.slice(0, -1);
    str += `${row}\r\n`;

    for (let i = 0; i < array.length; i++) {
      let line = '';
      for (const index of Object.keys(array[i])) {
        if (line !== '') {
          line += ';';
        }
        line += array[i][index];
      }
      str += `${line}\r\n`;
    }
    return str;
  }

This solution may be useful to someone facing similar challenges.

Answer №3

Getting the task done without relying on JavaScript libraries in the background might be a challenge. To smoothly integrate it into your Angular project using TypeScript, you'll need the necessary typings.

If you're looking to create an Excel file, consider utilizing something like exceljs. Make sure to also add the required typings from here, although I can't vouch for its suitability as I haven't tried it myself.

For downloading purposes, check out FileSaver.js (which I've personally used).

npm install file-saver --save

Don't forget to include the typings:

npm install @types/file-saver --save-dev

To utilize FileSaver.js, add this import statement to your component:

import * as FileSaver from 'file-saver';

When you want to trigger the download, use the following syntax:

FileSaver.saveAs(fileData, "filename.xlsx")

Make sure 'fileData' is in Blob format.

I hope this information proves helpful in some way.

Answer №4

It is not feasible.

XLS files are stored in a binary format.

The Apache POI project (referenced at https://en.wikipedia.org/wiki/Apache_POI) refers to this as HSSF (Horrible SpreadSheet Format).

My suggestion is to handle it on the server side for better efficiency.

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

Typescript is unable to locate the imported type Action

I've been working on my TypeScript + Redux project and encountered an issue while trying to import the type Action from redux using the following code: import { Action } from 'redux' An error popped up stating: TS2305: Module '"../ ...

Accessing data from datatables in a typescript component in HTML format

I need to retrieve the selected mfRowsOnPage data, which is currently set at 10. The user can later choose a different value such as 5 or 15. I also require information on which page the user is viewing, for example, the 1st or 2nd page. This is the table ...

I am currently working on integrating a Material Sorted feature

I am currently working on implementing Material Sorting, with the help of this reference: https://material.angular.io/components/sort/overview An interesting twist in my implementation is that I load my data after making a selection from a dropdown contro ...

Display JSON Array information in a template using a component

I have made an API call and received the response in this.order.info this.http.get(this.order_info_url+'/'+this.order_id) .subscribe( response => { this.order_info = response.json(); console.log(this.order_info[0]); }, ...

Issue "Received 3 arguments instead of the expected 1-2" when implementing useQuery with React Query and TypeScript

In my React Native project, I am utilizing useQuery from React Query to retrieve live scores. My intention is to provide three arguments - the query key, a fetch function, and an options object. However, I am facing an issue with an error message stating: ...

The data type 'string | number | null | undefined' cannot be assigned to the type 'null'

I am currently working on implementing the concept of initializing C# Class objects in a TypeScript class. However, I encountered an error message from the compiler as follows. Error: Type 'string | number | null | undefined' is not compatible ...

mention colleague(parent) instruction request

I have been exploring the use of metadata for setting HTML input attributes. After reading through the Attribute Directives Guide (https://angular.io/docs/ts/latest/guide/attribute-directives.html), I have developed the following implementation: import "r ...

Using Angular 6 to Share Data Among Components through Services

I am facing an issue in my home component, which is a child of the Dashboard component. The object connectedUser injected in layoutService appears to be undefined in the home component (home userID & home connectedUser in home component logs); Is there ...

Extracting the base href in Angular 6

Is there a way to dynamically retrieve /CTX-ROOT/assets/tiny-editor/langs/cs.js in Angular 6 component without using the PlatformLocation#getBaseHrefFromDOM method? constructor( private zone: NgZone, private platformLocation: PlatformLocation) ...

When creating an async function, the type of return value must be the universal Promise<T> type

https://i.stack.imgur.com/MhNuX.png Can you explain why TSlint continues to show the error message "The return type of an async function or method must be the global Promise type"? I'm confused about what the issue might be. UPDATE: https://i.stac ...

The 'children' property is not found in the '{}' data type

I encountered a TypeScript error where it mentioned that 'children' is not recognized on type '{}' despite the fact that this syntax has worked perfectly fine in my previous projects. ...

Defining object properties in TypeScript types

Let me explain the issue in a simple way I have a type consisting of predefined strings like: type myType = 'name' | 'age' | 'family' | 'other'; I want to define a type that enforces these strings to be used const ...

What are the steps to launch a Firebase application without requiring user authentication?

I have a unique firebase app/game that does not require authentication. My main goal is to allow anyone to easily access the website or mobile app and start playing right away, without the need for user IDs. I have been receiving numerous emails from Fireb ...

Cease the animated loading icon once the template has finished loading in sync with the async pipe

.ts initialize() { const loadingScreen = await this.loadingService.displayLoader();//loading screen this.products$ = this.bikeShopService.retrieveData();//Observable operation } .html <ion-col size="6" *ngFor="let product of (products$ ...

What is the purpose of the try..catch statement in a recoil selectorFamily when handling promise errors?

Currently, I am utilizing recoil selectorFamily which subscribes to several selectors or selectorFamilies for data queries. Additionally, I am implementing try...catch blocks to track the status of each data query operation. However, I recently noticed tha ...

The 'BrowserRouter' type is lacking the properties specified below... - TypeScript

I'm currently learning TypeScript and attempting to integrate it into my personal project. When I make the call to ReactDOM.render, I encounter this error: No overload matches this call. The last overload resulted in the following error. Argument of ...

Unable to include a header in an Angular 2 HTTP request

Having trouble with the http request headers while using the following code snippet: let authToken = new Headers() authToken.append("Authorization", "xyz"); this.http.get("http://localhost:8081/hello", {headers: authToken}) .subscribe((response) =& ...

Ways to conceal button for inactive edit row on a table

I am trying to implement inline editing for a table in my application. The requirement is to hide the "Edit" and "Delete" buttons for all other rows when the user clicks on the edit button of a particular row. I have attempted to achieve this using the c ...

Assistance with Python for managing Excel files in CSV format

I am working with a CSV file that contains numbers only. How can I import these numbers into an array in Python one row at a time, excluding any dates or strings? Here is the code I currently have: import csv def test(): out = open("example.csv","rb ...

Require a property to be mandatory depending on the value of another property within a generic interface

Looking for a way to have one property affect the others in a react component interface? Here's an example of what I'm trying to achieve: export interface IMyAwesomeComponentProps<T = {}> { className: string defaultPath?: ISomeOthe ...