Ionic | Error | fs.createWriteStream cannot be recognized as a function

I am attempting to generate a sample excel file, but I keep encountering the error 'fs.createWriteStream is not a function'. Below is the code snippet I am using to create the file:

import { Component } from '@angular/core';
import { NavController, Platform } from 'ionic-angular';
import * as Excel from "exceljs/dist/exceljs.js";

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor(platform: Platform) {
    platform.ready().then(() => {
      this.createSheetUsingExcelJs();
    });
  }

  ionViewDidLoad() {
  }

  createSheetUsingExcelJs() {
    let workbook = new Excel.Workbook();
    var worksheet = workbook.addWorksheet('My Sheet');

    worksheet.columns = [
      { header: 'Id', key: 'id', width: 10 },
      { header: 'Name', key: 'name', width: 32 },
      { header: 'D.O.B.', key: 'DOB', width: 10 }
    ];
    worksheet.addRow({ id: 1, name: 'Ionic Android', dob: new Date(1970, 1, 1) });
    worksheet.addRow({ id: 2, name: 'Ionic iOS', dob: new Date(1965, 1, 7) });
    var tempFilePath = 'C:/Users/mahmad/Downloads/temp.xlsx';
    console.log(workbook);

    workbook.xlsx.writeFile('temp.xlsx').then(function () {
      console.log('file has been written');
    });
  }
}

If you have any suggestions or solutions for resolving this issue, please feel free to share.

Answer №1

Utilize * as Excel from "exceljs/dist/exceljs.js";

If you want to import a javascript file into typescript, make sure to use the type definition file of the library.

You can find it on npm.

Follow these steps:

npm install @types/exceljs --save-dev

To import, do the following:

import * as Excel from 'exceljs';

You can also refer to a sample in the test file located in the "DefinitelyTyped" repository

Answer №2

After implementing the task, I successfully utilized the ts-xlsx library to complete it. Take a look at my code snippet below:

import { Component, Injectable } from '@angular/core';
import { NavController, Platform } from 'ionic-angular';
import * as XLSX from 'ts-xlsx';
import { File } from '@ionic-native/file';
import { EmailComposer } from '@ionic-native/email-composer';

declare var cordova: any;
declare var window;

@Component({
  selector: 'page-home',
  templateUrl: 'home.html',
  providers: [File]
})

@Injectable()
export class HomePage {

  sheetNames: string[] = []
  sheets: any;

  constructor(public emailComposer: EmailComposer, platform: Platform, public file: File) {
    var objects = [["Header 1", "Header 2", "Header 3"], ["Value 1 1", "Value 1 2", "Value 1 3"], ["Value 2 1", "Value 2 2", "Value 2 3"]];

    platform.ready().then(() => {
      console.log(cordova.file.externalCacheDirectory + "report.xlsx");
      this.createXSLX(objects);
      this.sendEmail(cordova.file.externalCacheDirectory + "report.xlsx");
    });
  }

  createXSLX(data: any) {

    var pathFile = "";
    var fileName = "report.xlsx";
    let ws_name = "OrderDetails";

    let wb: XLSX.IWorkBook = {
      SheetNames: [],
      Sheets: {},
      Props: {}

    };
    let ws = this.sheet_from_array_of_arrays(data, {});

    /* add worksheet to workbook */
    wb.SheetNames.push(ws_name);
    wb.Sheets[ws_name] = ws;
    let wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });

    let xslxBlob = new Blob([this.s2ab(wbout)], { type: "application/octet-stream" });
    pathFile = cordova.file.externalCacheDirectory;
    this.file.writeFile(pathFile, fileName, xslxBlob);
}





sendEmail(data) {    
    this.emailComposer.isAvailable().then((available: boolean) => {
      if (available) {
        //Now we know we can send
      }
    });

    let email = {
      to: '',
      attachments: [data],
      subject: 'XLSX File',
      body: 'How are you? Nice greetings from Leipzig',
      isHtml: true
    };

    // Send a text message using default options
    this.emailComposer.open(email);
  }


  datenum(v, date1904): any {
    if (date1904) v += 1462;
    let epoch: any = Date.parse(v);
    return (epoch - new Date(Date.UTC(1899, 11, 30)).getTime()) / (24 * 60 * 60 * 1000);
  }

  sheet_from_array_of_arrays(data, opts) {
    let ws = {};
    let range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } };
    for (let R = 0; R != data.length; ++R) {
      for (let C = 0; C != data[R].length; ++C) {
        if (range.s.r > R) range.s.r = R;
        if (range.s.c > C) range.s.c = C;
        if (range.e.r < R) range.e.r = R;
        if (range.e.c < C) range.e.c = C;
        let cell: any = { v: data[R][C] };
        if (cell.v == null) continue;
        let cell_ref = XLSX.utils.encode_cell({ c: C, r: R });

        if (typeof cell.v === 'number') cell.t = 'n';
        else if (typeof cell.v === 'boolean') cell.t = 'b';
        else if (cell.v instanceof Date) {
          cell.t = 'n';
          //cell.z = XLSX.SSF._table[14];
          cell.v = this.datenum(cell.v, null);
        }
        else cell.t = 's';

        ws[cell_ref] = cell;
      }
    }
    if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range.s, range.e);
    return ws;
  }





  s2ab(s) {
    let buf = new ArrayBuffer(s.length);
    let view = new Uint8Array(buf);
    for (let i = 0; i != s.length; ++i)
       view[i] = s.charCodeAt(i) & 0xFF;
    return buf;
  }
}

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

