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;
 | |
| } |