#!/usr/bin/env perl # SheetJE.pl (c) SheetJS LLC -- https://sheetjs.com use JE; use File::Slurp; use MIME::Base64 qw( encode_base64 ); ## Initialize say STDERR "Initializing Engine"; my $je = new JE; $je->eval("var global = (function(){ return this; }).call(null);"); $je->eval(<<'EOF'); Number.prototype.charCodeAt = function(n) { return this + 48; }; var string = ""; for(var i = 0; i < 256; ++i) string += String.fromCharCode(i); String.prototype.charCodeAt = function(n) { var result = string.indexOf(this.charAt(n)); if(result == -1) throw this.charAt(n); return result; }; String.prototype.old_match = String.prototype.match; String.prototype.match = function(p) { var result = this.old_match(p); return (Array.isArray(result) && result.length == 0) ? null : result; }; EOF ## Load SheetJS source say STDERR "Loading SheetJS Library"; my $src = read_file('xlsx.extendscript.js', { binmode => ':raw' }); $src =~ s/^\xEF\xBB\xBF//; my $XLSX = $je->eval($src); ## Set up conversion method $je->eval(<<'EOF'); function sheetjsparse(data) { try { return XLSX.read(String(data), {type: "base64", WTF:1}); } catch(e) { return String(e); } } function sheetjscsv(wb) { try { var ws = wb.Sheets[wb.SheetNames[0]]; return XLSX.utils.sheet_to_csv(ws); } catch(e) { return String(e); } } function sheetjswrite(wb) { try { return XLSX.write(wb, { WTF:1, bookType: "fods", type: "string" }); } catch(e) { return String(e); } } EOF ## Read file say STDERR "Parsing " . $ARGV[0]; my $raw_data = encode_base64(read_file($ARGV[0], { binmode => ':raw' }), ""); $workbook = $je->method(sheetjsparse => $raw_data); ## Convert to CSV say STDERR "Converting to CSV"; my $csv_data = $je->method(sheetjscsv => $workbook); print $csv_data; ## Write to SheetJE.fods say STDERR "Writing to SheetJE.fods"; my $fods = $je->method(sheetjswrite => $workbook); write_file("SheetJE.fods", $fods);