react-native-document-picker一个适合react native打开本地文件,上传文件的组件;也可直接用react-native-fetch-blob

云煌
2023-12-01

一些配置介绍

import DocumentPicker from 'react-native-document-picker';

const FileTypes = {
    All: DocumentPicker.types.allFiles,// All document types, on Android this is */*, on iOS is public.content (note that some binary and archive types do not inherit from public.content)
    Image: DocumentPicker.types.images, // All image types (image/* or public.image)
    Text: DocumentPicker.types.plainText, // Plain text files ie: .txt (text/plain or public.plain-text)
    Audio: DocumentPicker.types.audio, // All audio types (audio/* or public.audio)
    PDF: DocumentPicker.types.pdf, // PDF documents (application/pdf or com.adobe.pdf)
    Zip: DocumentPicker.types.zip, // Zip files (application/zip or public.zip-archive)
    Csv: DocumentPicker.types.csv, //Csv files (text/csv or public.comma-separated-values-text)
};

let Manager = {
    // Pick a single file
    pickerSingleFile: (fileType, callback, errorCallback) => {
        try {
            DocumentPicker.pick({
                type: [FileTypes[fileType]],
            }).then(res => {
                console.log(
                    res.uri,
                    res.type, // mime type
                    res.name,
                    res.size
                );
                if (callback) {
                    callback(res);
                }
            }).catch(error => {
                console.log(error);
                if (errorCallback) {
                    errorCallback(error);
                }
            });
        } catch (err) {
            if (errorCallback) {
                errorCallback(err);
            }
            if (DocumentPicker.isCancel(err)) {
                // User cancelled the picker, exit any dialogs or menus and move on
            } else {
                throw err;
            }
        }
    },
    PickMultipleFiles: (fileType, callback, errorCallback) => {
        // Pick multiple files
        try {
            DocumentPicker.pickMultiple({
                type: [FileTypes[fileType]],
            }).then(results => {
                for (const res of results) {
                    console.log(
                        res.uri,
                        res.type, // mime type
                        res.name,
                        res.size
                    );
                }
                if (callback) {
                    callback(results);
                }
            });
        } catch (err) {
            if (errorCallback) {
                errorCallback(err);
            }
            if (DocumentPicker.isCancel(err)) {
                // User cancelled the picker, exit any dialogs or menus and move on
            } else {
                throw err;
            }
        }
    },
};


module.exports = Manager;

实际使用,代码如下图所示

还需要借助另外一个组件:react-native-fetch-blob

pickFile = async () => {
try {
  const res = await DocumentPicker.pick({
    type: [DocumentPicker.types.allFiles],
  });

  console.log(res.uri);
  //output: content://com.android.providers.media.documents/document/image%3A4055

  RNFetchBlob.fs
    .stat(res.uri)
    .then((stats) => {
      console.log(stats.path);
 //output: /storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20200831-WA0019.jpg
    })
    .catch((err) => {
      console.log(err);
    });
} catch (err) {
  if (DocumentPicker.isCancel(err)) {
  } else {
    throw err;
  }
}};

代码二:直接用react-native-fetch-blob

引入
import RNFileSelector from "react-native-file-selector";
const RNFS = require('react-native-fs');
函数
    // 上传附件
    onSwitchToFile = () => {
      RNFileSelector.Show(
          {
              title: '请选择文件',
              onDone: (path) => {  
                  RNFS.read('file://' + path , 20971520 , 0 , 'base64')
                  .then(res => {
                      const size = res.length - (res.length / 8) * 2
                      
                      console.log('文件大小为: ' + (size / 1024 / 1024).toFixed(2) + 'M' )

                      if (size > 10485760) {
                        toast("文件大小不能超过10M!")
                        return false
                      }
  
                      let url = global.HOST + "media/upload"
                      let formData = new FormData()
                      let file = {
                          uri: 'file://' + path,
                          type: 'multipart/form-data',
                          name: path || 'file',
                      }
                      
                      formData.append("file", file)
                      
                      Net.upload(url, formData, res => {
                        if (res.result === 0) {
                          let fileName = path.substr(path.lastIndexOf("/") + 1)
                          this.setState({
                            fileName,
                            fileUrl: res.ret
                          })
                        }
                      })
                  })
                  .catch(error => {
                    toast('文件上传失败!请重试!')
                    console.log(error)
                  })
                  
              },
              onCancel: () => {
                  console.log('cancelled')
              }
          }
      )
    }

页面中:
   
            <SafeAreaView style={{ backgroundColor: '#F2F2F2' }}>
                <ScrollView contentContainerStyle={{ padding: 10, backgroundColor: '#FFF', marginTop: 10 }}>
                    <View style={[Styles.itemTitleContainer, { borderBottomWidth: 0 }]}>
                        <View style={Styles.item_title}>
                            <Text style={Styles.itemText}>上传附件</Text>
                        </View>
                        <View>
                          <TouchableOpacity 
                            style={{ 
                              borderColor: '#DDD', 
                              borderWidth: .5, 
                              paddingLeft: 15, 
                              paddingRight: 15, 
                              paddingTop: 8,
                              paddingBottom: 8,
                              flexDirection:"row",
                              alignItems: 'center',
                              justifyContent: 'center'
                            }} 
                            onPress={() => this.onSwitchToFile()}
                          >
                                <Text>
                                  {
                                    this.state.fileName
                                    ? this.state.fileName
                                    : <Ionicons style={{ color: "#DDD" }} name="md-add" size={25} />
                                  }
                                </Text>
                          </TouchableOpacity>
                          {
                            this.state.fileName &&
                            <View 
                              style={{
                                position: 'absolute',
                                top: -5,
                                right: -5
                              }}
                            >
                              <Text 
                                onPress={() => {
                                  this.setState({
                                    fileName: null,
                                    fileUrl: null
                                  })
                                }}
                                style={{
                                  width: 12,
                                  height: 12,
                                  borderRadius: 6,
                                  backgroundColor: '#ddd',
                                  fontSize: 10,
                                  textAlign: 'center',
                                  lineHeight: 12,
                                  color: '#fff'
                                }} 
                              >
                                x
                              </Text>
                            </View>
                          }
                        </View>
                    </View>
                </ScrollView>
                

 

 类似资料: