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