Refine v5 中使用 Mantine 实现 CSV 导入导出:useImport 与 useExport 实战指南
Refine v5 中使用 Mantine 实现 CSV 导入导出useImport 与 useExport 实战指南【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine导读在数据密集型后台应用中通过 CSV 进行批量数据录入与迁移是提效的关键手段。本文以 Refine 官方示例 import-export-mantine 为蓝本系统讲解如何在 Refine v5 的 Mantine 项目中用useImport、useExport两个核心 Hook 以及ImportButton /、ExportButton /两个 UI 组件快速实现 CSV 的批量导入与导出并深入源码剖析其底层执行机制Papa Parse 解析、分批写入、getList分页拉取等帮助你写出可投入生产环境的导入导出功能。Refine 允许你将数据以 CSV 文件的形式导出和导入。通过直接在 CSV 数据上定义模型操作你可以快速完成 CSV 的导入与导出。核心入口是useImport与useExport两个 Hook完整的官方指南参见 CSV Import - Export 指南。一、核心概念面向 CSV 数据的两个 HookRefine 将批量导入/导出抽象为两个对称的 HookHook方向底层数据方法核心依赖useImport文件 → 数据源create/createManyPapa Parse 解析 CSV 文件useExport数据源 → 文件getListPapa Parse 生成 CSV 文件并触发浏览器下载导入ImportuseImport允许你从 CSV 文件导入数据。文件中的每一行都会按照你的配置调用数据提供者的create或createMany方法。内部使用 Papa Parse 解析文件内容。导出ExportuseExport允许你将数据导出为 CSV 文件。它调用数据提供者的getList方法拉取数据并将其下载为 CSV 文件。内部同样由 Papa Parse 负责生成 CSV。iframe 限制CSV 文件的下载功能在 iframe如 live-previews 沙箱内无法生效。请将代码复制到自己的项目中运行以查看实际效果。二、导入实战useImport 完整用法2.1 最小可用示例在refinedev/core中引入useImport把返回的inputProps展开到一个input typefile上即可获得选择 CSV 文件 → 自动解析 → 逐行写入数据源的完整链路import React, { useState } from react; import { useImport, useList } from refinedev/core; export const HomePage () { const { result } useList({ resource: products, sorters: [{ field: id, order: desc }], }); const products result?.data; const [importProgress, setImportProgress] useState({ processed: 0, total: 0, }); const { inputProps, isLoading } useImportIProduct({ resource: products, onFinish: () { alert(Import completed!); }, onProgress: (progress) { setImportProgress({ processed: progress.processedAmount, total: progress.totalAmount, }); }, }); return ( div style{{ padding: 16px }} label {isLoading ? ( p {importProgress.processed} / {importProgress.total} /p ) : ( pImport CSV/p )} input namecsv {...inputProps} / /label {products?.map((product) ( div key{product.id} h4[ID: {product.id}] - {product.name}/h4 p{product.description}/p /div ))} /div ); }; interface IProduct { id: string; name: string; description: string; material: string; price: number; category: { id: string; }; }配套的App.tsx只需注册一个普通资源即可import { Refine } from refinedev/core; import dataProvider from refinedev/simple-rest; import { HomePage } from ./home-page; const App: React.FC () { return ( Refine dataProvider{dataProvider(https://api.fake-rest.refine.dev)} resources{[{ name: products }]} HomePage / /Refine ); };2.2 用于测试的 CSV 文件你可以用下面的products.csv直接测试导入功能注意嵌套对象需以 JSON 字符串形式写在引号中内部引号用转义name,material,description,price,category Test Product 1,Test Material 1,Test Description 1,100,{id:1} Test Product 2,Test Material 2,Test Description 2,200,{id:2} Test Product 3,Test Material 3,Test Description 3,300,{id:3}2.3 参数详解源码级从 useImport 实现 可以看出useImport的完整配置项如下参数类型默认值说明resourcestring路由读取到的资源名数据交互所用的资源名mapData(item) TVariables原样返回对每条解析出的 CSV 记录做映射映射结果将作为写入数据源的变量paparseOptionspapaparse.ParseConfig—自定义 Papa Parse 解析选项batchSizenumberNumber.MAX_SAFE_INTEGER请求批大小。为1时逐条调用create大于1时按批调用createMany此时数据提供者必须实现createManyonFinish(results) void—所有请求完成后回调参数包含succeeded与errored两组结果onProgress(params) void—上传进度回调percentage processedAmount / totalAmount * 100metaMetaQuery—传给数据提供者的元数据查询dataProviderNamestring—多数据提供者场景下指定使用的提供者返回对象inputProps可直接展开到input上的属性accept固定为.csv、mutationResultcreate或createMany的 mutation 结果、isLoading与handleChange。2.4 底层执行流程从 handleChange 实现 可以还原出完整执行链路解析papaparse.parse(file, { complete: ... })将文件解析为二维数组映射importCSVMapper(data, mapData)将每行转换为提交变量分派batchSize 1时逐条执行create.mutateAsync并通过sequentialPromises串行处理保证顺序与错误隔离否则用lodash/chunk将数据切成batchSize大小的批次逐批执行createMany.mutateAsync汇总所有批次完成后将结果拆分为succeeded/errored两组传给onFinish同时每个批次完成都会累加processedAmount驱动onProgress。代码中还特意关闭了单条记录的通知successNotification: false, errorNotification: false避免批量导入时产生通知风暴——这是生产实践中的一个重要细节。三、导出实战useExport 完整用法3.1 最小可用示例useExport返回triggerExport触发导出与isLoading导出中状态。mapData常用于将嵌套对象序列化为 CSV 可读的字符串import React from react; import { useExport, useList } from refinedev/core; export const HomePage () { const { result } useList({ resource: products }); const products result?.data; const { triggerExport, isLoading } useExportIProduct({ resource: products, mapData: (item) { return { ...item, // category is an object, we need to stringify it category: JSON.stringify(item.category), }; }, }); return ( div style{{ padding: 16px }} button onClick{triggerExport} disabled{isLoading} {isLoading ? Exporting... : Export Products} /button {products?.map((product) ( div key{product.id} h4[ID: {product.id}] - {product.name}/h4 p{product.description}/p /div ))} /div ); };3.2 参数详解源码级从 useExport 实现 提取完整配置项参数类型默认值说明resourcestring路由读取到的资源名数据交互所用资源名mapData(item) TVariables原样返回每条记录的映射函数映射结果写入文件内容sortersCrudSort[]—导出记录的排序规则filtersCrudFilter[]—导出记录的过滤规则maxItemCountnumber—最大导出条数达到后停止拉取pageSizenumber20分批拉取时的每页大小对应数据提供者getList的分页unparseConfigpapaparse.UnparseConfig{ quotes: true, header: true }生成 CSV 时的配置metaMetaQuery—传给数据提供者的元数据dataProviderNamestring—多数据提供者场景下指定提供者onError(error) void—导出错误回调downloadbooleantrue是否在浏览器中触发 CSV 下载filenamestring{资源复数名}-{本地化时间}自定义导出文件名空格会被替换为下划线useTextFilebooleanfalse是否导出为.txt纯文本文件useBombooleantrue是否在文件头写入 BOM\ufeff保证 Excel 等工具正确识别 UTF-8titlestringMy Generated Report导出文件首行的标题文字showTitlebooleanfalse是否在导出文件中显示标题返回对象isLoading与triggerExport: () Promisestring | undefined返回生成的 CSV 字符串方便你在触发下载之外继续处理。3.3 底层执行流程从 triggerExport 实现 可还原出导出链路分页拉取循环调用getListpagination固定为{ currentPage, pageSize: 20, mode: server }每轮累加数据终止条件当rawData.length maxItemCount此时截断到maxItemCount或total rawData.length已拉完时停止生成 CSVpapaparse.unparse(rawData.map(mapData), { quotes: true, header: true, ...unparseConfig })若showTitle为真则在文件首行插入title下载在浏览器环境下且download ! false通过downloadInBrowser触发下载文件名形如{filename 空格替换为 _}.csv或.txt内容为\ufeff csv受useBom控制MIME 类型为text/csv;charsetutf8;。四、Mantine 组件集成ImportButton 与 ExportButtonRefine 为各 UI 集成提供了与上述 Hook 兼容的按钮组件。在 Mantine 中二者分别位于 packages/mantine/src/components/buttons/import/index.tsx 与 packages/mantine/src/components/buttons/export/index.tsx均基于 Mantine 的Button与tabler/icons-react的IconFileImport/IconFileExport图标实现。ImportButton /接受inputProps来自useImport、hideText、loading等属性内部将input {...inputProps} hidden包在label中实现点击按钮即选择文件并暴露data-testid{RefineButtonTestIds.ImportButton}便于测试。ExportButton /接受onClick通常绑定triggerExport与loading。4.1 在 Mantine 表格页面中组合使用官方示例 examples/import-export-mantine 的 PostList 页面 完整展示了二者的组合方式import { List, DeleteButton, ImportButton, ExportButton, DateField, } from refinedev/mantine; import { useExport, useImport, useNotification } from refinedev/core; const { open } useNotification(); const { inputProps, isLoading } useImport({ onFinish: () { open?.({ message: Import successfully completed, type: success, }); }, }); const { triggerExport, isLoading: exportLoading } useExportIPost({ mapData: (item) { return { title: item.title, content: item.content, status: item.status, categoryId: item.category.id, }; }, maxItemCount: 50, }); return ( List headerButtons{ ImportButton loading{isLoading} inputProps{inputProps} / ExportButton loading{exportLoading} onClick{triggerExport} / / } {/* Mantine Table 表格内容 */} /List );要点解读导入完成时通过useNotification弹出Import successfully completed成功通知导出时通过mapData将category.id等嵌套字段拍平为扁平列并设置maxItemCount: 50限制单次导出规模ImportButton/ExportButton的loading分别绑定两个 Hook 的加载态防止重复触发。4.2 示例项目运行方式该示例完整源码位于 examples/import-export-mantine其 App.tsx 展示了 Mantine 项目的标准装配MantineProvider使用RefineThemes.BlueNotificationsProviderRefine数据提供者为refinedev/simple-rest指向https://api.fake-rest.refine.dev资源postsThemedLayout布局。本地运行方式npm create refine-applatest -- --example import-export-mantine或进入 examples/import-export-mantine 目录安装依赖后启动开发服务器。五、生产实践建议嵌套对象必须序列化CSV 是扁平的表格格式category这类嵌套对象在导入前应写成JSON.stringify(item.category)见 use-export 示例导入时再在mapData中反序列化。批量大小与createMany导入时batchSize默认是Number.MAX_SAFE_INTEGER一次性全部提交。若数据量较大或数据提供者未实现createMany请显式设置batchSize: 1逐条写入见 useImport 分派逻辑。利用进度回调通过onProgress计算processedAmount / totalAmount * 100可在导入按钮上展示百分比进度提升大数据量导入的交互体验。控制导出规模useExport默认以pageSize: 20循环拉取所有数据配合maxItemCount与filters/sorters可以精确控制导出的数据子集与顺序见 useExport 拉取逻辑。兼容 Excel保持默认的useBom: true写入 UTF-8 BOM可避免中文内容在 Excel 中乱码如需要给文件加标题行可开启showTitle与title。结语CSV 导入导出是后台管理系统中数据录入与迁移的基础设施。通过useImport/useExport两个 Hook 配合 Mantine 的ImportButton //ExportButton /Refine 用极少的样板代码就完成了从文件解析、分批写入、进度回传到分页拉取、CSV 生成、浏览器下载的完整闭环。对照 CSV Import - Export 指南 与 import-export-mantine 示例再结合 useImport 与 useExport 的源码你可以根据业务需要自由裁剪参数快速落地一套稳定可靠的 CSV 导入导出方案。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

K8s就绪探针实战:解决Java应用数据库故障时的服务假活问题

K8s就绪探针实战:解决Java应用数据库故障时的服务假活问题

去年做 MySQL 主备切换演练,我盯着监控屏看到了一个很典型的场景:数据库已经切到备库,连接闪断了大概 40 秒,按理说数据库恢复后业务应该很快恢复正常。但实际却是客户端在随后一分多钟里持续报 502/504,应用日志里全是…

2026/10/26 10:17:30 阅读更多 →
AI工具如何提升本科论文写作效率

AI工具如何提升本科论文写作效率

1. 本科生论文写作的痛点与AI工具的价值本科毕业论文是每个大学生必须跨越的一道坎,但现实中90%的学生都会遇到这些典型问题:文献综述找不到方向、数据收集耗时费力、格式调整反复折腾、查重降重令人崩溃。去年某高校调研显示,平均每位毕业生…

2026/10/26 10:17:33 阅读更多 →
PSO优化BP神经网络实现多特征分类的稳定提升方法

PSO优化BP神经网络实现多特征分类的稳定提升方法

简介:本资源是一套面向机器学习初学者与MATLAB实践者的PSO-BP神经网络分类预测完整实现方案,聚焦多特征输入下的四分类任务建模与优化。资源提供从粒子群算法(PSO)自动调参BP神经网络、特征映射、训练验证到结果可视化的一站式代码…

2026/10/26 10:17:36 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/27 17:33:32 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/27 4:06:49 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/27 7:21:53 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/27 18:20:50 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/27 6:20:47 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/27 4:06:50 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 13:55:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 7:21:50 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 19:19:37 阅读更多 →