diff --git a/README.md b/README.md index 060b3bc..5320a8b 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ The library can also be imported directly from JSX code with: import XLSX from 'xlsx'; ``` -This demo shows a simple React component transpiled in the browser using the babel +This demo shows a simple React component transpiled in the browser using Babel standalone library. Since there is no standard React table model, this demo settles on the array of arrays approach. @@ -77,45 +77,29 @@ function make_cols(refstr/*:string*/) { Reproducing the full project is straightforward: ```bash -# see native.sh -react-native init SheetJS -cd SheetJS -npm i -S xlsx react react-native react-native-table-component react-native-fs -cp ../react-native.js index.js -react-native link +$ make native # build the project +$ make ios # build and run the iOS demo +$ make android # build and run the android demo ``` -`react-native-table-component` draws the data table. `react-native-fs` reads -and write files on devices. The app will prompt before reading and after -writing data. The printed location will be: +The app will prompt before reading and after writing data. The printed location +depends on the environment: - android: path in the device filesystem - iOS simulator: local path to file - iOS device: a path accessible from iTunes App Documents view -`react-native-fs` supports `"ascii"` encoding for `readFile` and `writeFile`. -In practice, that encoding uses binary strings compatible with `"binary"` type: +Components used in the demo: +- [`react-native-table-component`](https://npm.im/react-native-table-component) +- [`react-native-file-access`](https://npm.im/react-native-file-access) -```js -import { writeFile, readFile } from 'react-native-fs'; - -/* read a workbook */ -readFile(file, 'ascii').then((res) => { - const workbook = XLSX.read(res, {type:'binary'}); - /* DO SOMETHING WITH workbook HERE */ -}); - -/* write a workbook */ -const wbout = XLSX.write(wb, {type:'binary', bookType:"xlsx"}); -writeFile(file, wbout, 'ascii').then((r)=>{/* :) */}).catch((e)=>{/* :( */}); -``` +React Native does not provide a native component for reading and writing files. +The sample script <`react-native.js`> uses `react-native-file-access` and has +notes for integrations with `react-native-fetch-blob` and `react-native-fs`. Note: for real app deployments, the `UIFileSharingEnabled` flag must be manually set in the iOS project `Info.plist` file. -To run the React Native demo, run either `make ios` or `make android` while -connected to a device or emulator. - #### Server-Rendered React Components with Next.js The demo uses the same component code as the in-browser version, but the build diff --git a/native.sh b/native.sh index 82ba882..d9e4cb4 100755 --- a/native.sh +++ b/native.sh @@ -1,11 +1,17 @@ #!/bin/bash # xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -if [ ! -e SheetJS ]; then - react-native init --version="0.62.2" SheetJS - cd SheetJS - npm i -S xlsx react-native-table-component react-native-fs - cd - -fi + +# Create starter project +if [ ! -e SheetJS ]; then react-native init SheetJS --version="0.67.2"; fi + +# Install dependencies +cd SheetJS; npm i -S xlsx react-native-table-component; cd - + +cd SheetJS; npm i -S react-native-file-access@2.x; cd - +# cd SheetJS; npm i -S react-native-fs; cd - +# cd SheetJS; npm i -S react-native-fetch-blob; cd - + +# Copy demo assets if [ ! -e SheetJS/logo.png ]; then curl -O http://oss.sheetjs.com/assets/img/logo.png mv logo.png SheetJS/logo.png @@ -16,6 +22,6 @@ if [ -e SheetJS/index.ios.js ]; then else cp react-native.js SheetJS/index.js fi -cd SheetJS; -RNFB_ANDROID_PERMISSIONS=true react-native link -cd -; + +# Link +cd SheetJS; RNFB_ANDROID_PERMISSIONS=true react-native link; cd - diff --git a/react-native.js b/react-native.js index ef2d933..c29eae6 100644 --- a/react-native.js +++ b/react-native.js @@ -14,12 +14,69 @@ import { } from 'react-native'; import { Table, Row, Rows, TableWrapper } from 'react-native-table-component'; +// react-native-file-access +var Base64 = function() { + var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + return { + encode: function(input) { + var o = ""; + var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0; + for (var i = 0; i < input.length; ) { + c1 = input.charCodeAt(i++); + e1 = c1 >> 2; + c2 = input.charCodeAt(i++); + e2 = (c1 & 3) << 4 | c2 >> 4; + c3 = input.charCodeAt(i++); + e3 = (c2 & 15) << 2 | c3 >> 6; + e4 = c3 & 63; + if (isNaN(c2)) { + e3 = e4 = 64; + } else if (isNaN(c3)) { + e4 = 64; + } + o += map.charAt(e1) + map.charAt(e2) + map.charAt(e3) + map.charAt(e4); + } + return o; + }, + decode: function(input) { + var o = ""; + var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0; + input = input.replace(/[^\w\+\/\=]/g, ""); + for (var i = 0; i < input.length; ) { + e1 = map.indexOf(input.charAt(i++)); + e2 = map.indexOf(input.charAt(i++)); + c1 = e1 << 2 | e2 >> 4; + o += String.fromCharCode(c1); + e3 = map.indexOf(input.charAt(i++)); + c2 = (e2 & 15) << 4 | e3 >> 2; + if (e3 !== 64) { + o += String.fromCharCode(c2); + } + e4 = map.indexOf(input.charAt(i++)); + c3 = (e3 & 3) << 6 | e4; + if (e4 !== 64) { + o += String.fromCharCode(c3); + } + } + return o; + } + }; +}(); + +import { Dirs, FileSystem } from 'react-native-file-access'; +const DDP = Dirs.DocumentDir + "/"; +const readFile = (path, enc) => FileSystem.readFile(path, "base64"); +const writeFile = (path, data, enc) => FileSystem.writeFile(path, data, "base64"); +const input = res => Base64.decode(res); +const output = str => Base64.encode(str); + // react-native-fs +/* import { writeFile, readFile, DocumentDirectoryPath } from 'react-native-fs'; const DDP = DocumentDirectoryPath + "/"; const input = res => res; const output = str => str; - +*/ // react-native-fetch-blob /* import RNFetchBlob from 'react-native-fetch-blob'; @@ -36,7 +93,7 @@ export default class SheetJS extends Component { constructor(props) { super(props); this.state = { - data: [[1,2,3],[4,5,6]], + data: [[2,3,4],[3,4,5]], widthArr: [60, 60, 60], cols: make_cols("A1:C2") };