├── LICENSE ├── README.md ├── RNReactNativeDocViewer.podspec ├── RNReactNativeDocViewer.sln ├── RNReactNativeDocViewer ├── Properties │ ├── AssemblyInfo.cs │ └── RNReactNativeDocViewer.rd.xml ├── RNReactNativeDocViewer.csproj ├── RNReactNativeDocViewerModule.cs ├── RNReactNativeDocViewerPackage.cs └── project.json ├── Screenshots ├── Screenshot.png ├── Screenshot1.png ├── Screenshot2.png ├── plist_file.png ├── screenshot_xcode_addlibrary.png └── screenshot_xcode_addlibrary2.png ├── android ├── .DS_Store ├── .gradle │ └── 4.3 │ │ ├── fileChanges │ │ └── last-build.bin │ │ └── fileHashes │ │ ├── fileHashes.bin │ │ └── fileHashes.lock ├── build.gradle └── src │ ├── .DS_Store │ └── main │ ├── .DS_Store │ ├── AndroidManifest.xml │ ├── java │ ├── .DS_Store │ └── com │ │ ├── .DS_Store │ │ └── philipphecht │ │ ├── FileProviderClass.java │ │ ├── RNDocViewerModule.java │ │ └── RNDocViewerPackage.java │ └── res │ └── xml │ └── filepaths.xml ├── example ├── .DS_Store └── ReactDocViewerExample │ ├── .babelrc │ ├── .buckconfig │ ├── .flowconfig │ ├── .gitattributes │ ├── .gitignore │ ├── .watchmanconfig │ ├── App.js │ ├── __tests__ │ └── App.js │ ├── android │ ├── .project │ ├── .settings │ │ └── org.eclipse.buildship.core.prefs │ ├── app │ │ ├── .classpath │ │ ├── .project │ │ ├── .settings │ │ │ └── org.eclipse.buildship.core.prefs │ │ ├── BUCK │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── reactdocviewerexample │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── keystores │ │ ├── BUCK │ │ └── debug.keystore.properties │ └── settings.gradle │ ├── app.json │ ├── index.js │ ├── ios │ ├── ReactDocViewerExample-tvOS │ │ └── Info.plist │ ├── ReactDocViewerExample-tvOSTests │ │ └── Info.plist │ ├── ReactDocViewerExample.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── ReactDocViewerExample-tvOS.xcscheme │ │ │ └── ReactDocViewerExample.xcscheme │ ├── ReactDocViewerExample │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── main.m │ ├── ReactDocViewerExampleTests │ │ ├── Info.plist │ │ └── ReactDocViewerExampleTests.m │ └── Resources │ │ ├── SampleXLSFile_19kb.xls │ │ └── react-native-logo.jpg │ ├── package.json │ └── yarn.lock ├── index.js ├── ios ├── .DS_Store ├── QLCustomPreviewItem.h ├── QLCustomPreviewItem.m ├── RNDocViewer.h ├── RNDocViewer.m └── RNDocViewer.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ ├── ethan.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── macbook.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ ├── ethan.xcuserdatad │ └── xcschemes │ │ └── xcschememanagement.plist │ └── macbook.xcuserdatad │ └── xcschemes │ ├── RNReactNativeDocViewer.xcscheme │ └── xcschememanagement.plist ├── package.json └── windows └── RNReactNativeDocViewer ├── RNReactNativeDocViewerModule.cs └── RNReactNativeDocViewerPackage.cs /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Phil Pike 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # react-native-doc-viewer [![npm version](https://img.shields.io/npm/v/react-native-doc-viewer.svg?style=flat)](https://www.npmjs.com/package/react-native-doc-viewer)![Platform](https://img.shields.io/badge/platform-react--native%20%5Bios%20%26%20android%5D-blue.svg)![License](https://img.shields.io/npm/l/express.svg) 3 | 4 | ![nodei.co](https://nodei.co/npm/react-native-doc-viewer.png?downloads=true&downloadRank=true&stars=true) 5 | 6 | A React Native bridge module: Document Viewer for files (pdf, png, jpg, xls, doc, ppt, xlsx, docx, pptx etc.) 7 | 8 | #### 2017 Roadmap 9 | - Download Progess Event Listener for big Files Android 10 | #### 2018 Roadmap 11 | - Android file without external Application 12 | - Windows Phone Support 13 | 14 | #### IMPORTANT INFORMATION: THIS IS A OPEN SOURCE PROJECT, SOMETIMES I HAVE NO TIME TO DEVELOP THIS PROJECT. THANK YOU FOR YOUR PULL REQUEST AND YOUR SUPPORT. I will continue to develop it as it is possible in time. 15 | 16 | 17 | 18 | 19 | Changelog: 20 | 21 | ``` 22 | 2.7.8 - XLS Exmaple Local File IOS 97-2003 23 | 2.7.7 - "react": "^16.3.0-alpha.1","react-native": "0.54.3" 24 | 2.7.5 - Pull Request local file from LeMinh1995 + Pull Request podspec Form Linh1987 25 | 2.7.3 - Example Local File 26 | 2.7.2 - Progress Download Feedback in example and Done Button Callback IOS 27 | 2.7.1 - Fix Progress IOS Download 28 | 2.6.9 - Progress IOS DOWNLOAD Document Callback in Native Code 29 | 2.6.0 - Android Openbase64 30 | 2.5.2 - OpenDocAndroid 31 | 2.5.1 - Cleanings 32 | 2.5.0 - Update Project for React Native 0.50.3 33 | 34 | ``` 35 | 36 | 37 | ## Getting started 38 | 39 | `$ npm install react-native-doc-viewer --save` 40 | 41 | ### Automatic installation 42 | 43 | `$ react-native link react-native-doc-viewer` 44 | 45 | ### CocoaPods installation 46 | 47 | If your project uses CocoaPods to manage React installation (especially with Expo-detached project), most likely you will run into issue with header files not found as described here (https://docs.expo.io/versions/latest/guides/expokit.html#changing-native-dependencies "Changing Native Dependencies"). It will be helpful to follow these steps to have it compiled successfully: 48 | 49 | 1. `npm install react-native-doc-viewer --save` 50 | 51 | 2. Add the plugin dependency to your Podfile, pointing at the path where NPM installed it: 52 | 53 | `pod 'RNReactNativeDocViewer', path: '../node_modules/react-native-doc-viewer'` 54 | 55 | 3. Run `pod install` 56 | 57 | ### Manual installation 58 | 59 | 60 | #### iOS 61 | 62 | 1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]` 63 | 2. Go to `node_modules` ➜ `react-native-doc-viewer` and add `RNDocViewer.xcodeproj` 64 | 3. In XCode, in the project navigator, select your project. Add `libRNDocViewer.a` to your project's `Build Phases` ➜ `Link Binary With Libraries` 65 | 4. Linked Frameworks and Libraries must have this 2 Libraries (AssetsLibrary.framework & QuickLook.framework). When not you have to add them. 66 | 67 | ![Alt text](https://raw.githubusercontent.com/philipphecht/react-native-doc-viewer/master/Screenshots/screenshot_xcode_addlibrary.png "Xcode add Library") 68 | 69 | ![Alt text](https://raw.githubusercontent.com/philipphecht/react-native-doc-viewer/master/Screenshots/screenshot_xcode_addlibrary2.png "Xcode add Library") 70 | 71 | 5. When you Show http Links don't forget to set APP Transport Security Settings -> 72 | Allow Arbitrary Loads to YES 73 | 74 | ![Alt text](https://raw.githubusercontent.com/philipphecht/react-native-doc-viewer/master/Screenshots/plist_file.png "Plist") 75 | 76 | 6. Run your project (`Cmd+R`)< 77 | 78 | #### Android 79 | 80 | 1. Open up `android/app/src/main/java/[...]/MainApplication.java` 81 | - Add `import com.philipphecht.RNDocViewerPackage;` to the imports at the top of the file 82 | - Add `new RNDocViewerPackage()` to the list returned by the `getPackages()` method 83 | 2. Append the following lines to `android/settings.gradle`: 84 | ``` 85 | include ':react-native-doc-viewer' 86 | project(':react-native-doc-viewer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-doc-viewer/android') 87 | ``` 88 | 3. Insert the following lines inside the dependencies block in `android/app/build.gradle`: 89 | ``` 90 | compile project(':react-native-doc-viewer') 91 | ``` 92 | 93 | #### Windows on the Roadmap 94 | [Read it! :D](https://github.com/ReactWindows/react-native) 95 | 96 | 1. In Visual Studio add the `RNReactNativeDocViewer.sln` in `node_modules/react-native-react-native-doc-viewer/windows/RNReactNativeDocViewer.sln` folder to their solution, reference from their app. 97 | 2. Open up your `MainPage.cs` app 98 | - Add `using com.Philipphecht.RNReactNativeDocViewer;` to the usings at the top of the file 99 | - Add `new RNReactNativeDocViewerPackage()` to the `List` returned by the `Packages` method 100 | 101 | 102 | ## API DOC 103 | ### IOS Document Viewer Doc 104 | 105 | | resource | description | 106 | |:----------------------------|:----------------------------------| 107 | | `DoneButtonEvent` | return true | 108 | | `RNDownloaderProgress`| return Progress Float| 109 | 110 | 111 | | resource | description | 112 | |:----------------------------|:----------------------------------| 113 | | `openDoc` | {url:String,fileNameOptional:String (optional)} | 114 | | `openDocb64`| {url:String,fileName:String,fileType:String }| 115 | | `openDocBinaryinUrl` | {url:String,fileName:String,fileType:String } | 116 | 117 | ### Android Document Viewer Doc 118 | 119 | | resource | description | 120 | |:----------------------------|:----------------------------------| 121 | | `openDoc` | {url:String,fileName:String, cache:boolean} | 122 | | `openDocb64`| {url:String,fileName:String,fileType:String, cache:boolean }| 123 | | `openDocBinaryinUrl` | not implemented yet | 124 | 125 | ## Usage 126 | ```javascript 127 | import React, { Component } from 'react'; 128 | import { 129 | AppRegistry, 130 | StyleSheet, 131 | Text, 132 | View, 133 | Platform, 134 | Button, 135 | Alert, 136 | ActivityIndicator, 137 | NativeAppEventEmitter, 138 | DeviceEventEmitter, 139 | NativeModules, 140 | NativeEventEmitter, 141 | TouchableHighlight 142 | } from 'react-native'; 143 | import OpenFile from 'react-native-doc-viewer'; 144 | var RNFS = require('react-native-fs'); 145 | var SavePath = Platform.OS === 'ios' ? RNFS.MainBundlePath : RNFS.DocumentDirectoryPath; 146 | export default class DocumentViewerExample extends Component { 147 | constructor(props) { 148 | super(props); 149 | this.state = { 150 | animating: false, 151 | progress: "", 152 | donebuttonclicked: false, 153 | } 154 | this.eventEmitter = new NativeEventEmitter(NativeModules.RNReactNativeDocViewer); 155 | this.eventEmitter.addListener('DoneButtonEvent', (data) => { 156 | /* 157 | *Done Button Clicked 158 | * return true 159 | */ 160 | console.log(data.close); 161 | this.setState({donebuttonclicked: data.close}); 162 | }) 163 | this.didPressToObjcButton = this.didPressToObjcButton.bind(this); 164 | } 165 | 166 | componentDidMount(){ 167 | // download progress 168 | this.eventEmitter.addListener( 169 | 'RNDownloaderProgress', 170 | (Event) => { 171 | console.log("Progress - Download "+Event.progress + " %") 172 | this.setState({progress: Event.progress + " %"}); 173 | } 174 | 175 | ); 176 | } 177 | 178 | componentWillUnmount (){ 179 | this.eventEmitter.removeListener(); 180 | } 181 | /* 182 | * Handle WWW File Method 183 | * fileType Default == "" you can use it, to set the File Extension (pdf,doc,xls,ppt etc) when in the Url the File Extension is missing. 184 | */ 185 | handlePress = () => { 186 | this.setState({animating: true}); 187 | if(Platform.OS === 'ios'){ 188 | OpenFile.openDoc([{ 189 | url:"https://calibre-ebook.com/downloads/demos/demo.docx", 190 | fileNameOptional:"test filename" 191 | }], (error, url) => { 192 | if (error) { 193 | this.setState({animating: false}); 194 | } else { 195 | this.setState({animating: false}); 196 | console.log(url) 197 | } 198 | }) 199 | }else{ 200 | //Android 201 | this.setState({animating: true}); 202 | OpenFile.openDoc([{ 203 | url:"https://www.huf-haus.com/fileadmin/Bilder/Header/ART_3/Header_HUF_Haus_ART_3___1_.jpg", // Local "file://" + filepath 204 | fileName:"sample", 205 | cache:false, 206 | fileType:"jpg" 207 | }], (error, url) => { 208 | if (error) { 209 | this.setState({animating: false}); 210 | console.error(error); 211 | } else { 212 | this.setState({animating: false}); 213 | console.log(url) 214 | } 215 | }) 216 | } 217 | 218 | } 219 | 220 | 221 | /* 222 | * Handle Local File Method 223 | * fileType Default == "" you can use it, to set the File Extension (pdf,doc,xls,ppt etc) when in the Url the File Extension is missing. 224 | */ 225 | handlePressLocal = () => { 226 | this.setState({animating: true}); 227 | if(Platform.OS === 'ios'){ 228 | OpenFile.openDoc([{url:SavePath+"/react-native-logo.jpg", 229 | fileNameOptional:"test filename" 230 | }], (error, url) => { 231 | if (error) { 232 | this.setState({animating: false}); 233 | } else { 234 | this.setState({animating: false}); 235 | console.log(url) 236 | } 237 | }) 238 | }else{ 239 | OpenFile.openDoc([{url:SavePath+"/demo.jpg", 240 | fileName:"sample", 241 | cache:false, 242 | fileType:"jpg" 243 | }], (error, url) => { 244 | if (error) { 245 | this.setState({animating: false}); 246 | } else { 247 | this.setState({animating: false}); 248 | console.log(url) 249 | } 250 | }) 251 | 252 | } 253 | } 254 | 255 | handlePressLocalXLS = () => { 256 | this.setState({animating: true}); 257 | if(Platform.OS === 'ios'){ 258 | OpenFile.openDoc([{url:SavePath+"/SampleXLSFile_19kb.xls", 259 | fileNameOptional:"Sample XLS 94-2003" 260 | }], (error, url) => { 261 | if (error) { 262 | this.setState({animating: false}); 263 | } else { 264 | this.setState({animating: false}); 265 | console.log(url) 266 | } 267 | }) 268 | }else{ 269 | OpenFile.openDoc([{url:SavePath+"/demo.jpg", 270 | fileName:"sample", 271 | cache:false, 272 | fileType:"jpg" 273 | }], (error, url) => { 274 | if (error) { 275 | this.setState({animating: false}); 276 | } else { 277 | this.setState({animating: false}); 278 | console.log(url) 279 | } 280 | }) 281 | 282 | } 283 | } 284 | 285 | 286 | /* 287 | * Binary in URL 288 | * Binary String in Url 289 | * fileType Default == "" you can use it, to set the File Extension (pdf,doc,xls,ppt etc) when in the Url you dont have an File Extensions 290 | */ 291 | handlePressBinaryinUrl = () => { 292 | this.setState({animating: true}); 293 | if(Platform.OS === 'ios'){ 294 | OpenFile.openDocBinaryinUrl([{ 295 | url:"https://storage.googleapis.com/need-sure/example", 296 | fileName:"sample", 297 | fileType:"xml" 298 | }], (error, url) => { 299 | if (error) { 300 | console.error(error); 301 | this.setState({animating: false}); 302 | } else { 303 | console.log(url) 304 | this.setState({animating: false}); 305 | } 306 | }) 307 | }else{ 308 | OpenFile.openDocBinaryinUrl([{ 309 | url:"https://storage.googleapis.com/need-sure/example", 310 | fileName:"sample", 311 | fileType:"xml", 312 | cache:true 313 | }], (error, url) => { 314 | if (error) { 315 | console.error(error); 316 | this.setState({animating: false}); 317 | } else { 318 | console.log(url) 319 | this.setState({animating: false}); 320 | } 321 | }) 322 | } 323 | } 324 | 325 | /* 326 | * Base64String 327 | * put only the base64 String without data:application/octet-stream;base64 328 | * fileType Default == "" you can use it, to set the File Extension (pdf,doc,xls,ppt etc) when in the Url you dont have an File Extensions 329 | */ 330 | handlePressb64 = () => { 331 | if(Platform.OS === 'ios'){ 332 | OpenFile.openDocb64([{ 333 | base64:"{BASE64String}" 334 | fileName:"sample", 335 | fileType:"png" 336 | }], (error, url) => { 337 | if (error) { 338 | console.error(error); 339 | } else { 340 | console.log(url) 341 | } 342 | }) 343 | }else{ 344 | //Android 345 | OpenFile.openDocb64([{ 346 | base64:"{BASE64String}" 347 | fileName:"sample", 348 | fileType:"png", 349 | cache:true /*Use Cache Folder Android*/ 350 | }], (error, url) => { 351 | if (error) { 352 | console.error(error); 353 | } else { 354 | console.log(url) 355 | } 356 | }) 357 | } 358 | 359 | /* 360 | * Video File 361 | */ 362 | handlePressVideo = () => { 363 | if(Platform.OS === 'ios'){ 364 | OpenFile.playMovie(video, (error, url) => { 365 | if (error) { 366 | console.error(error); 367 | } else { 368 | console.log(url) 369 | } 370 | }) 371 | }else{ 372 | Alert.alert("Android coming soon"); 373 | } 374 | } 375 | 376 | 377 |