react-native+expo读取手机本地XLSX/CSV文件转换为数组的问题问询
解决方案
你需要先通过expo-file-system读取URI对应的文件内容,再传递给XLSX库解析,具体实现如下:
步骤1:修改核心读取逻辑
你之前直接传入文件URI给XLSX.read()的方式在React Native环境下不生效,需要先把文件读取为Base64格式后再解析,修改后的excelboton方法代码:
const excelboton = async () => { const resultPermissions = await MediaLibrary.requestPermissionsAsync(); const resultPermissionsData = resultPermissions.status; if (resultPermissionsData === "denied"){ console.log("需要允许文件访问权限") return } const result = await DocumentPicker.getDocumentAsync({ copyToCacheDirectory:true, multiple:false, // 限制可选文件类型 type: [ 'text/csv', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // xlsx 'application/vnd.ms-excel' // xls ] }); if (result.canceled) return; const file = result.assets[0]; // 读取文件为Base64格式 const fileContent = await FileSystem.readAsStringAsync(file.uri, { encoding: FileSystem.EncodingType.Base64, }); // 解析文件内容 const workbook = XLSX.read(fileContent, { type: 'base64' }); // 取第一个工作表 const firstSheet = workbook.Sheets[workbook.SheetNames[0]]; // 转换为JSON数组,每一项对应表格的一行 const dataArray = XLSX.utils.sheet_to_json(firstSheet); console.log('解析得到的数组:', dataArray); };
完整修改后的组件代码
import React from "react"; import { StyleSheet } from "react-native"; import { Button, Input } from "react-native-elements"; import * as MediaLibrary from 'expo-media-library'; import * as DocumentPicker from 'expo-document-picker'; import * as XLSX from "xlsx"; import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view"; import * as FileSystem from "expo-file-system"; export default function Options() { const excelboton = async () => { const resultPermissions = await MediaLibrary.requestPermissionsAsync(); const resultPermissionsData = resultPermissions.status; if (resultPermissionsData === "denied"){ console.log("需要允许文件访问权限") return } const result = await DocumentPicker.getDocumentAsync({ copyToCacheDirectory:true, multiple:false, type: [ 'text/csv', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel' ] }); if (result.canceled) return; const file = result.assets[0]; const fileContent = await FileSystem.readAsStringAsync(file.uri, { encoding: FileSystem.EncodingType.Base64, }); const workbook = XLSX.read(fileContent, { type: 'base64' }); const firstSheet = workbook.Sheets[workbook.SheetNames[0]]; const dataArray = XLSX.utils.sheet_to_json(firstSheet); console.log('解析得到的数组:', dataArray); }; return ( <KeyboardAwareScrollView> <Input placeholder="Producto" containerStyle={styles.input} /> <Button title="EXCEL" containerStyle={styles.botoncontainer} buttonStyle={styles.boton} onPress={excelboton} /> </KeyboardAwareScrollView> ) } const styles = StyleSheet.create({ input: { marginHorizontal: 20, marginVertical: 10 }, botoncontainer: { marginHorizontal: 20, marginTop: 20 }, boton: { backgroundColor: '#2196F3' } })
注意事项
- 上面的代码会自动兼容CSV、XLS、XLSX三种格式,解析后得到的
dataArray就是你需要的表格数据数组 - 如果需要自定义表头映射、空值处理,可以在调用
XLSX.utils.sheet_to_json时传入配置参数,比如设置header: 1可以得到纯二维数组格式的数据 - 安卓13及以上版本需要额外配置存储权限,你可以在app.json的expo.android.permissions节点添加
READ_MEDIA_IMAGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO权限
内容的提问来源于stack exchange,提问作者csaqu
相关产品推荐
相关产品推荐

