fn doit(ctx: &ducc::Ducc, code: &str) { ctx.compile(code, None).unwrap().call::<(), ()>(()).unwrap(); } fn get_string(str: ducc::Value) -> String { str.as_string().unwrap().to_string().unwrap() } fn main() { let ctx = ducc::Ducc::new(); /* initialize */ doit(&ctx, "var global = (function(){ return this; }).call(null);"); /* load library */ { doit(&ctx, include_str!("shim.min.js")); doit(&ctx, include_str!("xlsx.full.min.js")); } /* get version string */ { let vers: ducc::Value = ctx.compile("XLSX.version", None).unwrap().call(()).unwrap(); println!("SheetJS library version {}", get_string(vers)); } /* read file */ { let mut iter = std::env::args(); let path: String = iter.nth(1).expect("must specify a file name"); let file: Vec = std::fs::read(path.clone()).unwrap(); /* push data to duktape (creates a Uint8Array) */ let bytes = ctx.create_bytes(file.as_slice()).unwrap(); /* assign to global `buf` */ let _ = ctx.globals().set("buf", bytes); } /* parse workbook */ { doit(&ctx, "wb = XLSX.read(buf.slice(0, buf.length), {type:'buffer'});"); doit(&ctx, "ws = wb.Sheets[wb.SheetNames[0]]"); } /* print CSV */ { let csv: ducc::Value = ctx.compile("XLSX.utils.sheet_to_csv(ws)", None).unwrap().call(()).unwrap(); println!("{}", get_string(csv)); } /* write file */ { /* due to issues with the duktape crate, it is easier to pass a base64-encoded string and decode in Rust */ let xlsb: ducc::Value = ctx.compile("XLSX.write(wb, {type:'base64', bookType:'xlsb'})", None).unwrap().call(()).unwrap(); let _ = std::fs::write("sheetjsw.xlsb", base64::Engine::decode(&base64::engine::general_purpose::STANDARD, get_string(xlsb)).unwrap()); } }