Displaying specific data from CSV file

Good day Typst Community!

I’ve been trying out Typst for a couple days now before our company purchases the Pro version for our report creation.

Some of our use cases involve importing data from a CSV file and then displaying it as a table. I have some questions on the same:

  1. How do we include the european notation (using commas instead of dots) for floating numbers? In general a double quotes around the value should suffice (or using curly brackets in the case of LaTex). However, this doesn’t seem to translate in Typst? Any leads on this?
  2. Once I import the csv as a dictionary (where each column is tied to the header key), I’d like to only display certain columns. May I know how I can parse the csv output to be able to extract and display only specific columns?

I would appreciate your help and thank you in advance for your inputs!

1 Like

Looks like I figured out the second part of my question (importing the CSV as an array). Posting example code below:

#let results = csv("sampleCSV.csv",
          row-type: array)
#figure(
  table(
    // columns: 4,
    table.header([Node], [Voltage Level $ k V^2 $]),
    columns : 2,
        fill: (_, y) => if y == 0 {
      gray.lighten(75%)
    }, 
    // ..results.flatten(),
    ..for(node,_,pFaults,..) in results.slice(1){(node, pFaults)}) //this is where I am selective in picking the 1st column and 3rd column for view
  )
  ,
    caption: [Dummy results from a CSV file ],
) <results_A01>  

Hello!

For number localization, you can take a look at this GitHub issue. Quoting @laurmaedje

Automatic locale-aware number formatting will happen

In the mean time @Andrew provides a simple solution for “1.1” to “1,1”.

#show regex("\d+\.\d+"): num => num.text.replace(".", ",")

You can restrict this to tables by only wrapping it in a table show rule.

For filtering columns in a csv, you can map-slice if the columns are contingous, or map-at

#let filtered = t.map(
  it => {
    // it.slice(0, 2)
    (it.at(0), it.at(1))
  }
)

The object given by csv is an array of rows, hence you apply map which operates on each row, selecting only the columns you want by index, starting from 0. Your solution also works! :smiley:

1 Like

I guess your questions have been answered already but here’s an alternative way to do it using row-type: dictionary and parsing the numbers to actual floating point numbers (instead of changing how typst shows them):

// Content of CSV file
#let csv-data = ```
col1,col2,col3
"1,1","2,1","3,1"
"1,2","2,2","3,2"
```.text

// To load a file, replace csv.decode(string) with csv(filename)
#let data = csv.decode(csv-data, row-type: dictionary)

// Parse a float encoded as string with comma decimal separator
#let eu-float(s) = float(s.replace(",", "."))

#let parse-values(data) = {
  // Get desired values from each row
  data.map(row => (row.col1, row.col3))
      // Flatten to a simple array of values
      .flatten()
      // Parse strings to floats
      .map(eu-float)
}

#parse-values(data)
1 Like

I recommend you to take a look at the excellent (and not very well known) package tabut.

Here is my code to handle csv files selecting columns:

#let table-tabut-csv(csvinput, colnames, align: auto, ..args) = {
  let data-columns = {
    let aux = ()

    for colname in colnames {
        aux.push((header: [], func: r => r.at(colname)))
    }

    (aux)
  }

  let datacsv = records-from-csv(csvinput)
  let celdas-tabut = tabut-cells(
    datacsv,
    data-columns,
    headers: false,
    align: align
  )

  table(
    stroke: none,
    table.hline(),
    ..args,
    ..celdas-tabut,
    table.hline()
  )
}

Then, you use it only with:

table-tabut-csv(csv("input.csv"), ("col1", "col3"))

And you get a table formatted as you defined it in the function. Obviously, you can also get the tabut-cells and do the formatting thing in another code. Perhaps there is a fancier way to do this, even you can work with tabut to do more tricks with your data. Take a look at their documentation (and more specifically, documentation of csv files).

As an example showing only columns col1 and col3 from an input.csv file.

If your company or you are profiting from table generation, please also consider donating to PgBiel.

1 Like