forked from sheetjs/docs.sheetjs.com
		
	
		
			
	
	
		
			152 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			152 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
|  | --- | ||
|  | title: Rust + Boa | ||
|  | pagination_prev: demos/bigdata/index | ||
|  | pagination_next: solutions/input | ||
|  | --- | ||
|  | 
 | ||
|  | import current from '/version.js'; | ||
|  | import CodeBlock from '@theme/CodeBlock'; | ||
|  | 
 | ||
|  | :::warning | ||
|  | 
 | ||
|  | In a production application, it is strongly recommended to use a binding for a | ||
|  | more performant engine like [`v8`](/docs/demos/engines/v8#rust) | ||
|  | 
 | ||
|  | ::: | ||
|  | 
 | ||
|  | Boa is a pure-Rust JavaScript engine. | ||
|  | 
 | ||
|  | The [Standalone scripts](/docs/getting-started/installation/standalone) can be | ||
|  | parsed and evaluated in a Boa context. | ||
|  | 
 | ||
|  | 
 | ||
|  | ## Integration Details
 | ||
|  | 
 | ||
|  | _Initialize Engine_ | ||
|  | 
 | ||
|  | A JS context can be constructed in one line: | ||
|  | 
 | ||
|  | ```rust | ||
|  | use boa_engine::Context; | ||
|  | 
 | ||
|  | /* initialize */ | ||
|  | let context = &mut Context::default(); | ||
|  | ``` | ||
|  | 
 | ||
|  | The following helper function evaluates strings as JS code: | ||
|  | 
 | ||
|  | ```rust | ||
|  | use std::string::String; | ||
|  | use boa_engine::{Context, Source, JsError}; | ||
|  | 
 | ||
|  | /* simple wrapper to evaluate code snippets */ | ||
|  | fn eval_code(c: &mut Context, code: &str) -> Result<String, JsError> { | ||
|  |   let src = Source::from_bytes(code); | ||
|  |   match c.eval_script(src) { | ||
|  |     Ok(res) => { return Ok(res.to_string(c).unwrap().to_std_string_escaped()); } | ||
|  |     Err(e) => { return Err(e); } | ||
|  |   }; | ||
|  | } | ||
|  | ``` | ||
|  | 
 | ||
|  | _Load SheetJS Scripts_ | ||
|  | 
 | ||
|  | Boa provides a special helper to read source code from a path: | ||
|  | 
 | ||
|  | ```rust | ||
|  | use std::path::Path; | ||
|  | use std::string::String; | ||
|  | use boa_engine::{Context, Source, JsError}; | ||
|  | 
 | ||
|  | /* simple wrapper to evaluate an entire script file */ | ||
|  | fn eval_file(c: &mut Context, path: &str) -> Result<String, JsError> { | ||
|  |   let src = Source::from_filepath(Path::new(path)).unwrap(); | ||
|  |   match c.eval_script(src) { | ||
|  |     Ok(res) => { return Ok(res.to_string(c).unwrap().to_std_string_escaped()); } | ||
|  |     Err(e) => { return Err(e); } | ||
|  |   }; | ||
|  | } | ||
|  | 
 | ||
|  | // ... | ||
|  |   /* load library */ | ||
|  |   match eval_file(context, "./xlsx.full.min.js") { | ||
|  |     Ok(_res) => {} | ||
|  |     Err(e) => { return eprintln!("Uncaught {e}"); } | ||
|  |   } | ||
|  | ``` | ||
|  | 
 | ||
|  | To confirm the library is loaded, `XLSX.version` can be inspected: | ||
|  | 
 | ||
|  | ```rust | ||
|  |   /* get version string */ | ||
|  |   match eval_code(context, "XLSX.version") { | ||
|  |     Ok(res) => { println!( "SheetJS library version {}", res); } | ||
|  |     Err(e) => { return eprintln!("Uncaught {e}"); } | ||
|  |   } | ||
|  | ``` | ||
|  | 
 | ||
|  | ### Reading Files
 | ||
|  | 
 | ||
|  | Boa supports `ArrayBuffer` natively.  This snippet reads data from a file into | ||
|  | `Vec<u8>` and stores the data as an `ArrayBuffer` in global scope: | ||
|  | 
 | ||
|  | ```rust | ||
|  |   /* read file */ | ||
|  |   let data: Vec<u8> = fs::read("pres.xlsx").unwrap(); | ||
|  |   let array: JsArrayBuffer = JsArrayBuffer::from_byte_block(data, context).unwrap(); | ||
|  |   let attrs = Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE; | ||
|  |   context.register_global_property("buf", array, attrs); | ||
|  | 
 | ||
|  |   /* parse with SheetJS */ | ||
|  |   match eval_code(context, "void (globalThis.wb = XLSX.read(buf))") { | ||
|  |     Ok(_res) => { } | ||
|  |     Err(e) => { return eprintln!("Uncaught {e}"); } | ||
|  |   } | ||
|  | ``` | ||
|  | 
 | ||
|  | `wb` will be a variable in the JS environment that can be inspected using the | ||
|  | various SheetJS API functions. | ||
|  | 
 | ||
|  | ## Complete Example
 | ||
|  | 
 | ||
|  | :::note | ||
|  | 
 | ||
|  | This demo was tested on 2023 May 22 | ||
|  | 
 | ||
|  | ::: | ||
|  | 
 | ||
|  | 1) Create a new project: | ||
|  | 
 | ||
|  | ```bash | ||
|  | cargo new sheetjs-rs | ||
|  | cd sheetjs-rs | ||
|  | cargo run | ||
|  | ``` | ||
|  | 
 | ||
|  | 2) Add the `boa` crate from the Git repository: | ||
|  | 
 | ||
|  | ```bash | ||
|  | cargo add --git https://github.com/boa-dev/boa boa_engine | ||
|  | ``` | ||
|  | 
 | ||
|  | 3) 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> | ||
|  | 
 | ||
|  | 4) Download [`main.rs`](pathname:///boa/main.rs) and replace `src/main.rs`: | ||
|  | 
 | ||
|  | ```bash | ||
|  | curl -L -o src/main.rs https://docs.sheetjs.com/boa/main.rs | ||
|  | ``` | ||
|  | 
 | ||
|  | 5) Download [the test file](https://sheetjs.com/pres.xlsx) and run: | ||
|  | 
 | ||
|  | ```bash | ||
|  | curl -LO https://sheetjs.com/pres.xlsx | ||
|  | cargo run | ||
|  | ``` | ||
|  | 
 | ||
|  | After a short wait, the contents will be displayed in CSV form. |