Skip to content

Commit

Permalink
updates to react demo
Browse files Browse the repository at this point in the history
- bump react and babel
- converted to functional components

removed preact demo

renamed jsx to js for next make instruction

removed image component
added pod install for pod linking
  • Loading branch information
nullhook committed Mar 31, 2021
1 parent 333deae commit 58e59dc
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 241 deletions.
4 changes: 2 additions & 2 deletions demos/react/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ react: init ## Simple server for react and clones
.PHONY: next
next: init ## next.js demo
mkdir -p pages static
cat nexthdr.js sheetjs.jsx > pages/sheetjs.js
cat nexthdr.js sheetjs.js > pages/sheetjs.js
cp ../../shim.js static/shim.js
next

Expand All @@ -15,7 +15,7 @@ native: ## Build react-native project

.PHONY: ios
ios: native ## react-native ios sim
cd SheetJS; react-native run-ios --simulator="iPhone X"; cd -
cd SheetJS; cd ios; pod install; cd -; react-native run-ios --simulator="iPhone X"; cd -

.PHONY: android
android: native ## react-native android sim
Expand Down
15 changes: 3 additions & 12 deletions demos/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ The library can also be imported directly from JSX code with:
import XLSX from 'xlsx';
```

This demo shows a simple JSX component transpiled in the browser using the babel
This demo shows a simple React component transpiled in the browser using the babel
standalone library. Since there is no standard React table model, this demo
settles on the array of arrays approach.

Other scripts in this demo show:
- server-rendered React component (with `next.js`)
- `preact` using the react compatibility library
- `react-native` deployment for iOS and android

## How to run

Run `make react` to run the browser demo for React, or run `make next` to run
the server-rendered demo using `next.js`.


## Internal State

The simplest state representation is an array of arrays. To avoid having the
Expand Down Expand Up @@ -116,15 +116,6 @@ 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.

## Other Demos

#### Preact

`preact-compat` is an easy-to-use compatibility layer that provides equivalents
for `React` and `ReactDOM`. The `preact` demo uses the same JSX component code!
[The docs](https://npm.im/preact-compat#use-without-webpackbrowserify) explain
how to convert the in-browser React demo to Preact.

#### Server-Rendered React Components with Next.js

The demo uses the same component code as the in-browser version, but the build
Expand Down
19 changes: 4 additions & 15 deletions demos/react/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>SheetJS React Demo</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<script src="node_modules/xlsx/dist/shim.min.js"></script>
<script src="node_modules/xlsx/dist/xlsx.full.min.js"></script>
<style>body, #app { height: 100%; };</style>
Expand All @@ -21,18 +21,7 @@ <h1><a href="http://sheetjs.com">SheetJS React Demo</a></h1>
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a><br /><br />
</div>
<div id="app" class="container-fluid"></div>
<script type="text/babel" src="sheetjs.jsx"></script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-36810333-1']);
_gaq.push(['_trackPageview']);

(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<script type="text/babel" src="sheetjs.js"></script>
<script type="text/babel">
ReactDOM.render( <SheetJSApp />, document.getElementById('app') );
</script>
Expand Down
42 changes: 0 additions & 42 deletions demos/react/preact.html

This file was deleted.

65 changes: 38 additions & 27 deletions demos/react/react-native.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
import XLSX from 'xlsx';

import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, Button, Alert, Image, ScrollView, TouchableWithoutFeedback } from 'react-native';
import {
AppRegistry,
StyleSheet,
Text,
View,
Button,
Alert,
Image,
ScrollView,
TouchableWithoutFeedback
} from 'react-native';
import { Table, Row, Rows, TableWrapper } from 'react-native-table-component';

// react-native-fs
Expand Down Expand Up @@ -68,34 +77,36 @@ export default class SheetJS extends Component {
Alert.alert("exportFile success", "Exported to " + file);
}).catch((err) => { Alert.alert("exportFile Error", "Error " + err.message); });
};
render() { return (
<ScrollView contentContainerStyle={styles.container} vertical={true}>
<Text style={styles.welcome}> </Text>
<Image style={{width: 128, height: 128}} source={require('./logo.png')} />
<Text style={styles.welcome}>SheetJS React Native Demo</Text>
<Text style={styles.instructions}>Import Data</Text>
<Button onPress={this.importFile} title="Import data from a spreadsheet" color="#841584" />
<Text style={styles.instructions}>Export Data</Text>
<Button disabled={!this.state.data.length} onPress={this.exportFile} title="Export data to XLSX" color="#841584" />

<Text style={styles.instructions}>Current Data</Text>
render() {
return (
<ScrollView contentContainerStyle={styles.container} vertical={true}>
<Text style={styles.welcome}> </Text>
<Text style={styles.welcome}>SheetJS React Native Demo</Text>
<Text style={styles.instructions}>Import Data</Text>
<Button onPress={this.importFile} title="Import data from a spreadsheet" color="#841584" />
<Text style={styles.instructions}>Export Data</Text>
<Button disabled={!this.state.data.length} onPress={this.exportFile} title="Export data to XLSX" color="#841584" />

<Text style={styles.instructions}>Current Data</Text>

<ScrollView style={styles.table} horizontal={true} >
<Table style={styles.table}>
<TableWrapper>
<Row data={this.state.cols} style={styles.thead} textStyle={styles.text} widthArr={this.state.widthArr}/>
</TableWrapper>
<TouchableWithoutFeedback>
<ScrollView vertical={true}>
<TableWrapper>
<Rows data={this.state.data} style={styles.tr} textStyle={styles.text} widthArr={this.state.widthArr}/>
</TableWrapper>
<ScrollView style={styles.table} horizontal={true} >
<Table style={styles.table}>
<TableWrapper>
<Row data={this.state.cols} style={styles.thead} textStyle={styles.text} widthArr={this.state.widthArr}/>
</TableWrapper>
<TouchableWithoutFeedback>
<ScrollView vertical={true}>
<TableWrapper>
<Rows data={this.state.data} style={styles.tr} textStyle={styles.text} widthArr={this.state.widthArr}/>
</TableWrapper>
</ScrollView>
</TouchableWithoutFeedback>
</Table>
</ScrollView>
</TouchableWithoutFeedback>
</Table>
</ScrollView>
</ScrollView>
); };
</ScrollView>
);
};
};

const styles = StyleSheet.create({
Expand Down
145 changes: 145 additions & 0 deletions demos/react/sheetjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
/* Notes:
- usage: `ReactDOM.render( <SheetJSApp />, document.getElementById('app') );`
- xlsx.full.min.js is loaded in the head of the HTML page
- this script should be referenced with type="text/babel"
- babel.js in-browser transpiler should be loaded before this script
*/
function SheetJSApp() {
const [data, setData] = React.useState([]);
const [cols, setCols] = React.useState([]);

const handleFile = (file) => {
const reader = new FileReader();
const rABS = !!reader.readAsBinaryString;
reader.onload = (e) => {
/* Parse data */
const bstr = e.target.result;
const wb = XLSX.read(bstr, {type:rABS ? 'binary' : 'array'});
/* Get first worksheet */
const wsname = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
/* Convert array of arrays */
const data = XLSX.utils.sheet_to_json(ws, {header:1});
/* Update state */
setData(data);
setCols(make_cols(ws['!ref']))
};
if(rABS) reader.readAsBinaryString(file); else reader.readAsArrayBuffer(file);
}

const exportFile = () => {
/* convert state to workbook */
const ws = XLSX.utils.aoa_to_sheet(data);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
/* generate XLSX file and send to client */
XLSX.writeFile(wb, "sheetjs.xlsx")
};

return (
<DragDropFile handleFile={handleFile}>
<div className="row"><div className="col-xs-12">
<DataInput handleFile={handleFile} />
</div></div>
<div className="row"><div className="col-xs-12">
<button disabled={!data.length} className="btn btn-success" onClick={exportFile}>Export</button>
</div></div>
<div className="row"><div className="col-xs-12">
<OutTable data={data} cols={cols} />
</div></div>
</DragDropFile>
);
}

if(typeof module !== 'undefined') module.exports = SheetJSApp

/* -------------------------------------------------------------------------- */

/*
Simple HTML5 file drag-and-drop wrapper
usage: <DragDropFile handleFile={handleFile}>...</DragDropFile>
handleFile(file:File):void;
*/

function DragDropFile({ handleFile, children }) {
const suppress = (e) => { e.stopPropagation(); e.preventDefault(); };
const handleDrop = (e) => { e.stopPropagation(); e.preventDefault();
const files = e.dataTransfer.files;
if(files && files[0]) handleFile(files[0]);
};

return (
<div
onDrop={handleDrop}
onDragEnter={suppress}
onDragOver={suppress}
>
{children}
</div>
);
}

/*
Simple HTML5 file input wrapper
usage: <DataInput handleFile={callback} />
handleFile(file:File):void;
*/

function DataInput({ handleFile }) {
const handleChange = (e) => {
const files = e.target.files;
if(files && files[0]) handleFile(files[0]);
};

return (
<form className="form-inline">
<div className="form-group">
<label htmlFor="file">Drag or choose a spreadsheet file</label>
<br />
<input
type="file"
className="form-control"
id="file"
accept={SheetJSFT}
onChange={handleChange}
/>
</div>
</form>
)
}

/*
Simple HTML Table
usage: <OutTable data={data} cols={cols} />
data:Array<Array<any> >;
cols:Array<{name:string, key:number|string}>;
*/
function OutTable({ data, cols }) {
return (
<div className="table-responsive">
<table className="table table-striped">
<thead>
<tr>{cols.map((c) => <th key={c.key}>{c.name}</th>)}</tr>
</thead>
<tbody>
{data.map((r,i) => <tr key={i}>
{cols.map(c => <td key={c.key}>{ r[c.key] }</td>)}
</tr>)}
</tbody>
</table>
</div>
);
}

/* list of supported file types */
const SheetJSFT = [
"xlsx", "xlsb", "xlsm", "xls", "xml", "csv", "txt", "ods", "fods", "uos", "sylk", "dif", "dbf", "prn", "qpw", "123", "wb*", "wq*", "html", "htm"
].map(x => `.${x}`).join(",");

/* generate an array of column objects */
const make_cols = refstr => {
let o = [], C = XLSX.utils.decode_range(refstr).e.c + 1;
for(var i = 0; i < C; ++i) o[i] = {name:XLSX.utils.encode_col(i), key:i}
return o;
};
Loading

0 comments on commit 58e59dc

Please sign in to comment.