如何在ClojureScript中用SheetJS读取Excel文件(基于re-frame项目)
在re-frame项目中使用SheetJS读取Excel工作表数据
以下是结合ClojureScript与re-frame状态管理模式的具体实现步骤:
1. 引入SheetJS依赖
先确保项目已安装SheetJS:
npm install xlsx
在ClojureScript文件中通过ES模块引入:
(ns your.app.namespace (:require ["xlsx" :as xlsx]))
2. 创建文件选择UI
添加文件输入组件,触发re-frame事件处理文件:
(defn excel-file-picker [] [:div [:label "选择Excel文件:"] [:input {:type "file" :accept ".xlsx,.xls,.csv" :on-change #(re-frame/dispatch [:parse-excel-file (-> % .-target .-files (aget 0))])}]])
3. 定义re-frame事件处理解析逻辑
首先定义文件解析事件,利用SheetJS API读取并转换文件内容:
(re-frame/reg-event-fx :parse-excel-file (fn [{:keys [db]} [_ file]] (let [reader (js/FileReader.)] ; 处理文件加载完成回调 (set! (.-onload reader) (fn [e] (let [array-buffer (-> e .-target .-result) workbook (xlsx/read array-buffer {:type "array"}) ; 获取第一个工作表名称(可替换为指定表名) sheet-name (-> workbook .-SheetNames (aget 0)) ; 将工作表转换为JSON格式 sheet-data (xlsx/utils/sheet_to_json (-> workbook .-Sheets (aget sheet-name)))] (re-frame/dispatch [:store-excel-data sheet-data])))) ; 读取文件为ArrayBuffer格式 (.readAsArrayBuffer reader file)) {:db db}))
接着定义事件将解析后的数据存入app-db:
(re-frame/reg-event-db :store-excel-data (fn [db [_ sheet-data]] (assoc db :excel/sheet-data sheet-data)))
4. 定义订阅获取数据
创建订阅来访问app-db中的Excel数据:
(re-frame/reg-sub :excel/sheet-data (fn [db] (:excel/sheet-data db)))
5. 渲染解析后的数据
在视图中通过订阅获取数据并展示(以表格为例):
(defn excel-data-view [] (let [sheet-data @(re-frame/subscribe [:excel/sheet-data])] (if sheet-data [:table {:style {:border-collapse "collapse"}} [:thead [:tr (for [header (keys (first sheet-data))] [:th {:style {:border "1px solid #ccc" :padding "8px"}} header])]] [:tbody (for [row sheet-data] [:tr (for [value (vals row)] [:td {:style {:border "1px solid #ccc" :padding "8px"}} value])])]] [:p "请选择Excel文件以查看数据"])))
可选优化与注意事项
- 自定义解析规则:
sheet_to_json支持多种配置,比如:header "A"会用列标(A、B、C...)作为键,:header 1会返回数组形式的行数据,可根据业务需求调整。 - 错误处理:可给FileReader添加
onerror回调,触发错误事件存储错误信息并在视图中展示提示。 - 大文件处理:超大Excel文件建议用Web Workers避免阻塞主线程,需注意re-frame事件与Worker的通信逻辑。
内容的提问来源于stack exchange,提问作者Yavuz Kuru
相关产品推荐
相关产品推荐

