v8-cli
This commit is contained in:
parent
58f45f9574
commit
6275307071
@ -17,6 +17,68 @@ it is feasible to build command-line tools for various workflows.
|
||||
This demo covers a number of strategies for building standalone processors. The
|
||||
goal is to generate CSV output from an arbitrary spreadsheet file.
|
||||
|
||||
## V8
|
||||
|
||||
The [V8](/docs/demos/engines/v8) demo covers standalone programs that embed the
|
||||
V8 engine. This demo uses the Rust integration to generate a command line tool.
|
||||
|
||||
<details><summary><b>Tested Deployments</b> (click to show)</summary>
|
||||
|
||||
This demo was last tested in the following deployments:
|
||||
|
||||
| Architecture | V8 Version | Date |
|
||||
|:-------------|:-------------|:-----------|
|
||||
| `darwin-x64` | `11.4.183.2` | 2023-05-22 |
|
||||
|
||||
</details>
|
||||
|
||||
0) Make a new folder for the project:
|
||||
|
||||
```bash
|
||||
mkdir sheetjs2csv
|
||||
cd sheetjs2csv
|
||||
```
|
||||
|
||||
1) Download the following scripts:
|
||||
|
||||
- [`Cargo.toml`](pathname:///cli/Cargo.toml)
|
||||
- [`snapshot.rs`](pathname:///cli/snapshot.rs)
|
||||
- [`sheet2csv.rs`](pathname:///cli/sheet2csv.rs)
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/cli/Cargo.toml
|
||||
curl -LO https://docs.sheetjs.com/cli/snapshot.rs
|
||||
curl -LO https://docs.sheetjs.com/cli/sheet2csv.rs
|
||||
```
|
||||
|
||||
2) Download the [standalone build](/docs/getting-started/installation/standalone):
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Build the V8 snapshot:
|
||||
|
||||
```bash
|
||||
cargo build --bin snapshot
|
||||
cargo run --bin snapshot
|
||||
```
|
||||
|
||||
4) Build `sheet2csv`:
|
||||
|
||||
```bash
|
||||
cargo build --release --bin sheet2csv
|
||||
mv target/release/sheet2csv .
|
||||
```
|
||||
|
||||
5) Download the test file <https://sheetjs.com/pres.numbers>:
|
||||
|
||||
```bash
|
||||
curl -LO https://sheetjs.com/pres.numbers
|
||||
```
|
||||
|
||||
Test by running `./sheet2csv pres.numbers`
|
||||
|
||||
## NodeJS
|
||||
|
||||
There are a few popular tools for compiling NodeJS scripts to CLI programs.
|
||||
@ -185,8 +247,8 @@ deno compile -r --allow-read https://docs.sheetjs.com/cli/sheet2csv.ts
|
||||
|
||||
The following demos for JS engines produce standalone programs:
|
||||
|
||||
- [ChakraCore](/docs/demos/engines/chakra)
|
||||
- [Duktape](/docs/demos/engines/duktape)
|
||||
- [ChakraCore](/docs/demos/engines/chakra)
|
||||
- [QuickJS](/docs/demos/engines/quickjs)
|
||||
- [Goja](/docs/demos/engines/goja)
|
||||
- [JavaScriptCore](/docs/demos/engines/jsc)
|
||||
- [QuickJS](/docs/demos/engines/quickjs)
|
||||
|
@ -183,6 +183,20 @@ const worker = new Worker(
|
||||
|
||||
## Live Demos
|
||||
|
||||
:::note
|
||||
|
||||
Each browser demo was tested in the following environments:
|
||||
|
||||
| Browser | Date | Comments |
|
||||
|:------------|:-----------|:----------------------------------------|
|
||||
| Chrome 113 | 2023-05-22 | |
|
||||
| Edge 113 | 2023-05-22 | |
|
||||
| Safari 16.4 | 2023-05-22 | File System Access API is not supported |
|
||||
| Brave 1.51 | 2023-05-22 | File System Access API is not supported |
|
||||
| Firefox 113 | 2023-05-22 | File System Access API is not supported |
|
||||
|
||||
:::
|
||||
|
||||
### Downloading a Remote File
|
||||
|
||||
:::note fetch in Web Workers
|
||||
|
15
docz/static/cli/Cargo.toml
Normal file
15
docz/static/cli/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "sheetjs2csv"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
v8 = "0.71.2"
|
||||
|
||||
[[bin]]
|
||||
name = "sheet2csv"
|
||||
path = "sheet2csv.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "snapshot"
|
||||
path = "snapshot.rs"
|
42
docz/static/cli/sheet2csv.rs
Normal file
42
docz/static/cli/sheet2csv.rs
Normal file
@ -0,0 +1,42 @@
|
||||
/* run code, get result as a Rust String */
|
||||
fn eval_code(scope: &mut v8::HandleScope, code: &str) -> std::string::String {
|
||||
let source = v8::String::new(scope, &code).unwrap();
|
||||
let script = v8::Script::compile(scope, source, None).unwrap();
|
||||
let result = script.run(scope).unwrap();
|
||||
return result.to_string(scope).unwrap().to_rust_string_lossy(scope);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
/* parse arguments */
|
||||
let mut iter = std::env::args();
|
||||
let path: String = iter.nth(1).expect("must specify a file name");
|
||||
let sheetname: String = match iter.nth(0) {
|
||||
Some(v) => format!("'{}'", v),
|
||||
None => "wb.SheetNames[0]".to_string()
|
||||
};
|
||||
|
||||
/* initialize */
|
||||
let platform = v8::new_default_platform(0, false).make_shared();
|
||||
v8::V8::initialize_platform(platform);
|
||||
v8::V8::initialize();
|
||||
|
||||
/* read snapshot */
|
||||
let startup_data: Vec<u8> = include_bytes!("./snapshot.bin").to_vec();
|
||||
let params = v8::Isolate::create_params().snapshot_blob(startup_data);
|
||||
let isolate = &mut v8::Isolate::new(params);
|
||||
let handle_scope = &mut v8::HandleScope::new(isolate);
|
||||
let context = v8::Context::new(handle_scope);
|
||||
let context_scope = &mut v8::ContextScope::new(handle_scope, context);
|
||||
|
||||
/* read file */
|
||||
let data: Vec<u8> = std::fs::read(path.clone()).unwrap();
|
||||
let back: v8::UniqueRef<v8::BackingStore> = v8::ArrayBuffer::new_backing_store_from_vec(data);
|
||||
let shared = back.make_shared();
|
||||
let ab: v8::Local<v8::ArrayBuffer> = v8::ArrayBuffer::with_backing_store(context_scope, &shared);
|
||||
let key = v8::String::new(context_scope, "buf").unwrap();
|
||||
context.global(context_scope).set(context_scope, key.into(), ab.into());
|
||||
|
||||
/* print CSV of specified sheet */
|
||||
let result = eval_code(context_scope, &mut format!("var wb = XLSX.read(buf, {{dense: true}}); XLSX.utils.sheet_to_csv(wb.Sheets[{}])", sheetname));
|
||||
println!("{}", result);
|
||||
}
|
38
docz/static/cli/snapshot.rs
Normal file
38
docz/static/cli/snapshot.rs
Normal file
@ -0,0 +1,38 @@
|
||||
/* run code, get result as a Rust String */
|
||||
fn eval_code(scope: &mut v8::HandleScope, code: &str) -> std::string::String {
|
||||
let source = v8::String::new(scope, &code).unwrap();
|
||||
let script = v8::Script::compile(scope, source, None).unwrap();
|
||||
let result = script.run(scope).unwrap();
|
||||
return result.to_string(scope).unwrap().to_rust_string_lossy(scope);
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
create_snapshot();
|
||||
}
|
||||
|
||||
fn create_snapshot() {
|
||||
/* initialize */
|
||||
let platform = v8::new_default_platform(0, false).make_shared();
|
||||
v8::V8::initialize_platform(platform);
|
||||
v8::V8::initialize();
|
||||
|
||||
let startup_data = {
|
||||
let mut isolate = v8::Isolate::snapshot_creator(None);
|
||||
{
|
||||
let handle_scope = &mut v8::HandleScope::new(&mut isolate);
|
||||
let context = v8::Context::new(handle_scope);
|
||||
let context_scope = &mut v8::ContextScope::new(handle_scope, context);
|
||||
|
||||
/* load library */
|
||||
{
|
||||
let script = std::fs::read_to_string("./xlsx.full.min.js").expect("Error reading xlsx.full.min.js");
|
||||
let _result = eval_code(context_scope, &script);
|
||||
}
|
||||
context_scope.set_default_context(context);
|
||||
}
|
||||
isolate.create_blob(v8::FunctionCodeHandling::Clear).unwrap()
|
||||
};
|
||||
let blob: Vec<u8> = startup_data.to_vec();
|
||||
std::fs::write("snapshot.bin", blob).unwrap();
|
||||
}
|
Loading…
Reference in New Issue
Block a user