forked from sheetjs/docs.sheetjs.com
		
	rnw11
This commit is contained in:
		
							parent
							
								
									e1584a41a3
								
							
						
					
					
						commit
						86e0b1941d
					
				| @ -41,6 +41,22 @@ The "Complete Example" creates an app that looks like the screenshots below: | ||||
| 
 | ||||
| </td></tr></tbody></table> | ||||
| 
 | ||||
| <details><summary><b>Tested Environments</b> (click to show)</summary> | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was tested in the following environments: | ||||
| 
 | ||||
| | OS and Version | Arch | RN Platform | Date       | | ||||
| |:---------------|:-----|:------------|:-----------| | ||||
| | Windows 10     | x64  | `v0.70.10`  | 2023-01-04 | | ||||
| | Windows 11     | x64  | `v0.71.11`  | 2023-05-11 | | ||||
| | MacOS 12.4     | x64  | `v0.64.30`  | 2023-01-04 | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ## Native Modules | ||||
| 
 | ||||
| :::caution | ||||
| @ -195,8 +211,6 @@ RCT_EXPORT_METHOD(PickAndRead:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromi | ||||
| 
 | ||||
| ## Windows Demo | ||||
| 
 | ||||
| This demo was tested against `v0.70.10` on 2023 January 04 in Windows 10. | ||||
| 
 | ||||
| :::warning | ||||
| 
 | ||||
| There is no simple standalone executable file at the end of the process. | ||||
| @ -222,11 +236,11 @@ used to switch the NodeJS version. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 1) Create a new project using React Native `0.70`: | ||||
| 1) Create a new project using React Native `0.71`: | ||||
| 
 | ||||
| ```powershell | ||||
| npx react-native init SheetJSWin --template react-native@^0.70.0 | ||||
| cd .\SheetJSWin\ | ||||
| ```bash | ||||
| npx react-native init SheetJSWin --template react-native@^0.71.0 | ||||
| cd SheetJSWin | ||||
| ``` | ||||
| 
 | ||||
| Create the Windows part of the application: | ||||
| @ -234,14 +248,14 @@ Create the Windows part of the application: | ||||
| <Tabs groupId="rnwlang"> | ||||
|   <TabItem value="cs" label="C#"> | ||||
| 
 | ||||
| ```powershell | ||||
| ```bash | ||||
| npx react-native-windows-init --no-telemetry --overwrite --language=cs | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="cpp" label="C++"> | ||||
| 
 | ||||
| ```powershell | ||||
| ```bash | ||||
| npx react-native-windows-init --no-telemetry --overwrite | ||||
| ``` | ||||
| 
 | ||||
| @ -256,49 +270,45 @@ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| 
 | ||||
| To ensure that the app works, launch the app: | ||||
| 
 | ||||
| ```powershell | ||||
| ```bash | ||||
| npx react-native run-windows --no-telemetry | ||||
| ``` | ||||
| 
 | ||||
| :::caution | ||||
| 
 | ||||
| When the demo was tested in Windows 11, the run step failed with the message: | ||||
| 
 | ||||
| > The Windows SDK version `10.0.19041.0` was not found | ||||
| 
 | ||||
| Specific Windows SDK versions can be installed through Visual Studio Installer. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| <Tabs groupId="rnwlang"> | ||||
|   <TabItem value="cs" label="C#"> | ||||
| 
 | ||||
| 2) Create the file `windows\SheetJSWin\DocumentPicker.cs` with the following: | ||||
| 2) Download [`DocumentPicker.cs`](pathname:///reactnative/DocumentPicker.cs) and | ||||
| save to `windows\SheetJSWin\DocumentPicker.cs`. | ||||
| 
 | ||||
| ```csharp title="windows\SheetJSWin\DocumentPicker.cs" | ||||
| using System; | ||||
| using System.Threading.Tasks; | ||||
| using Windows.Security.Cryptography; | ||||
| using Windows.Storage; | ||||
| using Windows.Storage.Pickers; | ||||
| using Microsoft.ReactNative.Managed; | ||||
| <Tabs groupId="shell"> | ||||
|   <TabItem value="pwsh" label="PowerShell"> | ||||
| 
 | ||||