Using TypeScript to Bind a Class Method as a jQuery EventHandler

Currently, I am in the process of converting some JavaScript code to TypeScript and I am facing a challenge with defining the signature of a jQuery EventHandler. In the original JavaScript code, simplified to more generic terms, there is an Observer proto ...

Ways to monitor data usage for a specific network on an Android device

Is it possible to track data usage from a specific WiFi network on an Android device? I have tried searching for information on this but haven't found any answers. Can we accurately monitor how much data has been consumed on a network using an Android ...

I'm having trouble grasping the concept of 'globals' in TypeScript/NodeJS and distinguishing their differences. Can someone explain it to me?

As I review this code snippet: import { MongoMemoryServer } from "mongodb-memory-server"; import mongoose from "mongoose"; import request from "supertest"; import { app } from "../app"; declare global { function s ...

Is your pure function component not receiving or responding to input props correctly?

Here is my code snippet: const actionCreators = { action: AppReducer.actionCreators.action } interface GlobalState { user: Model.User | null; } interface InputState { setStashBarWidth(width: number); stashWidth: number; } const Header = ...

NestJS RabbitMQ Microservice Integration

Currently, I am attempting to establish a connection to a Rabbit MQ docker container through NestJS microservice. The setup involves running it using vagrant. Unfortunately, I keep encountering the following error: [1601171008162] ERROR (32761 on local): D ...

Steps to create an instance method that only accepts the name of another instance method

I am looking to enhance an object by adding a method that specifically accepts the name of another method within the object. How can I achieve this in a way that dynamically narrows down the accepted names of methods, without hardcoding them? Let's t ...

Is there a way to exclude the file type as .js when saving a file in .ts format?

I am working on importing .ts files as they are without specifying the file type as .js, for example: import {acccessRights} from "utils/accessRights". My desired outcome is to be able to import a method from another file without having to speci ...

If the data type is numerical, Angular 6 will display the zero in 1.0

I encountered a situation in my code where I declared a number with a zero decimal like so: var myNumber: number = 1.0; When using Angular, it automatically strips off the zero from the value displayed in my form. Converting it to a string is not preferr ...

What is the capability of dynamically generating an index in Typescript?

Can you explain why the Typescript compiler successfully compiles this code snippet? type O = { name: string city: string } function returnString(s: string) { return s } let o1: O = { name: "Marc", city: "Paris", [returnString("random")]: ...

What steps can be taken to troubleshoot and resolve this specific TypeScript compilation error, as well as similar errors that may

I am struggling with this TypeScript code that contains comments and seems a bit messy: function getPlacesToStopExchange(): { our: { i: number; val: number; }[]; enemy: { i: number; val: number; }[]; //[party in 'our' | 'enemy' ]: ...

Angular 2 - Error: Unexpected token < in Http request

I encountered a JavaScript error in my browser while working with the following code: Uncaught SyntaxError: Unexpected token < The error disappears when I remove constructor(private _http:Http) { } from image.service.ts. Could it be that I am incorre ...

An effective method for displaying the total sum of selected row data in Angular dynamically

My goal is to dynamically show the sum of selected column data using the SelectionModel on the rows that I have selected in my table. The displayed data should update when I select or deselect rows. I initially believed that utilizing ngOnInit() would hel ...

Using Angular to Bind Checkbox Value in Typescript

I have a challenge of creating a quiz where a card is displayed with 4 questions structured like this: <div class="col-md-6"> <div class="option" id="Answer1"> <label class="Answer1"> <input value= "Answer1" type="checkbox ...

What is the best way to retrieve all the keys from an array?

I am looking to retrieve the address, latitude, and longitude data dynamically: let Orders= [{ pedido: this.listAddress[0].address, lat: this.listAddress[0].lat, lng: this.listAddress[0].lng }] The above code only fetches the first item from the lis ...

Managing nested request bodies in NestJS for POST operations

A client submits the following data to a REST endpoint: { "name":"Harry potter", "address":{ "street":"ABC Street", "pincode":"123", "geo":{ &q ...

Building a custom CellRenderer in AGGrid using TypeScript within a React environment

Currently, I am utilizing React along with TypeScript and attempting to create a custom CellRenderer in AGGrid. My code is structured like this: PriorityCellRenderer.tsx import React from 'react'; function PriorityCellRenderer(props:any) { co ...

When using Angular, it is important to remember that calling `this.useraccount.next(user)` may result in an error stating that an argument of type 'HttpResponse<any>' cannot be used with a 'Useraccount' balance

When attempting to use this.useraccountsubject(user) to insert information upon login, I encountered an error: ErrorType: this.useraccount.next(user) then Error An argument of type 'HttpResponse' is not allowed against a balance of 'Userac ...

What is the process for generating an object type that encompasses all the keys from an array type?

In my coding journey, I am exploring the creation of a versatile class that can define and handle CRUD operations for various resources. The ultimate goal is to have a single generic class instance that can be utilized to generate services, reducer slices, ...

Trying to create a function in TypeScript that works like lodash's "bindKey"?

I am looking to create a function that serves as a shortcut for obj.func.bind(obj). It should work like this: const bound = <...>(obj: ..., fnKey: ...) : ... => obj[fnKey].bind(obj); const obj = { a: "abc", b() { console.log(thi ...

Is it advisable to flag non-(null|undefined)able type arguments as a type error?

Can the function throwIfMissing be modified to only flag test1 as a compiler error? function throwIfMissing<T>(x: T): T { if (x === null || x === undefined) { throw new Error('Throwing because a variable was null or undefined') ...