事件背景:最近在写一个项目,要求本地打开、查看和打开远程的文档。找到了一个组件,使用起来挺方便的。就分享一下。我是配合react-native-fs实用的,fs配置的一些东西看我另一篇随笔。
react-native-doc-viewer,可以在手机上直接打开文档,支持远程和本地文档。
支持的文档格式:xls,ppt,doc,xlsx,pptx,docx,png,jpg,pdf,mp4。支持iOS和Android。
组件名称:react-native-doc-viewer
首先安装:npm install react-native-doc-viewer --save
其次自动链接:react-native link react-native-doc-viewer
按理说是自动连接是可以的。可是程序运行一下发现还是报错。只能手动来了。
先附上npm网址:https://www.npmjs.com/package/react-native-doc-viewer
检查并链接:
一、ios端:
1、在XCode中,在项目导航器中,右键单击Libraries➜Add Files to [你的项目名字]
2、转到node_modules➜ react-native-doc-viewer并添加RNReactNativeDocViewer.xcodeproj
3、在XCode中,在项目导航器中,选择您的项目。添加libRNReactNativeDocViewer.a到项目的Build Phases➜Link Binary With Libraries
划重点,我的以上三条都链接上了。只有下面的没有链接上。
链接的框架和库必须具有此2个库(AssetsLibrary.framework和QuickLock.framework)
注意当显示http链接时,不要忘记将APP传输安全设置 - >允许任意加载设置为YES
在info.plist里没有的话添加上。
二、android配置
去看npm网址吧,我的是直接连接一下就自动配置上了,所以懒得整理了。
附上API:
openDoc 打开远程货或本地文档
openDocb64 打开Base64字符串格式文档
openDocBinaryinUrl 打开二进制文件
playMovie 打开视频文件
制作这个组件的作者估计是没时间写很详细,所以npm上也不是很详细。下面附上我写的一部分程序。
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');
//保存路径可以跳进去看,具体自己选择
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", // 将文件保存到的本地文件系统路径
//进度条
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)
}
})
}
}
//打开远程文件
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="打开远程文档"
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 有需要的可以点下FS,去我的另一篇文章 。
再次划重点:打开本地文件失败:打开本地文件的url:必须是file://+路径+文件名字。上面也有注释。我是遇到这个问题了,所以就想唠叨一下。
我只使用了打开远程的和下载后打开本地的。其他的官方上npm上有例子。可以去查看。