事件背景:最近在寫一個(gè)項(xiàng)目击喂,要求本地打開维苔、查看和打開遠(yuǎn)程的文檔碰辅。找到了一個(gè)組件懂昂,使用起來挺方便的。就分享一下没宾。我是配合react-native-fs實(shí)用的凌彬,fs配置的一些東西看我另一篇隨筆沸柔。
react-native-doc-viewer,可以在手機(jī)上直接打開文檔铲敛,支持遠(yuǎn)程和本地文檔褐澎。
支持的文檔格式:xls,ppt,doc,xlsx,pptx,docx,png,jpg,pdf,mp4。支持iOS和Android伐蒋。
組件名稱:react-native-doc-viewer
首先安裝:npm install react-native-doc-viewer --save
其次自動(dòng)鏈接:react-native link react-native-doc-viewer
????????按理說是自動(dòng)連接是可以的工三。可是程序運(yùn)行一下發(fā)現(xiàn)還是報(bào)錯(cuò)先鱼。只能手動(dòng)來了。
先附上npm網(wǎng)址:https://www.npmjs.com/package/react-native-doc-viewer
檢查并鏈接:
一、ios端:
1芹彬、在XCode中玻熙,在項(xiàng)目導(dǎo)航器中,右鍵單擊Libraries?Add Files to [你的項(xiàng)目名字]
2宏多、轉(zhuǎn)到node_modules??react-native-doc-viewer并添加RNReactNativeDocViewer.xcodeproj
3儿惫、在XCode中,在項(xiàng)目導(dǎo)航器中伸但,選擇您的項(xiàng)目肾请。添加libRNReactNativeDocViewer.a到項(xiàng)目的Build Phases?Link Binary With Libraries
劃重點(diǎn),我的以上三條都鏈接上了更胖。只有下面的沒有鏈接上筐喳。
鏈接的框架和庫必須具有此2個(gè)庫(AssetsLibrary.framework和QuickLock.framework)
注意當(dāng)顯示http鏈接時(shí),不要忘記將APP傳輸安全設(shè)置 - >允許任意加載設(shè)置為YES
在info.plist里沒有的話添加上函喉。
二避归、android配置
去看npm網(wǎng)址吧,我的是直接連接一下就自動(dòng)配置上了管呵,所以懶得整理了梳毙。
附上API:
openDoc 打開遠(yuǎn)程貨或本地文檔
openDocb64 打開Base64字符串格式文檔
openDocBinaryinUrl 打開二進(jìn)制文件
playMovie 打開視頻文件
制作這個(gè)組件的作者估計(jì)是沒時(shí)間寫很詳細(xì),所以npm上也不是很詳細(xì)捐下。下面附上我寫的一部分程序账锹。
import React, { Component } from 'react';
import {
? ? StyleSheet,Text,View,
? ? Platform,Button,Alert,ActivityIndicator
} from 'react-native';
import OpenFile from 'react-native-doc-viewer';
var RNFS = require('react-native-fs');
//保存路徑可以跳進(jìn)去看,具體自己選擇
var SavePath = Platform.OS === 'ios' ? RNFS.LibraryDirectoryPath : RNFS.ExternalDirectoryPath;
export default class Component extends Component {
? ? static navigationOptions = ({ navigation }) => ({
? ? ? ? title: `${navigation.state.params.name}`,
? ? });
? ? state = { animating: false }
//首先下載文件
? ? ?componentDidMount() {
? ? ? alert("開始")
? ? RNFS.exists(SavePath + "demo.docx").then(
? ? ? ? //判斷文件是否已存在坷襟,返回result為true說明存在奸柬,result為false說明不存在
? ? ? ? (result)=>{
? ? ? ? ? ? console.log(result);
? ? ? ? ? ? if(!result){
? ? ? ? ? ? ? ? var DownloadFileOptions = {
? ? ? ? ? ? ? ? ? ? fromUrl: "https://calibre-ebook.com/downloads/demos/demo.docx",// 下載文件的URL
? ? ? ? ? ? ? ? ? ? toFile: SavePath+"/demo.docx",? ? ? ? // 將文件保存到的本地文件系統(tǒng)路徑
? ? ? ? ? ? ? ? ? ? //進(jìn)度條
? ? ? ? ? ? ? ? ? ? begin: (res) => {
? ? ? ? ? ? ? ? ? ? ? ? console.log('begin', res);
? ? ? ? ? ? ? ? ? ? ? ? console.log('contentLength:', res.contentLength / 1024 / 1024, 'M');
? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? progress: (res) => {
? ? ? ? ? ? ? ? ? ? ? ? let pro = res.bytesWritten / res.contentLength;
? ? ? ? ? ? ? ? ? ? ? ? console.log(pro);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? const ret = RNFS.downloadFile(DownloadFileOptions);
? ? ? ? ? ? ? ? ret.promise.then(res => {
? ? ? ? ? ? ? ? ? ? console.log('success', res);
? ? ? ? ? ? ? ? ? ? console.log('file://' + DownloadFileOptions.toFile)
? ? ? ? ? ? ? ? }).catch(err => {
? ? ? ? ? ? ? ? ? ? console.log('err', err);
? ? ? ? ? ? ? ? });
? ? ? ? ? ? }
? ? ? ? }
? ? ).catch(
? ? )
}
//打開本地文件
? ? handlePressLocal = () => {
? ? ? ? this.setState({ animating: true });
? ? ? ? if (Platform.OS === 'ios') {
? ? ? ? ? ? OpenFile.openDoc([{
? ? ? ? ? ? ? ? url: SavePath + "/demo.docx",
? ? ? ? ? ? ? ? fileNameOptional: "白皮書"
? ? ? ? ? ? }], (error, url) => {
? ? ? ? ? ? ? ? if (error) {
? ? ? ? ? ? ? ? ? ? this.setState({ animating: false });
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? this.setState({ animating: false });
? ? ? ? ? ? ? ? ? ? console.log(url)
? ? ? ? ? ? ? ? }
? ? ? ? ? ? })
? ? ? ? } else {
? ? ? ? ? ? OpenFile.openDoc([{
? ? ? ? ? ? ? ? url: "file://"+SavePath+"/demo.docx",//打開本地文件必須加上file://
? ? ? ? ? ? ? ? fileName: "白皮書",
? ? ? ? ? ? ? ? cache: true,
? ? ? ? ? ? ? ? fileType: "docx"
? ? ? ? ? ? }], (error, url) => {
? ? ? ? ? ? ? ? if (error) {
? ? ? ? ? ? ? ? ? ? console. log(error)
? ? ? ? ? ? ? ? ? ? this.setState({ animating: false });
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? this.setState({ animating: false });
? ? ? ? ? ? ? ? ? ? console.log(url)
? ? ? ? ? ? ? ? ? ? alert(url)
? ? ? ? ? ? ? ? }
? ? ? ? ? ? })
? ? ? ? }
? ? }
//打開遠(yuǎn)程文件
handlePress = () => {
? ? ? ? this.setState({ animating: true });
? ? ? ? if (Platform.OS === 'ios') {
? ? ? ? ? ? OpenFile.openDoc([{
? ? ? ? ? ? ? ? url: "https://calibre-ebook.com/downloads/demos/demo.docx",
? ? ? ? ? ? ? ? fileNameOptional: "test filename"
? ? ? ? ? ? }], (error, url) => {
? ? ? ? ? ? ? ? if (error) {
? ? ? ? ? ? ? ? ? ? this.setState({ animating: false });
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? this.setState({ animating: false });
? ? ? ? ? ? ? ? ? ? console.log(url)
? ? ? ? ? ? ? ? }
? ? ? ? ? ? })
? ? ? ? } else {
? ? ? ? ? ? //Android
? ? ? ? ? ? this.setState({ animating: true });
? ? ? ? ? ? OpenFile.openDoc([{
? ? ? ? ? ? ? ? url: "https://www.huf-haus.com/fileadmin/Bilder/Header/ART_3/Header_HUF_Haus_ART_3___1_.jpg", // Local "file://" + filepath
? ? ? ? ? ? ? ? fileName: "sample",
? ? ? ? ? ? ? ? cache: false,
? ? ? ? ? ? ? ? fileType: "jpg"
? ? ? ? ? ? }], (error, url) => {
? ? ? ? ? ? ? ? if (error) {
? ? ? ? ? ? ? ? ? ? this.setState({ animating: false });
? ? ? ? ? ? ? ? ? ? console.error(error);
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? this.setState({ animating: false });
? ? ? ? ? ? ? ? ? ? console.log(url)
? ? ? ? ? ? ? ? }
? ? ? ? ? ? })
? ? ? ? }
? ? }
setToggleTimeout() {
? ? ? ? this.setTimeout(() => {
? ? ? ? ? ? this.setState({ animating: !this.state.animating });
? ? ? ? ? ? this.setToggleTimeout();
? ? ? ? }, 2000);
? ? }
render() {
? ? ? ? return (
? ? ? ? ? ? <View style={styles.container}>
? ? ? ? ? ? ? ? <ActivityIndicator
? ? ? ? ? ? ? ? ? ? animating={this.state.animating}
? ? ? ? ? ? ? ? ? ? style={[styles.centering, { height: 80 }]}
? ? ? ? ? ? ? ? ? ? size="large" />
? ? ? ? ? ? ? ? <Text style={styles.welcome}>
? ? ? ? ? ? ? ? ? ? Doc Viewer React Native
? ? ? ? ? ? ? ? </Text>
? ? ? ? ? ? ? ? <Button
? ? ? ? ? ? ? ? ? ? onPress={this.handlePress.bind(this)}
? ? ? ? ? ? ? ? ? ? title="打開遠(yuǎn)程文檔"
? ? ? ? ? ? ? ? ? ? accessibilityLabel="See a Document"
? ? ? ? ? ? ? ? />
? ? ? ? ? ? ? ? <Button
? ? ? ? ? ? ? ? ? ? onPress={this.handlePressLocal.bind(this)}
? ? ? ? ? ? ? ? ? ? title="打開本地文檔"
? ? ? ? ? ? ? ? ? ? accessibilityLabel="See a Document"
? ? ? ? ? ? ? ? />
? ? ? ? ? ? </View>
? ? ? ? );
? ? }
}
const styles = StyleSheet.create({
? ? container: {
? ? ? ? flex: 1,
? ? ? ? justifyContent: 'center',
? ? ? ? alignItems: 'center',
? ? ? ? backgroundColor: '#F5FCFF',
? ? },
? ? welcome: {
? ? ? ? fontSize: 20,
? ? ? ? textAlign: 'center',
? ? ? ? margin: 10,
? ? },
? ? instructions: {
? ? ? ? textAlign: 'center',
? ? ? ? color: '#333333',
? ? ? ? marginBottom: 5,
? ? },
});
上面我覺得重要的地方都有加注釋。有使用fs 有需要的可以點(diǎn)下FS婴程,去我的另一篇文章?廓奕。
再次劃重點(diǎn):打開本地文件失敗:打開本地文件的url:必須是file://+路徑+文件名字。上面也有注釋桌粉。我是遇到這個(gè)問題了蒸绩,所以就想嘮叨一下。
我只使用了打開遠(yuǎn)程的和下載后打開本地的铃肯。其他的官方上npm上有例子患亿。可以去查看押逼。