forked from sheetjs/docs.sheetjs.com
		
	
		
			
	
	
		
			102 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			102 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
|  | <?php | ||
|  | 
 | ||
|  | $ffi = FFI::cdef(' | ||
|  | typedef int duk_int_t; | ||
|  | typedef unsigned int duk_uint_t; | ||
|  | typedef unsigned int duk_small_uint_t; | ||
|  | typedef size_t duk_size_t; | ||
|  | typedef duk_int_t duk_idx_t; | ||
|  | typedef duk_small_uint_t duk_bool_t; | ||
|  | 
 | ||
|  | typedef struct duk_hthread duk_context; | ||
|  | 
 | ||
|  | void duk_push_undefined(duk_context *ctx); | ||
|  | const char *duk_push_lstring(duk_context *ctx, const char *str, duk_size_t len); | ||
|  | duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags); | ||
|  | void duk_pop(duk_context *ctx); | ||
|  | void duk_config_buffer(duk_context *ctx, duk_idx_t idx, void *ptr, duk_size_t len); | ||
|  | void *duk_push_buffer_raw(duk_context *ctx, duk_size_t size, duk_small_uint_t flags); | ||
|  | duk_bool_t duk_put_global_string(duk_context *ctx, const char *key); | ||
|  | duk_bool_t duk_get_global_string(duk_context *ctx, const char *key); | ||
|  | void *duk_get_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size); | ||
|  | const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len); | ||
|  | void duk_destroy_heap(duk_context *ctx); | ||
|  | duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags); | ||
|  | duk_context *duk_create_heap(void* alloc_func, void* realloc_func, void* free_func, void *heap_udata, void *fatal_handler); | ||
|  | const char *duk_get_string(duk_context *ctx, duk_idx_t idx); | ||
|  | ', './libduktape.207.20700.so' ); | ||
|  | 
 | ||
|  | function duk_create_heap_default() { global $ffi;	return $ffi->duk_create_heap(null, null, null, null, null); } | ||
|  | function duk_eval_string_noresult($context, $cmd) { global $ffi; return $ffi->duk_eval_raw($context, $cmd, 0, 1 | (1<<3) | (1<<9) | (1<<10) | (1<<8) | (1<<11) ); } | ||
|  | function duk_eval_string($context, $cmd) { global $ffi; return $ffi->duk_eval_raw($context, $cmd, 0, 0 | (1<<3) | (1<<9) | (1<<10) | (1<<11) ); } | ||
|  | function duk_peval($context) { global $ffi; return $ffi->duk_eval_raw($context, null, 0, 1 | (1<<3) | (1<<7) | (1<<11) ); } | ||
|  | function duk_get_string($context, $idx) { global $ffi; return $ffi->duk_get_string($context, $idx); } | ||
|  | function duk_pop($context) { global $ffi; return $ffi->duk_pop($context); } | ||
|  | 
 | ||
|  | function eval_file($context, $path) { | ||
|  |   global $ffi; | ||
|  |   $script = file_get_contents($path); | ||
|  |   $ffi->duk_push_lstring($context, $script, strlen($script)); | ||
|  |   $retval = duk_peval($context); | ||
|  |   $ffi->duk_pop($context); | ||
|  |   return $retval; | ||
|  | } | ||
|  | function load_file($context, $path, $var) { | ||
|  |   global $ffi; | ||
|  |   $data = file_get_contents($path); | ||
|  | 
 | ||
|  |   $ffi->duk_push_buffer_raw($context, 0, 1 | 2); | ||
|  |   $ffi->duk_config_buffer($context, -1, $data, strlen($data)); | ||
|  |   $ffi->duk_put_global_string($context, $var); | ||
|  |   return 0; | ||
|  | } | ||
|  | function save_file($context, $path, $var) { | ||
|  |   global $ffi; | ||
|  |   $ffi->duk_get_global_string($context, $var); | ||
|  | 
 | ||
|  |   $sz = $ffi->new("duk_size_t"); | ||
|  |   $ptr = $ffi->duk_get_buffer_data($context, -1, FFI::addr($sz)); | ||
|  |   $buf = FFI::string($ptr, strval($sz)); | ||
|  | 
 | ||
|  |   $fh = fopen($path, "wb"); | ||
|  |   fwrite($fh, $buf, strval($sz)); | ||
|  |   fclose($fh); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | function DOIT($cmd) { global $context; return duk_eval_string_noresult($context, $cmd); } | ||
|  | 
 | ||
|  | /* initialize */ | ||
|  | $context = duk_create_heap_default(); | ||
|  | /* duktape does not expose a standard "global" by default */ | ||
|  | DOIT("var global = (function(){ return this; }).call(null);"); | ||
|  | 
 | ||
|  | /* load library */ | ||
|  | eval_file($context, "shim.min.js"); | ||
|  | eval_file($context, "xlsx.full.min.js"); | ||
|  | 
 | ||
|  | /* get version string */ | ||
|  | duk_eval_string($context, "XLSX.version"); | ||
|  | printf("SheetJS Library Version %s\n", duk_get_string($context, -1)); | ||
|  | duk_pop($context); | ||
|  | 
 | ||
|  | /* read file */ | ||
|  | $res = load_file($context, $argv[1], "buf"); | ||
|  | printf("Loaded file %s\n", $argv[1]); | ||
|  | 
 | ||
|  | /* parse workbook */ | ||
|  | DOIT("wb = XLSX.read(buf.slice(0, buf.length), {type:'buffer'});"); | ||
|  | DOIT("ws = wb.Sheets[wb.SheetNames[0]]"); | ||
|  | 
 | ||
|  | /* print CSV */ | ||
|  | duk_eval_string($context, "XLSX.utils.sheet_to_csv(ws)"); | ||
|  | printf("%s\n", duk_get_string($context, -1)); | ||
|  | duk_pop($context); | ||
|  | 
 | ||
|  | /* write file */ | ||
|  | DOIT("newbuf = (XLSX.write(wb, {type:'array', bookType:'xlsb'}));"); | ||
|  | save_file($context, "sheetjsw.xlsb", "newbuf"); | ||
|  | 
 | ||
|  | /* cleanup */ | ||
|  | $ffi->duk_destroy_heap($context); | ||
|  | return 0; |