#include #include #include /* simple wrapper to read the entire script file */ static char *read_file(const char *filename, size_t *sz) { FILE *f = fopen(filename, "rb"); if(!f) return NULL; long fsize; { fseek(f, 0, SEEK_END); fsize = ftell(f); fseek(f, 0, SEEK_SET); } char *buf = (char *)malloc(fsize * sizeof(char)); *sz = fread(buf, 1, fsize, f); fclose(f); return buf; } #define JS_STR_TO_C \ JSStringRef str = JSValueToStringCopy(ctx, result, NULL); \ size_t sz = JSStringGetMaximumUTF8CStringSize(str); \ char *buf = (char *)malloc(sz); \ JSStringGetUTF8CString(str, buf, sz); \ #define DOIT(cmd) \ JSStringRef script = JSStringCreateWithUTF8CString(cmd); \ JSValueRef result = JSEvaluateScript(ctx, script, NULL, NULL, 0, NULL); \ JSStringRelease(script); int main(int argc, char **argv) { int res = 0; size_t sz = 0; char *file = NULL; /* initialize */ JSGlobalContextRef ctx = JSGlobalContextCreate(NULL); /* JSC does not expose a standard "global" by default */ { DOIT("var global = (function(){ return this; }).call(null);") } /* load library */ { file = read_file("xlsx.full.min.js", &sz); DOIT(file); free(file); } /* get version string */ { DOIT("XLSX.version") if(!JSValueIsString(ctx, result)) { printf("Could not get SheetJS version.\n"); res = 1; goto cleanup; } JS_STR_TO_C printf("SheetJS library version %s\n", buf); free(buf); JSStringRelease(str); } /* read file */ file = read_file(argv[1], &sz); { /* push data to JSC */ JSValueRef u8 = JSObjectMakeTypedArrayWithBytesNoCopy(ctx, kJSTypedArrayTypeUint8Array, file, sz, NULL, NULL, NULL); /* assign to `global.buf` */ JSObjectRef global = JSContextGetGlobalObject(ctx); JSStringRef key = JSStringCreateWithUTF8CString("buf"); JSObjectSetProperty(ctx, global, key, u8, 0, NULL); JSStringRelease(key); } /* parse workbook and print CSV */ { DOIT( "var wb = XLSX.read(global.buf);" "var ws = wb.Sheets[wb.SheetNames[0]];" "XLSX.utils.sheet_to_csv(ws)" ) if(!JSValueIsString(ctx, result)) { printf("Could not generate CSV.\n"); res = 2; goto cleanup; } JS_STR_TO_C printf("%s\n", buf); free(buf); JSStringRelease(str); } /* write file */ { DOIT("XLSX.write(wb, {type:'buffer', bookType:'xlsb'});") /* pull Uint8Array data back to C */ JSObjectRef u8 = JSValueToObject(ctx, result, NULL); size_t sz = JSObjectGetTypedArrayLength(ctx, u8, NULL); char *buf = (char *)JSObjectGetTypedArrayBytesPtr(ctx, u8, NULL); /* save file */ FILE *f = fopen("sheetjsw.xlsb", "wb"); fwrite(buf, 1, sz, f); fclose(f); } cleanup: // Release the JavaScript context JSGlobalContextRelease(ctx); if(file) free(file); return res; }