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