Moltes dades que necessitem estan en format CSV

Introducció

En aquest enllaç tens el projecte de suport d'aquesta activitat: https://gitlab.com/xtec/typescript/csv

Entorn de treball

Crea un projecte react:

$ bun create vite csv --template react-swc-ts

PapaParse

PapaParse és un parser de dades CSV.

Afegeix una dependència amb papaparse

$ bun add papaparse 
$ bun add --dev @types/papaparse

Afegeix aquest import al fitxer index.ts:

import Papa from 'papaparse'

Imagina't que tenim aquestes dades CSV:

const csv = `name,age,email
John,32,jonn@gmail.com
Ruth,51,ruth@gmail.com`

Defineix el tipus Person per les nostres dades CSV:

import Papa from "papaparse"

interface Person {
    name: string
    age: number
    email: string
}

Amb aquesta interfície pots llegir les dades CSV:

const persons = Papa.parse<Person>(csv, {
  header: true,
  dynamicTyping: true
}).data

Al indicar que la primera fila és una capçalera ("header"), cada fila s'organitza pel nom del camp enlloc d'utilitzar un index.

Per defecte tot es converteix al tipus string.

Amb dynamicTyping: true fas que els números es converteixin en number i els booleans en boolean.

I ja pots mostrar tots els noms en una llista:

import Papa from 'papaparse'

interface Person {
  name: string
  age: number
  email: string
}

export default function App() {

  const csv = `name,age,email
John,32,jonn@gmail.com
Ruth,51,ruth@gmail.com`

  const persons = Papa.parse<Person>(csv, {
    header: true,
    dynamicTyping: true
  }).data

  return (
    <ul>
      {persons.map(person => <li>{person.name}</li>)}
    </ul>
  )

}

Enlloc de mostrar una llista, mostra tots els resultats en una taula:

return (
    <div className='container m-5'>
      <div className='row align-items-center'>
        <div className='col-6'>
          <h3 className='text-center'>Data</h3>
          <table className='table table-striped mt-5 text-center'>
            <tr><th>Name</th><th>Age</th><th>Email</th></tr>
            {persons.map(person => <tr><td>{person.name}</td><td>{person.age}</td><td>{person.email}</td></tr>)}
          </table>
        </div>
      </div>
    </div>
  )

Mou tot el codi a un fitxer FromString.tsx.

Modificar el fitxer App.tsx amb aquest codi:

import FromString  from "./FromString"

export default function App() {

  return <FromString/>

}

Fitxer remot

Pots treballar amb fitxer remots has de passar una URL i un funció "callback":

import { useEffect, useState } from "react"
import Papa from 'papaparse'


export default function App() {

  const [data, setData] = useState<any[]>([])

  useEffect(() => {

    // https://datos.gob.es/es/catalogo/ea0010587-numero-de-estudiantes-de-educacion-superior-que-han-recibido-becas-o-ayudas-segun-el-tipo-de-beca-o-ayuda-recibida-identificador-api-t13-p460-2019-l0-02014-px1

    const url = "https://www.ine.es/jaxi/files/tpx/csv_bdsc/43494.csv"
    Papa.parse(url, {
      // El fitxer utilitza ; com a delimitador enlloc de ,
      delimiter: ";",
      download: true,
      complete: function (results) {
        setData(results.data);
      }
    }
    )
  }, [])


  return (<><h3>Data</h3><ViewCSV csv={data} /></>
  )
}

// Funció que crea una taula amb el contingut del fitxer CSV
function ViewCSV({ csv }: { csv: any[][] }) {

  return <table className='table table-striped'>
    {csv.map(row => <tr>
      {row.map( item => <td>{item}</td> )}
      </tr>)}
  </table>

}

Gestiona l'error amb un missatge:

import { useEffect, useState } from "react"
import Papa from 'papaparse'

export default function App() {

  const [result, setResult] = useState<{ message: string, data: any[] }>({ message: "Descargando", data: [] })

  useEffect(() => {

    // https://datos.gob.es/es/catalogo/ea0010587-numero-de-estudiantes-de-educacion-superior-que-han-recibido-becas-o-ayudas-segun-el-tipo-de-beca-o-ayuda-recibida-identificador-api-t13-p460-2019-l0-02014-px1

    const url = "https://www.ine.es/jaxi/files/tpx/csv_bdsc/43494.csvXXX"
    Papa.parse(url, {
      // El fitxer utilitza ; com a delimitador enlloc de ,
      delimiter: ";",
      download: true,
      complete: function (results) {

        if (results.errors.length != 0) {
          setResult({ message: "Error", data: [] });

        } else {
          setResult({ message: "Descargado", data: results.data });
        }
      }
    }
    )
  }, [])


  return (
    <div className="container">
      <h3 className="text-center">Data</h3>
      <p className="border border-2 border-info rounded p-2 text-secondary">{result.message}</p>
      <ViewCSV csv={result.data} />
    </div>
  )
}

// Funció que crea una taula amb el contingut del fitxer CSV
function ViewCSV({ csv }: { csv: any[][] }) {

  return <table className='table table-striped'>
    {csv.map(row => <tr>
      {row.map(item => <td>{item}</td>)}
    </tr>)}
  </table>

}

Seguir explicat: https://www.papaparse.com/

Plot

https://github.com/javascriptdata/danfojs

TODO