Search code examples
clojurescriptreagent

How can ı do read excel with sheetjs in Clojurescript?


I have a excel file. I imported sheetjs (https://sheetjs.com/). I want to read to sheet data. How can ı do read excel with sheetjs in Clojurescript?

The project written with https://github.com/day8/re-frame


Solution

  • This should put you in the right direction - it opens a file called datadump.xlsx in the same folder as index.html (the root folder of your app). Easy to adapt to upload a file through a form. In the main namespace you'd just call (data/read-local-file).

    (ns data
      (:require [reagent.core :as r]
                [reagent.dom :as rd]
                [re-frame.core :as rf]
                ["xlsx" :as XLSX]))
    
    (defn read-sheet [wb sheet-name]
      (let [sheet (aget (. wb -Sheets) sheet-name)
            data (XLSX/utils.sheet_to_json sheet #js {:header 1})
            dataclj (js->clj data)
            kk (map keyword (first dataclj))
            outdata (into [] (for [line (rest dataclj)] (zipmap kk line)))]
    
        (rf/dispatch [:source-data outdata])))
    
    (defn read-local-file []
      (let [xhr (js/XMLHttpRequest.)]
        (.open xhr "GET" "datadump.xlsx" true)
        (set! (.-responseType xhr) "blob")
        (set! (.-onload xhr)
              (fn []
                (let [reader (js/FileReader.)]
                  (.readAsArrayBuffer reader (.-response xhr))
                  (set! (.-onload reader)
                        (fn [evt]
                          (let [ab (-> evt .-target .-result)
                                wb (XLSX/read ab #js {:type "array" :cellDates true})
                                sn (. wb -SheetNames)]
                            (read-sheet wb (first sn))))))))
        (.send xhr)))