forked from sheetjs/docs.sheetjs.com
		
	
		
			
	
	
		
			112 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			112 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #include <stdio.h>
 | ||
|  | #include <stdlib.h>
 | ||
|  | #include <JavaScriptCore/JavaScript.h>
 | ||
|  | 
 | ||
|  | /* 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; | ||
|  | } |