/* sheetjs.v8 (C) SheetJS -- https://sheetjs.com */ /* based on the official V8 samples ("BSD-3-Clause") */ #include #include #include #include "include/libplatform/libplatform.h" #include "include/v8.h" 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((void *) buf, 1, fsize, f); fclose(f); return buf; } v8::Local eval_code(v8::Isolate *isolate, v8::Local context, char* code, size_t sz = -1) { v8::Local source = v8::String::NewFromUtf8(isolate, code, v8::NewStringType::kNormal, sz).ToLocalChecked(); v8::Local script = v8::Script::Compile(context, source).ToLocalChecked(); return script->Run(context).ToLocalChecked(); } #define EVAL_CODE(x) eval_code(isolate, context, (char *)x) #define EVAL_CODE2(x,sz) eval_code(isolate, context, (char *)x, sz) int main(int argc, char* argv[]) { /* initialize -- this part is from the hello world example */ v8::V8::InitializeICUDefaultLocation(argv[0]); v8::V8::InitializeExternalStartupData(argv[0]); std::unique_ptr platform = v8::platform::NewDefaultPlatform(); v8::V8::InitializePlatform(platform.get()); v8::V8::Initialize(); v8::Isolate::CreateParams create_params; create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator(); v8::Isolate* isolate = v8::Isolate::New(create_params); { v8::Isolate::Scope isolate_scope(isolate); v8::HandleScope handle_scope(isolate); v8::Local context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); /* load library */ { /* read file */ size_t sz; char *file = read_file("xlsx.full.min.js", &sz); if(!file) { perror("Error reading xlsx.full.min.js"); return 1; } /* evaluate */ v8::Local result = EVAL_CODE2(file, sz); /* free */ free(file); } /* get version string */ { v8::Local result = EVAL_CODE("XLSX.version"); v8::String::Utf8Value vers(isolate, result); printf("SheetJS library version %s\n", *vers); } /* read file */ { /* read bytes */ size_t sz; char *file = read_file(argv[1], &sz); if(!file) { perror("Error reading file"); return 1; } /* copy into array buffer and assign to `buf` in the global scope */ { std::unique_ptr back = v8::ArrayBuffer::NewBackingStore(isolate, sz); memcpy(back->Data(), file, sz); v8::Local ab = v8::ArrayBuffer::New(isolate, std::move(back)); v8::Maybe res = context->Global()->Set(context, v8::String::NewFromUtf8Literal(isolate, "buf"), ab); } printf("Loaded file %s\n", argv[1]); } /* parse workbook and assign to global `wb` property */ { v8::Local result = EVAL_CODE("globalThis.wb = XLSX.read(buf)"); } /* print CSV of first worksheet */ { v8::Local result = EVAL_CODE("XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]])"); v8::String::Utf8Value csv(isolate, result); printf("%s\n", *csv); } // write sheetjsw.xlsb { v8::Local result = EVAL_CODE("XLSX.write(wb, {type:'array', bookType:'xlsb'})"); v8::Local ab = v8::Local::Cast(result); FILE *f = fopen("sheetjsw.xlsb", "wb"); fwrite((char *)ab->Data(), 1, ab->ByteLength(), f); fclose(f); } } /* cleanup -- this part is from the hello world example */ isolate->Dispose(); v8::V8::Dispose(); v8::V8::DisposePlatform(); delete create_params.array_buffer_allocator; return 0; }