| namespace SheetJSWin { | ||||
|   [ReactModule] | ||||
|   class DocumentPicker { | ||||
|     private ReactContext context; | ||||
|     [ReactInitializer] | ||||
|     public void Initialize(ReactContext reactContext) { context = reactContext; } | ||||
| 
 | ||||
|     [ReactMethod("PickAndRead")] | ||||
|     public async void PickAndRead(IReactPromise<string> result) { | ||||
|       context.Handle.UIDispatcher.Post(async() => { try { | ||||
|         var picker = new FileOpenPicker(); | ||||
|         picker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary; | ||||
|         picker.FileTypeFilter.Add(".xlsx"); | ||||
|         picker.FileTypeFilter.Add(".xls"); | ||||
| 
 | ||||
|         var file = await picker.PickSingleFileAsync(); | ||||
|         if(file == null) throw new Exception("File not found"); | ||||
| 
 | ||||
|         var buf = await FileIO.ReadBufferAsync(file); | ||||
|         result.Resolve(CryptographicBuffer.EncodeToBase64String(buf)); | ||||
|       } catch(Exception e) { result.Reject(new ReactError { Message = e.Message }); }}); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| ```bash | ||||
| iwr -Uri https://docs.sheetjs.com/reactnative/DocumentPicker.cs -OutFile windows/SheetJSWin/DocumentPicker.cs | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="bash" label="WSL Bash"> | ||||
| 
 | ||||
| ```bash | ||||
| curl -Lo windows/SheetJSWin/DocumentPicker.cs https://docs.sheetjs.com/reactnative/DocumentPicker.cs | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 3) Add the highlighted line to `windows\SheetJSWin\SheetJSWin.csproj`. Look for | ||||
| the `ItemGroup` that contains `ReactPackageProvider.cs`: | ||||
| 
 | ||||
| @ -312,53 +322,26 @@ the `ItemGroup` that contains `ReactPackageProvider.cs`: | ||||
|   </TabItem> | ||||
|   <TabItem value="cpp" label="C++"> | ||||
| 
 | ||||
| 2) Create the file `windows\SheetJSWin\DocumentPicker.h` with the following: | ||||
| 2) Download [`DocumentPicker.h`](pathname:///reactnative/DocumentPicker.h) and | ||||
| save to `windows\SheetJSWin\DocumentPicker.h`. | ||||
| 
 | ||||
| ```cpp title="windows\SheetJSWin\DocumentPicker.h" | ||||
| #pragma once | ||||
| <Tabs groupId="shell"> | ||||
|   <TabItem value="pwsh" label="PowerShell"> | ||||
| 
 | ||||
| #include <winrt/Windows.Storage.Pickers.h> | ||||
| #include <winrt/Windows.Security.Cryptography.h> | ||||
| #include "NativeModules.h" | ||||
| 
 | ||||
| using namespace winrt::Microsoft::ReactNative; | ||||
| using namespace winrt::Windows::Storage; | ||||
| using namespace winrt::Windows::Storage::Pickers; | ||||
| using namespace winrt::Windows::Security::Cryptography; | ||||
| 
 | ||||
| namespace SheetJSWin { | ||||
|   REACT_MODULE(DocumentPicker); | ||||
|   struct DocumentPicker { | ||||
|     REACT_INIT(Initialize); | ||||
|     void Initialize(const ReactContext& reactContext) noexcept { | ||||
|       context = reactContext; | ||||
|     } | ||||
| 
 | ||||
|     REACT_METHOD(PickAndRead); | ||||
|     void PickAndRead(ReactPromise<winrt::hstring> promise) noexcept { | ||||
|       auto prom = promise; | ||||
|       context.UIDispatcher().Post([prom = std::move(prom)]()->winrt::fire_and_forget { | ||||
|         auto p = prom; | ||||
|         FileOpenPicker picker; | ||||
|         picker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary); | ||||
|         picker.FileTypeFilter().Append(L".xlsx"); | ||||
|         picker.FileTypeFilter().Append(L".xls"); | ||||
| 
 | ||||
|         StorageFile file = co_await picker.PickSingleFileAsync(); | ||||
|         if(file == nullptr) { p.Reject("File not Found"); co_return; } | ||||
| 
 | ||||
|         auto buf = co_await FileIO::ReadBufferAsync(file); | ||||
|         p.Resolve(CryptographicBuffer::EncodeToBase64String(buf)); | ||||
|         co_return; | ||||
|       }); | ||||
|     } | ||||
| 
 | ||||
|     private: | ||||
|       ReactContext context{nullptr}; | ||||
|   }; | ||||
| } | ||||
| ```bash | ||||
| iwr -Uri https://docs.sheetjs.com/reactnative/DocumentPicker.h -OutFile windows/SheetJSWin/DocumentPicker.h | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="bash" label="WSL Bash"> | ||||
| 
 | ||||
| ```bash | ||||
| curl -Lo windows/SheetJSWin/DocumentPicker.h https://docs.sheetjs.com/reactnative/DocumentPicker.h | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| 3) Add the highlighted line to `windows\SheetJSWin\ReactPackageProvider.cpp`: | ||||
| 
 | ||||
| ```cpp title="windows\SheetJSWin\ReactPackageProvider.cpp" | ||||
| @ -373,55 +356,30 @@ namespace SheetJSWin { | ||||
| 
 | ||||
| Now the native module will be added to the app. | ||||
| 
 | ||||
| 4) Remove `App.js` and save the following to `App.tsx`: | ||||
| 4) Remove `App.js` (if it exists) and save the following to `App.tsx`: | ||||
| 
 | ||||
| ```tsx title="App.tsx" | ||||
| import React, { useState, type Node } from 'react'; | ||||
| import { SafeAreaView, ScrollView, StyleSheet, Text, TouchableHighlight, View } from 'react-native'; | ||||
| import { read, utils, version } from 'xlsx'; | ||||
| import { getEnforcing } from 'react-native/Libraries/TurboModule/TurboModuleRegistry'; | ||||
| const DocumentPicker = getEnforcing('DocumentPicker'); | ||||
| <Tabs groupId="shell"> | ||||
|   <TabItem value="pwsh" label="PowerShell"> | ||||
| 
 | ||||
| const App: () => Node = () => { | ||||
| 
 | ||||
|   const [ aoa, setAoA ] = useState(["SheetJS".split(""), "5433795".split("")]); | ||||
| 
 | ||||
|   return ( | ||||
|     <SafeAreaView style={styles.outer}> | ||||
|       <Text style={styles.title}>SheetJS × React Native Windows {version}</Text> | ||||
|       <TouchableHighlight onPress={async() => { | ||||
|         try { | ||||
|           const b64 = await DocumentPicker.PickAndRead(); | ||||
|           const wb = read(b64); | ||||
|           setAoA(utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1 } )); | ||||
|         } catch(err) { alert(`Error: ${err.message}`); } | ||||
|       }}><Text style={styles.button}>Click here to Open File!</Text></TouchableHighlight> | ||||
|       <ScrollView contentInsetAdjustmentBehavior="automatic"> | ||||
|         <View style={styles.table}>{aoa.map((row,R) => ( | ||||
|           <View style={styles.row} key={R}>{row.map((cell,C) => ( | ||||
|             <View style={styles.cell} key={C}><Text>{cell}</Text></View> | ||||
|           ))}</View> | ||||
|         ))}</View> | ||||
|       </ScrollView> | ||||
|     </SafeAreaView> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| const styles = StyleSheet.create({ | ||||
|   cell: { flex: 4 }, | ||||
|   row: { flexDirection: 'row', justifyContent: 'space-evenly', padding: 10, backgroundColor: 'white', }, | ||||
|   table: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', }, | ||||
|   outer: { marginTop: 32, paddingHorizontal: 24, }, | ||||
|   title: { fontSize: 24, fontWeight: '600', }, | ||||
|   button: { marginTop: 8, fontSize: 18, fontWeight: '400', }, | ||||
| }); | ||||
| 
 | ||||
| export default App; | ||||
| ```bash | ||||
| iwr -Uri https://docs.sheetjs.com/reactnative/desktop/App.tsx -OutFile App.tsx | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="bash" label="WSL Bash"> | ||||
| 
 | ||||
| ```bash | ||||
| curl -LO https://docs.sheetjs.com/reactnative/desktop/App.tsx | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 5) Test the app again: | ||||
| 
 | ||||
| ```powershell | ||||
| ```bash | ||||
| npx react-native run-windows --no-telemetry | ||||
| ``` | ||||
| 
 | ||||
| @ -430,8 +388,6 @@ file picker to select the `pres.xlsx` file and the app will show the data. | ||||
| 
 | ||||
| ## macOS Demo | ||||
| 
 | ||||
| This demo was tested against `v0.64.30` on 2023 January 04 in MacOS 12.4 | ||||
| 
 | ||||
| 0) Follow the [React Native](https://reactnative.dev/docs/environment-setup) | ||||
|    guide for React Native CLI on MacOS. | ||||
| 
 | ||||
| @ -463,7 +419,7 @@ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| 
 | ||||
| To ensure that the app works, launch the app: | ||||
| 
 | ||||
| ```powershell | ||||
| ```bash | ||||
| npx react-native run-macos | ||||
| ``` | ||||
| 
 | ||||
|  | ||||
| @ -93,7 +93,7 @@ async function extern(url) { | ||||
| 
 | ||||
| 2) Install dependencies in a new PowerShell window: | ||||
| 
 | ||||
| ```powershell | ||||
| ```bash | ||||
| npm i -g yo bower generator-office | ||||
| ``` | ||||
| 
 | ||||
| @ -109,7 +109,7 @@ npm i -g yo bower generator-office | ||||
| 
 | ||||
| 4) Start the dev process: | ||||
| 
 | ||||
