const std = @import("std"); const duktape = @cImport({ @cInclude("duktape.h"); }); // SheetJS scripts embedded at comptime const shim = @embedFile("shim.min.js"); const xlsx = @embedFile("xlsx.full.min.js"); pub fn main() !void { // initialize duktape const ctx = duktape.duk_create_heap(null, null, null, null, null); defer _ = duktape.duk_destroy_heap(ctx); // load SheetJS scripts _ = duktape.duk_peval_string(ctx, shim); _ = duktape.duk_peval_string(ctx, xlsx); // display version number _ = duktape.duk_peval_string(ctx, "XLSX.version"); const sum = duktape.duk_get_string(ctx, -1); std.debug.print("SheetJS Version {s}\n", .{sum}); duktape.duk_pop(ctx); // create allocator var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); var alloc = gpa.allocator(); // determine file to read var args = try std.process.argsWithAllocator(alloc); defer args.deinit(); _ = args.next(); const path = args.next(); if (path == null) { std.debug.print("Must specify a filename!", .{}); return; } std.debug.print("Reading from {s}\n", .{path.?}); // read file const file = try std.fs.cwd().readFileAlloc(alloc, path.?, std.math.maxInt(usize)); defer alloc.free(file); std.debug.print("Size: {} bytes\n", .{file.len}); // load into duktape _ = duktape.duk_push_buffer_raw(ctx, 0, duktape.DUK_BUF_FLAG_DYNAMIC | duktape.DUK_BUF_FLAG_EXTERNAL); duktape.duk_config_buffer(ctx, -1, file.ptr, file.len); _ = duktape.duk_put_global_string(ctx, "buf"); _ = duktape.duk_eval_raw(ctx, "workbook = XLSX.read(buf.slice(0, buf.length), {type:'buffer'});", 0, duktape.DUK_COMPILE_EVAL | duktape.DUK_COMPILE_NOSOURCE | duktape.DUK_COMPILE_STRLEN | duktape.DUK_COMPILE_NORESULT | duktape.DUK_COMPILE_NOFILENAME); // display CSV of first worksheet _ = duktape.duk_peval_string(ctx, "XLSX.utils.sheet_to_csv(workbook.Sheets[workbook.SheetNames[0]])"); const csv = duktape.duk_get_string(ctx, -1); std.debug.print("{s}\n", .{csv}); duktape.duk_pop(ctx); // convert to XLSX _ = duktape.duk_eval_raw(ctx, "XLSX.write(workbook, {type:'array', bookType:'xlsx'})", 0, duktape.DUK_COMPILE_EVAL | duktape.DUK_COMPILE_NOSOURCE | duktape.DUK_COMPILE_STRLEN | duktape.DUK_COMPILE_NOFILENAME); var sz: usize = 0; const c_ptr: *anyopaque = duktape.duk_get_buffer_data(ctx, -1, &sz).?; // generate zig slice from C pointer + length const slc: []u8 = @as([*]u8, @ptrCast(c_ptr))[0..sz]; // write to file _ = try std.fs.cwd().writeFile(.{ .sub_path = "sheetjs.zig.xlsx", .data = slc }); }