1

I have an Ionic React app and want to download data as CSV. Therefore I added react-papaparse, but I am unable to download the data with the app. As soon as I try it in the browser, it works fine.

In the end, I want to be able to fetch data stored on the phone, convert it from JSON to CSV, and then download it to the phone. I tried it as well with my fetch data as with a dummy array. Neither worked.

But when I click the button inside the browser, I am able to save the generated CSV file. Therefore I think my basic code is working, I am just missing a piece to make it work on the phone/emulator (android studio).

let data
let filename

class ExportCSV extends React.Component {

    getData = async() => {
        let {value} = await Storage.get({key: 'csv' })

        //data = JSON.stringify(value)
        data = value
    }

    getName = () => {
        var today = new Date();
        var dd = String(today.getDate()).padStart(2, '0');
        var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
        var yyyy = today.getFullYear();

        today = dd + '-' + mm + '-' + yyyy;

        filename = "damage_" + today //+ ".csv"            
    }  
  
    render() {

        this.getName()            
        
        const exportCSV = async () => {
          await this.getData()
          let csv = jsonToCSV(data)

          return csv
        }

        
        const inputJSON = [
          {
            Name: "Steve Rogers",
            Hero: "Captain America",
            Color: "Blue & Red",
            Weapon: "Grit & Discipline"
          },
          {
            Name: "Tony Stark",
            Hero: "Ironman",
            Color: "Red & Gold",
            Weapon: "Money & Mind"
          },
          {
            Name: "Dr. Banner",
            Hero: "Hulk",
            Color: "Green",
            Weapon: "Mind & Anger"
          },
          {
            Name: "Dr. Strange",
            Hero: "Dr. Strange",
            Color: "Red",
            Weapon: "Magic"
          },
          {
            Name: "Thor",
            Hero: "Thor",
            Color: "Multi",
            Weapon: "Immortality"
          }
        ];

          //<CSVDownloader filename={filename} data={inputJSON} bom={true} download={true}><IonButton>Export CSV</IonButton></CSVDownloader>

      return (
        <CSVDownloader filename={filename} data={() =>exportCSV()} bom={true} download={true}><IonButton>Export CSV</IonButton></CSVDownloader>
      );
    }
  }

export default ExportCSV
nima
  • 7,796
  • 12
  • 36
  • 53
jonsken
  • 111
  • 1
  • 11

2 Answers2

1

Make a test page that eliminates everything except the code you want to focus on. That way you can concentrate on implementing file download.

For example:

return (
  <CSVDownloader
    filename={'test.csv'}
    data={'columnOne,columeTwo\nrow1col1,row1col2\nrow2col1,row2col2'}
    bom={true}
    download={true}>
    <IonButton>Export CSV</IonButton>
  </CSVDownloader>
);

I'm not familiar with Ionic, but are you sure your code runs when you click the export button? I did a quick google and would expect to see an onClick handler.

Dave
  • 7,552
  • 4
  • 22
  • 26
  • It works in the browser but not using the app on a smartphone/emulator. So trying a onClick handler, is good point. – jonsken Sep 21 '21 at 16:04
0

Solved it by using capacitor filesystem for writing my CSV file. I am just writing a new file after fetching my desired data with capacitor storage API and parsing it with papa parse.

It is important to add encoding: Encoding.UTF8 while writing the file to use it as txt or csv. By default it writes base64 encoded data.

Here is my solution code:

import React from 'react'
import { jsonToCSV } from 'react-papaparse'
import { Filesystem, Directory, Encoding } from '@capacitor/filesystem'
import { Storage } from '@capacitor/storage'
import { IonButton } from '@ionic/react'

class CsvButton extends React.Component {

    render () {
            
        const saveFile = async() => {

            let {value} = await Storage.get({key: 'csv' })
            let csv = jsonToCSV(value)

            var today = new Date();
            var dd = String(today.getDate()).padStart(2, '0');
            var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
            var yyyy = today.getFullYear();

            today = dd + '-' + mm + '-' + yyyy;

            let filename = "csv_" + today + ".csv"

            await Filesystem.writeFile({
                path: filename,
                data: csv,
                directory: Directory.Documents,
                encoding: Encoding.UTF8
              });
          };
        
    return(
            <IonButton onClick={saveFile}>Export Test</IonButton>
    )
    }
}

export default CsvButton
jonsken
  • 111
  • 1
  • 11