| ```powershell | ||||
| ```bash | ||||
| cd SheetJSImport | ||||
| npm run build | ||||
| npm start | ||||
|  | ||||
| @ -98,7 +98,7 @@ chmod +x compile-git-with-openssl.sh | ||||
| E) Set `git` config `core.autocrlf` setting to `false`. The following commands | ||||
| should be run twice, once within PowerShell and once within WSL bash: | ||||
| 
 | ||||
| ```powershell | ||||
| ```bash | ||||
| git config --global --add core.autocrlf false | ||||
| git config --global --unset core.autocrlf true | ||||
| ``` | ||||
|  | ||||
| @ -192,25 +192,31 @@ const config = { | ||||
|         { from: '/docs/demos/extendscript', to: '/docs/demos/extensions/extendscript/' }, | ||||
|         { from: '/docs/demos/excelapi', to: '/docs/demos/extensions/excelapi/' }, | ||||
|         { from: '/docs/demos/chromium', to: '/docs/demos/extensions/chromium/' }, | ||||
|         /* cloudata */ | ||||
|         { from: '/docs/getting-started/demos/chromium', to: '/docs/demos/extensions/chromium/' }, | ||||
|         /* cloud */ | ||||
|         { from: '/docs/demos/cloudata', to: '/docs/demos/cloud/' }, | ||||
|         { from: '/docs/demos/cloudata/gsheet', to: '/docs/demos/cloud/gsheet/' }, | ||||
|         { from: '/docs/demos/cloudata/airtable', to: '/docs/demos/cloud/airtable/' }, | ||||
|         { from: '/docs/getting-started/demos/netsuite', to: '/docs/demos/cloud/netsuite/' }, | ||||
|         /* hosting */ | ||||
|         { from: '/docs/demos/hosting/dropbox', to: '/docs/demos/cloud/dropbox/' }, | ||||
|         { from: '/docs/demos/hosting/github', to: '/docs/demos/cloud/github/' }, | ||||
|         /* data */ | ||||
|         { from: '/docs/demos/nosql', to: '/docs/demos/data/' }, | ||||
|         { from: '/docs/demos/database', to: '/docs/demos/data/' }, | ||||
|         { from: '/docs/demos/nosql', to: '/docs/demos/data/' }, | ||||
|         { from: '/docs/getting-started/demos/nosql', to: '/docs/demos/data/' }, | ||||
|         /* net */ | ||||
|         { from: '/docs/demos/headless', to: '/docs/demos/net/headless/' }, | ||||
|         { from: '/docs/demos/server', to: '/docs/demos/net/server/' }, | ||||
|         { from: '/docs/demos/network', to: '/docs/demos/net/network/' }, | ||||
|         { from: '/docs/getting-started/demos/network', to: '/docs/demos/net/network/' }, | ||||
|         /* local */ | ||||
|         { from: '/docs/demos/clipboard', to: '/docs/demos/local/clipboard/' }, | ||||
|         { from: '/docs/demos/localfile', to: '/docs/demos/local/file/' }, | ||||
|         /* desktop */ | ||||
|         { from: '/docs/demos/cli', to: '/docs/demos/desktop/cli/' }, | ||||
|         { from: '/docs/getting-started/demos/cli', to: '/docs/demos/desktop/cli/' }, | ||||
|         { from: '/docs/getting-started/demos/desktop', to: '/docs/demos/desktop/' }, | ||||
|         /* bigdata */ | ||||
|         { from: '/docs/demos/ml', to: '/docs/demos/bigdata/ml/' }, | ||||
|         { from: '/docs/demos/worker', to: '/docs/demos/bigdata/worker/' }, | ||||
|  | ||||
							
								
								
									
										31
									
								
								docz/static/reactnative/DocumentPicker.cs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										31
									
								
								docz/static/reactnative/DocumentPicker.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| using System; | ||||
| using System.Threading.Tasks; | ||||
| using Windows.Security.Cryptography; | ||||
| using Windows.Storage; | ||||
| using Windows.Storage.Pickers; | ||||
| using Microsoft.ReactNative.Managed; | ||||
| 
 | ||||
| namespace SheetJSWin { | ||||
|   [ReactModule] | ||||
|   class DocumentPicker { | ||||
|     private ReactContext context; | ||||
|     [ReactInitializer] | ||||
|     public void Initialize(ReactContext reactContext) { context = reactContext; } | ||||
| 
 | ||||
|     [ReactMethod("PickAndRead")] | ||||
|     public async void PickAndRead(IReactPromise<string> result) { | ||||
|       context.Handle.UIDispatcher.Post(async() => { try { | ||||
|         var picker = new FileOpenPicker(); | ||||
|         picker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary; | ||||
|         picker.FileTypeFilter.Add(".xlsx"); | ||||
|         picker.FileTypeFilter.Add(".xls"); | ||||
| 
 | ||||
|         var file = await picker.PickSingleFileAsync(); | ||||
|         if(file == null) throw new Exception("File not found"); | ||||
| 
 | ||||
|         var buf = await FileIO.ReadBufferAsync(file); | ||||
|         result.Resolve(CryptographicBuffer.EncodeToBase64String(buf)); | ||||
|       } catch(Exception e) { result.Reject(new ReactError { Message = e.Message }); }}); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										42
									
								
								docz/static/reactnative/DocumentPicker.h
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										42
									
								
								docz/static/reactnative/DocumentPicker.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <winrt/Windows.Storage.Pickers.h> | ||||
| #include <winrt/Windows.Security.Cryptography.h> | ||||
| #include "NativeModules.h" | ||||
| 
 | ||||
| using namespace winrt::Microsoft::ReactNative; | ||||
| using namespace winrt::Windows::Storage; | ||||
| using namespace winrt::Windows::Storage::Pickers; | ||||
| using namespace winrt::Windows::Security::Cryptography; | ||||
| 
 | ||||
| namespace SheetJSWin { | ||||
|   REACT_MODULE(DocumentPicker); | ||||
|   struct DocumentPicker { | ||||
|     REACT_INIT(Initialize); | ||||
|     void Initialize(const ReactContext& reactContext) noexcept { | ||||
|       context = reactContext; | ||||
|     } | ||||
| 
 | ||||
|     REACT_METHOD(PickAndRead); | ||||
|     void PickAndRead(ReactPromise<winrt::hstring> promise) noexcept { | ||||
|       auto prom = promise; | ||||
|       context.UIDispatcher().Post([prom = std::move(prom)]()->winrt::fire_and_forget { | ||||
|         auto p = prom; | ||||
|         FileOpenPicker picker; | ||||
|         picker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary); | ||||
|         picker.FileTypeFilter().Append(L".xlsx"); | ||||
|         picker.FileTypeFilter().Append(L".xls"); | ||||
| 
 | ||||
|         StorageFile file = co_await picker.PickSingleFileAsync(); | ||||
|         if(file == nullptr) { p.Reject("File not Found"); co_return; } | ||||
| 
 | ||||
|         auto buf = co_await FileIO::ReadBufferAsync(file); | ||||
|         p.Resolve(CryptographicBuffer::EncodeToBase64String(buf)); | ||||
|         co_return; | ||||
|       }); | ||||
|     } | ||||
| 
 | ||||
|     private: | ||||
|       ReactContext context{nullptr}; | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										41
									
								
								docz/static/reactnative/desktop/App.tsx
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										41
									
								
								docz/static/reactnative/desktop/App.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| import React, { useState, type Node } from 'react'; | ||||
| import { SafeAreaView, ScrollView, StyleSheet, Text, TouchableHighlight, View } from 'react-native'; | ||||
| import { read, utils, version } from 'xlsx'; | ||||
| import { getEnforcing } from 'react-native/Libraries/TurboModule/TurboModuleRegistry'; | ||||
| const DocumentPicker = getEnforcing('DocumentPicker'); | ||||
| 
 | ||||
| const App: () => Node = () => { | ||||
| 
 | ||||
|   const [ aoa, setAoA ] = useState(["SheetJS".split(""), "5433795".split("")]); | ||||
| 
 | ||||
|   return ( | ||||
|     <SafeAreaView style={styles.outer}> | ||||
|       <Text style={styles.title}>SheetJS × React Native Windows {version}</Text> | ||||
|       <TouchableHighlight onPress={async() => { | ||||
|         try { | ||||
|           const b64 = await DocumentPicker.PickAndRead(); | ||||
|           const wb = read(b64); | ||||
|           setAoA(utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1 } )); | ||||
|         } catch(err) { alert(`Error: ${err.message}`); } | ||||
|       }}><Text style={styles.button}>Click here to Open File!</Text></TouchableHighlight> | ||||
|       <ScrollView contentInsetAdjustmentBehavior="automatic"> | ||||
|         <View style={styles.table}>{aoa.map((row,R) => ( | ||||
|           <View style={styles.row} key={R}>{row.map((cell,C) => ( | ||||
|             <View style={styles.cell} key={C}><Text>{cell}</Text></View> | ||||
|           ))}</View> | ||||
|         ))}</View> | ||||
|       </ScrollView> | ||||
|     </SafeAreaView> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| const styles = StyleSheet.create({ | ||||
|   cell: { flex: 4 }, | ||||
|   row: { flexDirection: 'row', justifyContent: 'space-evenly', padding: 10, backgroundColor: 'white', }, | ||||
|   table: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', }, | ||||
|   outer: { marginTop: 32, paddingHorizontal: 24, }, | ||||
|   title: { fontSize: 24, fontWeight: '600', }, | ||||
|   button: { marginTop: 8, fontSize: 18, fontWeight: '400', }, | ||||
| }); | ||||
| 
 | ||||
| export default App; | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 11 KiB | 
		Loading…
	
		Reference in New Issue
	
	Block a user