2023-05-21 02:11:51 +00:00
|
|
|
/* sheetjs.v8 (C) SheetJS -- https://sheetjs.com */
|
|
|
|
/* based on the official V8 samples ("BSD-3-Clause") */
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#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;
|
|
|
|
}
|
|
|
|
|
2023-08-26 23:05:59 +00:00
|
|
|
v8::Local<v8::Value> eval_code(v8::Isolate *isolate, v8::Local<v8::Context> context, char* code, size_t sz = -1) {
|
|
|
|
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, code, v8::NewStringType::kNormal, sz).ToLocalChecked();
|
2023-05-21 02:11:51 +00:00
|
|
|
v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked();
|
|
|
|
return script->Run(context).ToLocalChecked();
|
|
|
|
}
|
|
|
|
#define EVAL_CODE(x) eval_code(isolate, context, (char *)x)
|
2023-08-26 23:05:59 +00:00
|
|
|
#define EVAL_CODE2(x,sz) eval_code(isolate, context, (char *)x, sz)
|
2023-05-21 02:11:51 +00:00
|
|
|
|
|
|
|
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<v8::Platform> 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<v8::Context> 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 */
|
2023-08-26 23:05:59 +00:00
|
|
|
v8::Local<v8::Value> result = EVAL_CODE2(file, sz);
|
2023-05-21 02:11:51 +00:00
|
|
|
|
|
|
|
/* free */
|
|
|
|
free(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get version string */
|
|
|
|
{
|
|
|
|
v8::Local<v8::Value> 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<v8::BackingStore> back = v8::ArrayBuffer::NewBackingStore(isolate, sz);
|
|
|
|
memcpy(back->Data(), file, sz);
|
|
|
|
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, std::move(back));
|
|
|
|
v8::Maybe<bool> 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<v8::Value> result = EVAL_CODE("globalThis.wb = XLSX.read(buf)");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* print CSV of first worksheet */
|
|
|
|
{
|
|
|
|
v8::Local<v8::Value> 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<v8::Value> result = EVAL_CODE("XLSX.write(wb, {type:'array', bookType:'xlsb'})");
|
|
|
|
v8::Local<v8::ArrayBuffer> ab = v8::Local<v8::ArrayBuffer>::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;
|
|
|
|
}
|