forked from sheetjs/sheetjs
version bump 0.12.5: ancillary utility update
- add BOM to `stream.to_csv` (fixes #1024 h/t @hr5959) - `utils.format_cell` type (h/t @victorj2307) - duktape niggles - demo cleanup
This commit is contained in:
parent
73a5e50f21
commit
5de62a947f
@ -106,6 +106,7 @@ ui-grid
|
||||
angular-cli
|
||||
|
||||
- demos/database/README.md
|
||||
Knex
|
||||
LowDB
|
||||
MariaDB
|
||||
MySQL
|
||||
|
@ -162,6 +162,7 @@ In the browser, just add a script tag:
|
||||
| `unpkg` | <https://unpkg.com/xlsx/> |
|
||||
| `jsDelivr` | <https://jsdelivr.com/package/npm/xlsx> |
|
||||
| `CDNjs` | <http://cdnjs.com/libraries/xlsx> |
|
||||
| `packd` | <https://bundle.run/xlsx?name=XLSX> |
|
||||
|
||||
`unpkg` makes the latest version available at:
|
||||
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.12.4';
|
||||
XLSX.version = '0.12.5';
|
||||
|
@ -14,7 +14,8 @@ function write_comments_vml(rId, comments) {
|
||||
];
|
||||
while(_shapeid < rId * 1000) _shapeid += 1000;
|
||||
|
||||
comments.map(function(x) { return decode_cell(x[0]); }).forEach(function(c) { o = o.concat([
|
||||
comments.forEach(function(x) { var c = decode_cell(x[0]);
|
||||
o = o.concat([
|
||||
'<v:shape' + wxt_helper({
|
||||
id:'_x0000_s' + (++_shapeid),
|
||||
type:"#_x0000_t202",
|
||||
|
@ -36,13 +36,11 @@ function write_comments_xml(data/*::, opts*/) {
|
||||
|
||||
var iauthor/*:Array<string>*/ = [];
|
||||
o.push("<authors>");
|
||||
data.map(function(x) { return x[1]; }).forEach(function(comment) {
|
||||
comment.map(function(x) { return escapexml(x.a); }).forEach(function(a) {
|
||||
if(iauthor.indexOf(a) > -1) return;
|
||||
iauthor.push(a);
|
||||
o.push("<author>" + a + "</author>");
|
||||
});
|
||||
});
|
||||
data.forEach(function(x) { x[1].forEach(function(w) { var a = escapexml(w.a);
|
||||
if(iauthor.indexOf(a) > -1) return;
|
||||
iauthor.push(a);
|
||||
o.push("<author>" + a + "</author>");
|
||||
}); });
|
||||
o.push("</authors>");
|
||||
o.push("<commentList>");
|
||||
data.forEach(function(d) {
|
||||
|
@ -163,6 +163,8 @@ function xlml_clean_comment(comment/*:any*/) {
|
||||
function xlml_normalize(d)/*:string*/ {
|
||||
if(has_buf &&/*::typeof Buffer !== "undefined" && d != null && d instanceof Buffer &&*/ Buffer.isBuffer(d)) return d.toString('utf8');
|
||||
if(typeof d === 'string') return d;
|
||||
/* duktape */
|
||||
if(typeof Uint8Array !== 'undefined' && d instanceof Uint8Array) return utf8read(a2s(ab2a(d)));
|
||||
throw new Error("Bad input format: expected Buffer or string");
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,9 @@ if(has_buf && typeof require != 'undefined') (function() {
|
||||
var rowinfo/*:Array<RowInfo>*/ = o.skipHidden && sheet["!rows"] || [];
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colinfo[C]||{}).hidden)) cols[C] = encode_col(C);
|
||||
var R = r.s.r;
|
||||
var BOM = false;
|
||||
stream._read = function() {
|
||||
if(!BOM) { BOM = true; return stream.push("\uFEFF"); }
|
||||
if(R > r.e.r) return stream.push(null);
|
||||
while(R <= r.e.r) {
|
||||
++R;
|
||||
|
1
demos/altjs/.gitignore
vendored
1
demos/altjs/.gitignore
vendored
@ -4,5 +4,6 @@ duk*
|
||||
*.class
|
||||
*.jar
|
||||
rhino
|
||||
shim.min.js
|
||||
xlsx.*.js
|
||||
payload.js
|
||||
|
@ -5,12 +5,16 @@ all: duktape nashorn rhinojs swift
|
||||
base:
|
||||
if [ ! -e sheetjs.xlsx ]; then node ../../tests/write.js; fi
|
||||
if [ ! -e xlsx.full.min.js ]; then cp ../../dist/xlsx.full.min.js .; fi
|
||||
if [ ! -e shim.min.js ]; then cp ../../dist/shim.min.js .; fi
|
||||
|
||||
.PHONY: duktape
|
||||
duktape: base ## duktape demo
|
||||
.PHONY: duk
|
||||
duk: base
|
||||
bash ./duktape.sh
|
||||
gcc -std=c99 -Wall -osheetjs.duk sheetjs.duk.c duktape.c -lm
|
||||
./sheetjs.duk
|
||||
|
||||
.PHONY: duktape
|
||||
duktape: duk ## duktape demo
|
||||
for ext in xlsx xlsb biff8.xls xml.xls; do ./sheetjs.duk sheetjs.$$ext; done
|
||||
|
||||
.PHONY: nashorn
|
||||
nashorn: base ## nashorn demo
|
||||
|
@ -2,95 +2,95 @@
|
||||
import JavaScriptCore;
|
||||
|
||||
enum SJSError: Error {
|
||||
case badJSContext;
|
||||
case badJSWorkbook;
|
||||
case badJSWorksheet;
|
||||
case badJSContext;
|
||||
case badJSWorkbook;
|
||||
case badJSWorksheet;
|
||||
};
|
||||
|
||||
class SJSWorksheet {
|
||||
var context: JSContext!;
|
||||
var wb: JSValue!; var ws: JSValue!;
|
||||
var idx: Int32;
|
||||
var context: JSContext!;
|
||||
var wb: JSValue!; var ws: JSValue!;
|
||||
var idx: Int32;
|
||||
|
||||
func toCSV() throws -> String {
|
||||
let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX");
|
||||
let utils: JSValue! = XLSX.objectForKeyedSubscript("utils");
|
||||
let sheet_to_csv: JSValue! = utils.objectForKeyedSubscript("sheet_to_csv");
|
||||
return sheet_to_csv.call(withArguments: [ws]).toString();
|
||||
}
|
||||
func toCSV() throws -> String {
|
||||
let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX");
|
||||
let utils: JSValue! = XLSX.objectForKeyedSubscript("utils");
|
||||
let sheet_to_csv: JSValue! = utils.objectForKeyedSubscript("sheet_to_csv");
|
||||
return sheet_to_csv.call(withArguments: [ws]).toString();
|
||||
}
|
||||
|
||||
init(ctx: JSContext, workbook: JSValue, worksheet: JSValue, idx: Int32) throws {
|
||||
self.context = ctx; self.wb = workbook; self.ws = worksheet; self.idx = idx;
|
||||
}
|
||||
init(ctx: JSContext, workbook: JSValue, worksheet: JSValue, idx: Int32) throws {
|
||||
self.context = ctx; self.wb = workbook; self.ws = worksheet; self.idx = idx;
|
||||
}
|
||||
}
|
||||
|
||||
class SJSWorkbook {
|
||||
var context: JSContext!;
|
||||
var wb: JSValue!; var SheetNames: JSValue!; var Sheets: JSValue!;
|
||||
var context: JSContext!;
|
||||
var wb: JSValue!; var SheetNames: JSValue!; var Sheets: JSValue!;
|
||||
|
||||
func getSheetAtIndex(idx: Int32) throws -> SJSWorksheet {
|
||||
let SheetName: String = SheetNames.atIndex(Int(idx)).toString();
|
||||
let ws: JSValue! = Sheets.objectForKeyedSubscript(SheetName);
|
||||
return try SJSWorksheet(ctx: context, workbook: wb, worksheet: ws, idx: idx);
|
||||
}
|
||||
func getSheetAtIndex(idx: Int32) throws -> SJSWorksheet {
|
||||
let SheetName: String = SheetNames.atIndex(Int(idx)).toString();
|
||||
let ws: JSValue! = Sheets.objectForKeyedSubscript(SheetName);
|
||||
return try SJSWorksheet(ctx: context, workbook: wb, worksheet: ws, idx: idx);
|
||||
}
|
||||
|
||||
func writeBStr(bookType: String = "xlsx") throws -> String {
|
||||
let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX");
|
||||
context.evaluateScript(String(format: "var writeopts = {type:'binary', bookType:'%@'}", bookType));
|
||||
let writeopts: JSValue! = context.objectForKeyedSubscript("writeopts");
|
||||
let writefunc: JSValue! = XLSX.objectForKeyedSubscript("write");
|
||||
return writefunc.call(withArguments: [wb, writeopts]).toString();
|
||||
}
|
||||
func writeBStr(bookType: String = "xlsx") throws -> String {
|
||||
let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX");
|
||||
context.evaluateScript(String(format: "var writeopts = {type:'binary', bookType:'%@'}", bookType));
|
||||
let writeopts: JSValue! = context.objectForKeyedSubscript("writeopts");
|
||||
let writefunc: JSValue! = XLSX.objectForKeyedSubscript("write");
|
||||
return writefunc.call(withArguments: [wb, writeopts]).toString();
|
||||
}
|
||||
|
||||
init(ctx: JSContext, wb: JSValue) throws {
|
||||
self.context = ctx;
|
||||
self.wb = wb;
|
||||
self.SheetNames = wb.objectForKeyedSubscript("SheetNames");
|
||||
self.Sheets = wb.objectForKeyedSubscript("Sheets");
|
||||
}
|
||||
init(ctx: JSContext, wb: JSValue) throws {
|
||||
self.context = ctx;
|
||||
self.wb = wb;
|
||||
self.SheetNames = wb.objectForKeyedSubscript("SheetNames");
|
||||
self.Sheets = wb.objectForKeyedSubscript("Sheets");
|
||||
}
|
||||
}
|
||||
|
||||
class SheetJSCore {
|
||||
var context: JSContext!;
|
||||
var XLSX: JSValue!;
|
||||
var context: JSContext!;
|
||||
var XLSX: JSValue!;
|
||||
|
||||
func init_context() throws -> JSContext {
|
||||
var context: JSContext!
|
||||
do {
|
||||
context = JSContext();
|
||||
context.exceptionHandler = { ctx, X in if let e = X { print(e.toString()); }; };
|
||||
context.evaluateScript("var global = (function(){ return this; }).call(null);");
|
||||
context.evaluateScript("if(typeof wbs == 'undefined') wbs = [];");
|
||||
let src = try String(contentsOfFile: "xlsx.full.min.js");
|
||||
context.evaluateScript(src);
|
||||
if context != nil { return context!; }
|
||||
} catch { print(error.localizedDescription); }
|
||||
throw SJSError.badJSContext;
|
||||
}
|
||||
func init_context() throws -> JSContext {
|
||||
var context: JSContext!
|
||||
do {
|
||||
context = JSContext();
|
||||
context.exceptionHandler = { ctx, X in if let e = X { print(e.toString()); }; };
|
||||
context.evaluateScript("var global = (function(){ return this; }).call(null);");
|
||||
context.evaluateScript("if(typeof wbs == 'undefined') wbs = [];");
|
||||
let src = try String(contentsOfFile: "xlsx.full.min.js");
|
||||
context.evaluateScript(src);
|
||||
if context != nil { return context!; }
|
||||
} catch { print(error.localizedDescription); }
|
||||
throw SJSError.badJSContext;
|
||||
}
|
||||
|
||||
func version() throws -> String {
|
||||
if let version = XLSX.objectForKeyedSubscript("version") { return version.toString(); }
|
||||
throw SJSError.badJSContext;
|
||||
}
|
||||
func version() throws -> String {
|
||||
if let version = XLSX.objectForKeyedSubscript("version") { return version.toString(); }
|
||||
throw SJSError.badJSContext;
|
||||
}
|
||||
|
||||
func readFile(file: String) throws -> SJSWorkbook {
|
||||
let data: String! = try String(contentsOfFile: file, encoding: String.Encoding.isoLatin1);
|
||||
return try readBStr(data: data);
|
||||
}
|
||||
func readFile(file: String) throws -> SJSWorkbook {
|
||||
let data: String! = try String(contentsOfFile: file, encoding: String.Encoding.isoLatin1);
|
||||
return try readBStr(data: data);
|
||||
}
|
||||
|
||||
func readBStr(data: String) throws -> SJSWorkbook {
|
||||
context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol)!);
|
||||
context.evaluateScript("var wb = XLSX.read(payload, {type:'binary'});");
|
||||
let wb: JSValue! = context.objectForKeyedSubscript("wb");
|
||||
if wb == nil { throw SJSError.badJSWorkbook; }
|
||||
return try SJSWorkbook(ctx: context, wb: wb);
|
||||
}
|
||||
func readBStr(data: String) throws -> SJSWorkbook {
|
||||
context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol)!);
|
||||
context.evaluateScript("var wb = XLSX.read(payload, {type:'binary'});");
|
||||
let wb: JSValue! = context.objectForKeyedSubscript("wb");
|
||||
if wb == nil { throw SJSError.badJSWorkbook; }
|
||||
return try SJSWorkbook(ctx: context, wb: wb);
|
||||
}
|
||||
|
||||
init() throws {
|
||||
do {
|
||||
self.context = try init_context();
|
||||
self.XLSX = self.context.objectForKeyedSubscript("XLSX");
|
||||
if self.XLSX == nil { throw SJSError.badJSContext; }
|
||||
} catch { print(error.localizedDescription); }
|
||||
}
|
||||
init() throws {
|
||||
do {
|
||||
self.context = try init_context();
|
||||
self.XLSX = self.context.objectForKeyedSubscript("XLSX");
|
||||
if self.XLSX == nil { throw SJSError.badJSContext; }
|
||||
} catch { print(error.localizedDescription); }
|
||||
}
|
||||
}
|
||||
|
@ -5,27 +5,27 @@ import com.sheetjs.SheetJSFile;
|
||||
import com.sheetjs.SheetJSSheet;
|
||||
|
||||
public class SheetJSRhino {
|
||||
public static void main(String args[]) throws Exception {
|
||||
try {
|
||||
SheetJS sjs = new SheetJS();
|
||||
public static void main(String args[]) throws Exception {
|
||||
try {
|
||||
SheetJS sjs = new SheetJS();
|
||||
|
||||
/* open file */
|
||||
SheetJSFile xl = sjs.read_file(args[0]);
|
||||
/* open file */
|
||||
SheetJSFile xl = sjs.read_file(args[0]);
|
||||
|
||||
/* get sheetnames */
|
||||
String[] sheetnames = xl.get_sheet_names();
|
||||
System.err.println(sheetnames[0]);
|
||||
/* get sheetnames */
|
||||
String[] sheetnames = xl.get_sheet_names();
|
||||
System.err.println(sheetnames[0]);
|
||||
|
||||
/* convert to CSV */
|
||||
SheetJSSheet sheet = xl.get_sheet(0);
|
||||
String csv = sheet.get_csv();
|
||||
/* convert to CSV */
|
||||
SheetJSSheet sheet = xl.get_sheet(0);
|
||||
String csv = sheet.get_csv();
|
||||
|
||||
System.out.println(csv);
|
||||
System.out.println(csv);
|
||||
|
||||
} catch(Exception e) {
|
||||
throw e;
|
||||
} finally {
|
||||
SheetJS.close();
|
||||
}
|
||||
}
|
||||
} catch(Exception e) {
|
||||
throw e;
|
||||
} finally {
|
||||
SheetJS.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,39 +13,39 @@ import org.mozilla.javascript.NativeObject;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
|
||||
public class JSHelper {
|
||||
static String read_file(String file) throws IOException {
|
||||
byte[] b = Files.readAllBytes(Paths.get(file));
|
||||
System.out.println(b.length);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(int i = 0; i < b.length; ++i) sb.append(Character.toString((char)(b[i] < 0 ? b[i] + 256 : b[i])));
|
||||
return sb.toString();
|
||||
}
|
||||
static String read_file(String file) throws IOException {
|
||||
byte[] b = Files.readAllBytes(Paths.get(file));
|
||||
System.out.println(b.length);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(int i = 0; i < b.length; ++i) sb.append(Character.toString((char)(b[i] < 0 ? b[i] + 256 : b[i])));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static Object get_object(String path, Object base) throws ObjectNotFoundException {
|
||||
int idx = path.indexOf(".");
|
||||
Scriptable b = (Scriptable)base;
|
||||
if(idx == -1) return b.get(path, b);
|
||||
Object o = b.get(path.substring(0,idx), b);
|
||||
if(o == Scriptable.NOT_FOUND) throw new ObjectNotFoundException("not found: |" + path.substring(0,idx) + "|" + Integer.toString(idx));
|
||||
return get_object(path.substring(idx+1), (NativeObject)o);
|
||||
}
|
||||
static Object get_object(String path, Object base) throws ObjectNotFoundException {
|
||||
int idx = path.indexOf(".");
|
||||
Scriptable b = (Scriptable)base;
|
||||
if(idx == -1) return b.get(path, b);
|
||||
Object o = b.get(path.substring(0,idx), b);
|
||||
if(o == Scriptable.NOT_FOUND) throw new ObjectNotFoundException("not found: |" + path.substring(0,idx) + "|" + Integer.toString(idx));
|
||||
return get_object(path.substring(idx+1), (NativeObject)o);
|
||||
}
|
||||
|
||||
static Object[] get_array(String path, Object base) throws ObjectNotFoundException {
|
||||
NativeArray arr = (NativeArray)get_object(path, base);
|
||||
Object[] out = new Object[(int)arr.getLength()];
|
||||
int idx;
|
||||
for(Object o : arr.getIds()) out[idx = (Integer)o] = arr.get(idx, arr);
|
||||
return out;
|
||||
}
|
||||
static Object[] get_array(String path, Object base) throws ObjectNotFoundException {
|
||||
NativeArray arr = (NativeArray)get_object(path, base);
|
||||
Object[] out = new Object[(int)arr.getLength()];
|
||||
int idx;
|
||||
for(Object o : arr.getIds()) out[idx = (Integer)o] = arr.get(idx, arr);
|
||||
return out;
|
||||
}
|
||||
|
||||
static String[] get_string_array(String path, Object base) throws ObjectNotFoundException {
|
||||
NativeArray arr = (NativeArray)get_object(path, base);
|
||||
String[] out = new String[(int)arr.getLength()];
|
||||
int idx;
|
||||
for(Object o : arr.getIds()) out[idx = (Integer)o] = arr.get(idx, arr).toString();
|
||||
return out;
|
||||
}
|
||||
|
||||
public static void close() { Context.exit(); }
|
||||
static String[] get_string_array(String path, Object base) throws ObjectNotFoundException {
|
||||
NativeArray arr = (NativeArray)get_object(path, base);
|
||||
String[] out = new String[(int)arr.getLength()];
|
||||
int idx;
|
||||
for(Object o : arr.getIds()) out[idx = (Integer)o] = arr.get(idx, arr).toString();
|
||||
return out;
|
||||
}
|
||||
|
||||
public static void close() { Context.exit(); }
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,6 @@ package com.sheetjs;
|
||||
import java.lang.Exception;
|
||||
|
||||
public class ObjectNotFoundException extends Exception {
|
||||
public ObjectNotFoundException() {}
|
||||
public ObjectNotFoundException(String message) { super(message); }
|
||||
public ObjectNotFoundException() {}
|
||||
public ObjectNotFoundException(String message) { super(message); }
|
||||
}
|
||||
|
@ -12,47 +12,47 @@ import org.mozilla.javascript.NativeObject;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
|
||||
public class SheetJS {
|
||||
public Scriptable scope;
|
||||
public Context cx;
|
||||
public NativeObject nXLSX;
|
||||
public Scriptable scope;
|
||||
public Context cx;
|
||||
public NativeObject nXLSX;
|
||||
|
||||
public SheetJS() throws Exception {
|
||||
this.cx = Context.enter();
|
||||
this.scope = this.cx.initStandardObjects();
|
||||
public SheetJS() throws Exception {
|
||||
this.cx = Context.enter();
|
||||
this.scope = this.cx.initStandardObjects();
|
||||
|
||||
/* boilerplate */
|
||||
cx.setOptimizationLevel(-1);
|
||||
String s = "var global = (function(){ return this; }).call(null);";
|
||||
cx.evaluateString(scope, s, "<cmd>", 1, null);
|
||||
/* boilerplate */
|
||||
cx.setOptimizationLevel(-1);
|
||||
String s = "var global = (function(){ return this; }).call(null);";
|
||||
cx.evaluateString(scope, s, "<cmd>", 1, null);
|
||||
|
||||
/* eval library */
|
||||
s = new Scanner(SheetJS.class.getResourceAsStream("/xlsx.full.min.js")).useDelimiter("\\Z").next();
|
||||
//s = new Scanner(new File("xlsx.full.min.js")).useDelimiter("\\Z").next();
|
||||
cx.evaluateString(scope, s, "<cmd>", 1, null);
|
||||
/* eval library */
|
||||
s = new Scanner(SheetJS.class.getResourceAsStream("/xlsx.full.min.js")).useDelimiter("\\Z").next();
|
||||
//s = new Scanner(new File("xlsx.full.min.js")).useDelimiter("\\Z").next();
|
||||
cx.evaluateString(scope, s, "<cmd>", 1, null);
|
||||
|
||||
/* grab XLSX variable */
|
||||
Object XLSX = scope.get("XLSX", scope);
|
||||
if(XLSX == Scriptable.NOT_FOUND) throw new Exception("XLSX not found");
|
||||
this.nXLSX = (NativeObject)XLSX;
|
||||
}
|
||||
/* grab XLSX variable */
|
||||
Object XLSX = scope.get("XLSX", scope);
|
||||
if(XLSX == Scriptable.NOT_FOUND) throw new Exception("XLSX not found");
|
||||
this.nXLSX = (NativeObject)XLSX;
|
||||
}
|
||||
|
||||
public SheetJSFile read_file(String filename) throws IOException, ObjectNotFoundException {
|
||||
/* open file */
|
||||
String d = JSHelper.read_file(filename);
|
||||
public SheetJSFile read_file(String filename) throws IOException, ObjectNotFoundException {
|
||||
/* open file */
|
||||
String d = JSHelper.read_file(filename);
|
||||
|
||||
/* options argument */
|
||||
NativeObject q = (NativeObject)this.cx.evaluateString(this.scope, "q = {'type':'binary', 'WTF':1};", "<cmd>", 2, null);
|
||||
/* options argument */
|
||||
NativeObject q = (NativeObject)this.cx.evaluateString(this.scope, "q = {'type':'binary', 'WTF':1};", "<cmd>", 2, null);
|
||||
|
||||
/* set up function arguments */
|
||||
Object args[] = {d, q};
|
||||
/* set up function arguments */
|
||||
Object args[] = {d, q};
|
||||
|
||||
/* call read -> wb workbook */
|
||||
Function readfunc = (Function)JSHelper.get_object("XLSX.read",this.scope);
|
||||
NativeObject wb = (NativeObject)readfunc.call(this.cx, this.scope, this.nXLSX, args);
|
||||
/* call read -> wb workbook */
|
||||
Function readfunc = (Function)JSHelper.get_object("XLSX.read",this.scope);
|
||||
NativeObject wb = (NativeObject)readfunc.call(this.cx, this.scope, this.nXLSX, args);
|
||||
|
||||
return new SheetJSFile(wb, this);
|
||||
}
|
||||
return new SheetJSFile(wb, this);
|
||||
}
|
||||
|
||||
public static void close() { JSHelper.close(); }
|
||||
public static void close() { JSHelper.close(); }
|
||||
}
|
||||
|
||||
|
@ -6,19 +6,19 @@ import org.mozilla.javascript.NativeObject;
|
||||
import org.mozilla.javascript.Function;
|
||||
|
||||
public class SheetJSFile {
|
||||
public NativeObject wb;
|
||||
public SheetJS sheetjs;
|
||||
public SheetJSFile() {}
|
||||
public SheetJSFile(NativeObject wb, SheetJS sheetjs) { this.wb = wb; this.sheetjs = sheetjs; }
|
||||
public String[] get_sheet_names() {
|
||||
try {
|
||||
return JSHelper.get_string_array("SheetNames", this.wb);
|
||||
} catch(ObjectNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public SheetJSSheet get_sheet(int idx) throws ObjectNotFoundException {
|
||||
return new SheetJSSheet(this, idx);
|
||||
}
|
||||
public NativeObject wb;
|
||||
public SheetJS sheetjs;
|
||||
public SheetJSFile() {}
|
||||
public SheetJSFile(NativeObject wb, SheetJS sheetjs) { this.wb = wb; this.sheetjs = sheetjs; }
|
||||
public String[] get_sheet_names() {
|
||||
try {
|
||||
return JSHelper.get_string_array("SheetNames", this.wb);
|
||||
} catch(ObjectNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public SheetJSSheet get_sheet(int idx) throws ObjectNotFoundException {
|
||||
return new SheetJSSheet(this, idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,24 +6,24 @@ import org.mozilla.javascript.Function;
|
||||
import org.mozilla.javascript.NativeObject;
|
||||
|
||||
public class SheetJSSheet {
|
||||
public NativeObject ws;
|
||||
public SheetJSFile wb;
|
||||
public SheetJSSheet(SheetJSFile wb, int idx) throws ObjectNotFoundException {
|
||||
this.wb = wb;
|
||||
this.ws = (NativeObject)JSHelper.get_object("Sheets." + wb.get_sheet_names()[idx],wb.wb);
|
||||
}
|
||||
public String get_range() throws ObjectNotFoundException {
|
||||
return JSHelper.get_object("!ref",this.ws).toString();
|
||||
}
|
||||
public String get_string_value(String address) throws ObjectNotFoundException {
|
||||
return JSHelper.get_object(address + ".v",this.ws).toString();
|
||||
}
|
||||
public NativeObject ws;
|
||||
public SheetJSFile wb;
|
||||
public SheetJSSheet(SheetJSFile wb, int idx) throws ObjectNotFoundException {
|
||||
this.wb = wb;
|
||||
this.ws = (NativeObject)JSHelper.get_object("Sheets." + wb.get_sheet_names()[idx],wb.wb);
|
||||
}
|
||||
public String get_range() throws ObjectNotFoundException {
|
||||
return JSHelper.get_object("!ref",this.ws).toString();
|
||||
}
|
||||
public String get_string_value(String address) throws ObjectNotFoundException {
|
||||
return JSHelper.get_object(address + ".v",this.ws).toString();
|
||||
}
|
||||
|
||||
public String get_csv() throws ObjectNotFoundException {
|
||||
Function csvify = (Function)JSHelper.get_object("XLSX.utils.sheet_to_csv",this.wb.sheetjs.scope);
|
||||
Object csvArgs[] = {this.ws};
|
||||
Object csv = csvify.call(this.wb.sheetjs.cx, this.wb.sheetjs.scope, this.wb.sheetjs.scope, csvArgs);
|
||||
return csv.toString();
|
||||
}
|
||||
public String get_csv() throws ObjectNotFoundException {
|
||||
Function csvify = (Function)JSHelper.get_object("XLSX.utils.sheet_to_csv",this.wb.sheetjs.scope);
|
||||
Object csvArgs[] = {this.ws};
|
||||
Object csv = csvify.call(this.wb.sheetjs.cx, this.wb.sheetjs.scope, this.wb.sheetjs.scope, csvArgs);
|
||||
return csv.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,17 +5,17 @@ let sheetjs = try SheetJSCore();
|
||||
try print(sheetjs.version());
|
||||
|
||||
let filenames: [[String]] = [
|
||||
["xlsx", "xlsx"],
|
||||
["xlsb", "xlsb"],
|
||||
["biff8.xls", "xls"],
|
||||
["xml.xls", "xlml"]
|
||||
["xlsx", "xlsx"],
|
||||
["xlsb", "xlsb"],
|
||||
["biff8.xls", "xls"],
|
||||
["xml.xls", "xlml"]
|
||||
];
|
||||
|
||||
for fn in filenames {
|
||||
let wb: SJSWorkbook = try sheetjs.readFile(file: "sheetjs." + fn[0]);
|
||||
let ws: SJSWorksheet = try wb.getSheetAtIndex(idx: 0);
|
||||
let csv: String = try ws.toCSV();
|
||||
print(csv);
|
||||
let wbout: String = try wb.writeBStr(bookType: fn[1]);
|
||||
try wbout.write(toFile: "sheetjsswift." + fn[0], atomically: false, encoding: String.Encoding.isoLatin1);
|
||||
let wb: SJSWorkbook = try sheetjs.readFile(file: "sheetjs." + fn[0]);
|
||||
let ws: SJSWorksheet = try wb.getSheetAtIndex(idx: 0);
|
||||
let csv: String = try ws.toCSV();
|
||||
print(csv);
|
||||
let wbout: String = try wb.writeBStr(bookType: fn[1]);
|
||||
try wbout.write(toFile: "sheetjsswift." + fn[0], atomically: false, encoding: String.Encoding.isoLatin1);
|
||||
}
|
||||
|
@ -66,6 +66,8 @@ int main(int argc, char *argv[]) {
|
||||
DOIT("var global = (function(){ return this; }).call(null);");
|
||||
|
||||
/* load library */
|
||||
res = eval_file(ctx, "shim.min.js");
|
||||
if(res != 0) FAIL("shim load")
|
||||
res = eval_file(ctx, "xlsx.full.min.js");
|
||||
if(res != 0) FAIL("library load")
|
||||
|
||||
@ -75,9 +77,9 @@ int main(int argc, char *argv[]) {
|
||||
duk_pop(ctx);
|
||||
|
||||
/* read file */
|
||||
#define INFILE "sheetjs.xlsx"
|
||||
res = load_file(ctx, INFILE, "buf");
|
||||
if(res != 0) FAIL("load " INFILE)
|
||||
res = load_file(ctx, argv[1], "buf");
|
||||
if(res != 0) FAIL("file load")
|
||||
printf("Loaded file %s\n", argv[1]);
|
||||
|
||||
/* parse workbook */
|
||||
DOIT("wb = XLSX.read(buf, {type:'buffer', cellNF:true});");
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"env": { "shared-node-browser":true },
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017
|
||||
"ecmaVersion": 8
|
||||
},
|
||||
"plugins": [ "html", "json" ]
|
||||
}
|
||||
|
73
demos/database/KnexTest.js
Normal file
73
demos/database/KnexTest.js
Normal file
@ -0,0 +1,73 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* eslint-env node */
|
||||
/* global Promise */
|
||||
const XLSX = require('xlsx');
|
||||
const assert = require('assert');
|
||||
const SheetJSKnex = require("./SheetJSKnex");
|
||||
const Knex = require('knex');
|
||||
|
||||
/* Connection to both databases are passed around */
|
||||
let P = Promise.resolve([
|
||||
Knex({ client: 'sqlite3', connection: { filename: './knex1.db' } }),
|
||||
Knex({ client: 'sqlite3', connection: { filename: './knex2.db' } })
|
||||
]);
|
||||
|
||||
/* Sample data table */
|
||||
P = P.then(async (_) => {
|
||||
const [knex] = _;
|
||||
await knex.schema.dropTableIfExists('pres');
|
||||
await knex.schema.createTable('pres', (table) => {
|
||||
table.string('name');
|
||||
table.integer('idx');
|
||||
});
|
||||
await knex.insert([
|
||||
{ name: "Barack Obama", idx: 44 },
|
||||
{ name: "Donald Trump", idx: 45 }
|
||||
]).into('pres');
|
||||
|
||||
await knex.schema.dropTableIfExists('fmts');
|
||||
await knex.schema.createTable('fmts', (table) => {
|
||||
table.string('ext');
|
||||
table.string('ctr');
|
||||
table.integer('multi');
|
||||
});
|
||||
await knex.insert([
|
||||
{ ext: 'XLSB', ctr: 'ZIP', multi: 1 },
|
||||
{ ext: 'XLS', ctr: 'CFB', multi: 1 },
|
||||
{ ext: 'XLML', ctr: '', multi: 1 },
|
||||
{ ext: 'CSV', ctr: 'ZIP', multi: 0 },
|
||||
]).into('fmts');
|
||||
|
||||
return _;
|
||||
});
|
||||
|
||||
/* Export database to XLSX */
|
||||
P = P.then(async (_) => {
|
||||
const [knex] = _;
|
||||
const wb = XLSX.utils.book_new();
|
||||
await SheetJSKnex.book_append_knex(wb, knex, "pres");
|
||||
await SheetJSKnex.book_append_knex(wb, knex, "fmts");
|
||||
XLSX.writeFile(wb, "knex.xlsx");
|
||||
return _;
|
||||
});
|
||||
|
||||
/* Import XLSX to database */
|
||||
P = P.then(async (_) => {
|
||||
const [, knex] = _;
|
||||
const wb = XLSX.readFile("knex.xlsx");
|
||||
await SheetJSKnex.wb_to_knex(wb, knex);
|
||||
return _;
|
||||
});
|
||||
|
||||
/* Compare databases */
|
||||
P = P.then(async (_) => {
|
||||
const [k1, k2] = _;
|
||||
const P1 = await k1.select("*").from('pres');
|
||||
const P2 = await k2.select("*").from('pres');
|
||||
const F1 = await k1.select("*").from('fmts');
|
||||
const F2 = await k2.select("*").from('fmts');
|
||||
assert.deepEqual(P1, P2);
|
||||
assert.deepEqual(F1, F2);
|
||||
});
|
||||
|
||||
P.then(async () => { process.exit(); });
|
@ -27,7 +27,7 @@ var init = [
|
||||
];
|
||||
|
||||
(async () => {
|
||||
const conn1 = await mysql.createConnection({...opts, database: "sheetjs"});
|
||||
const conn1 = await mysql.createConnection(Object.assign({}, opts, {database: "sheetjs"}));
|
||||
for(var i = 0; i < init.length; ++i) await conn1.query(init[i]);
|
||||
|
||||
/* Export table to XLSX */
|
||||
@ -50,7 +50,7 @@ var init = [
|
||||
await conn1.close();
|
||||
|
||||
/* Import XLSX to table */
|
||||
const conn2 = await mysql.createConnection({...opts, database: "sheetj5"});
|
||||
const conn2 = await mysql.createConnection(Object.assign({}, opts, {database: "sheetj5"}));
|
||||
var wb2 = XLSX.readFile("mysql.xlsx");
|
||||
var queries = SheetJSSQL.book_to_sql(wb2, "MYSQL");
|
||||
for(i = 0; i < queries.length; ++i) await conn2.query(queries[i]);
|
||||
|
@ -26,8 +26,8 @@ var init = [
|
||||
"INSERT INTO fmts VALUES ('CSV', '', 0)",
|
||||
];
|
||||
|
||||
var conn1 = new Client({...opts, database: "sheetjs"});
|
||||
var conn2 = new Client({...opts, database: "sheetj5"});
|
||||
var conn1 = new Client(Object.assign({}, opts, {database: "sheetjs"}));
|
||||
var conn2 = new Client(Object.assign({}, opts, {database: "sheetj5"}));
|
||||
(async () => {
|
||||
await conn1.connect();
|
||||
for(var i = 0; i < init.length; ++i) await conn1.query(init[i]);
|
||||
|
@ -49,8 +49,12 @@ scanned to determine the column "types", and there are third-party connectors
|
||||
that can push arrays of JS objects to database tables.
|
||||
|
||||
The [`sexql`](http://sheetjs.com/sexql) browser demo uses WebSQL, which is
|
||||
limited to the SQLite fundamental types. Its schema builder scans the first row
|
||||
to find headers:
|
||||
limited to the SQLite fundamental types.
|
||||
|
||||
<details>
|
||||
<summary><b>Implementation details</b> (click to show)</summary>
|
||||
|
||||
The `sexql` schema builder scans the first row to find headers:
|
||||
|
||||
```js
|
||||
if(!ws || !ws['!ref']) return;
|
||||
@ -99,8 +103,11 @@ value of a column, the column is marked as `TEXT`:
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
The included `SheetJSSQL.js` script demonstrates SQL statement generation.
|
||||
|
||||
|
||||
## Objects, K/V and "Schema-less" Databases
|
||||
|
||||
So-called "Schema-less" databases allow for arbitrary keys and values within the
|
||||
@ -137,6 +144,9 @@ XXX| A | B |
|
||||
|
||||
The included `ObjUtils.js` script demonstrates object-workbook conversion:
|
||||
|
||||
<details>
|
||||
<summary><b>Implementation details</b> (click to show)</summary>
|
||||
|
||||
```js
|
||||
function deepset(obj, path, value) {
|
||||
if(path.indexOf(".") == -1) return obj[path] = value;
|
||||
@ -185,6 +195,8 @@ function object_to_workbook(obj) {
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
## Browser APIs
|
||||
|
||||
@ -229,7 +241,7 @@ differences surround API shape and supported data types.
|
||||
|
||||
[The `better-sqlite3` module](https://www.npmjs.com/package/better-sqlite3)
|
||||
provides a very simple API for working with SQLite databases. `Statement#all`
|
||||
runs a prepared statement and returns an array of JS objects
|
||||
runs a prepared statement and returns an array of JS objects.
|
||||
|
||||
`SQLiteTest.js` generates a simple two-table SQLite database (`SheetJS1.db`),
|
||||
exports to XLSX (`sqlite.xlsx`), imports the new XLSX file to a new database
|
||||
@ -255,6 +267,15 @@ The `rows` key of the object is an array of JS objects.
|
||||
tables in the `sheetjs` database, exports to XLSX, imports the new XLSX file to
|
||||
the `sheetj5` database and verifies the tables are preserved.
|
||||
|
||||
#### Knex Query Builder
|
||||
|
||||
[The `knex` module](https://www.npmjs.com/package/knex) builds SQL queries. The
|
||||
same exact code can be used against Oracle Database, MSSQL, and other engines.
|
||||
|
||||
`KnexTest.js` uses the `sqlite3` connector and follows the same procedure as the
|
||||
SQLite test. The included `SheetJSKnex.js` script converts between the query
|
||||
builder and the common spreadsheet format.
|
||||
|
||||
### Key/Value Stores
|
||||
|
||||
#### Redis
|
||||
@ -267,7 +288,7 @@ strings in a special worksheet (`_strs`), the manifest in another worksheet
|
||||
`RedisTest.js` connects to a local Redis server, populates data based on the
|
||||
official Redis tutorial, exports to XLSX, flushes the server, imports the new
|
||||
XLSX file and verifies the data round-tripped correctly. `SheetJSRedis.js`
|
||||
includes the implementation details
|
||||
includes the implementation details.
|
||||
|
||||
#### LowDB
|
||||
|
||||
|
@ -21,7 +21,7 @@ var init = [
|
||||
];
|
||||
db1.exec(init.join(";"));
|
||||
|
||||
/* Export table to XLSX */
|
||||
/* Export database to XLSX */
|
||||
var wb = XLSX.utils.book_new();
|
||||
function book_append_table(wb, db, name) {
|
||||
var r = db.prepare('SELECT * FROM ' + name).all();
|
||||
@ -32,7 +32,7 @@ book_append_table(wb, db1, "pres");
|
||||
book_append_table(wb, db1, "fmts");
|
||||
XLSX.writeFile(wb, "sqlite.xlsx");
|
||||
|
||||
/* Import XLSX to table */
|
||||
/* Import XLSX to database */
|
||||
var db2 = new Database('SheetJS2.db');
|
||||
var wb2 = XLSX.readFile("sqlite.xlsx");
|
||||
var queries = SheetJSSQL.book_to_sql(wb2, "SQLITE");
|
||||
@ -46,7 +46,6 @@ var F2 = db2.prepare("SELECT * FROM fmts").all();
|
||||
assert.deepEqual(P1, P2);
|
||||
assert.deepEqual(F1, F2);
|
||||
|
||||
/* Display results */
|
||||
console.log(P2);
|
||||
console.log(F2);
|
||||
|
||||
|
78
demos/database/SheetJSKnex.js
Normal file
78
demos/database/SheetJSKnex.js
Normal file
@ -0,0 +1,78 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* eslint-env node */
|
||||
var XLSX = require("xlsx");
|
||||
|
||||
async function book_append_knex(wb, knex, tbl) {
|
||||
const aoo = await knex.select("*").from(tbl);
|
||||
XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet(aoo), tbl);
|
||||
}
|
||||
|
||||
const TYPES = {
|
||||
b: "boolean",
|
||||
n: "float",
|
||||
t: "string",
|
||||
d: "dateTime"
|
||||
};
|
||||
async function ws_to_knex(ws, knex, n) {
|
||||
if(!ws || !ws['!ref']) return;
|
||||
var range = XLSX.utils.decode_range(ws['!ref']);
|
||||
if(!range || !range.s || !range.e || range.s > range.e) return;
|
||||
var R = range.s.r, C = range.s.c;
|
||||
|
||||
var names = new Array(range.e.c-range.s.c+1);
|
||||
for(C = range.s.c; C<= range.e.c; ++C){
|
||||
var addr = XLSX.utils.encode_cell({c:C,r:R});
|
||||
names[C-range.s.c] = ws[addr] ? ws[addr].v : XLSX.utils.encode_col(C);
|
||||
}
|
||||
|
||||
for(var i = 0; i < names.length; ++i) if(names.indexOf(names[i]) < i)
|
||||
for(var j = 0; j < names.length; ++j) {
|
||||
var _name = names[i] + "_" + (j+1);
|
||||
if(names.indexOf(_name) > -1) continue;
|
||||
names[i] = _name;
|
||||
}
|
||||
|
||||
var types = new Array(range.e.c-range.s.c+1);
|
||||
for(C = range.s.c; C<= range.e.c; ++C) {
|
||||
var seen = {}, _type = "";
|
||||
for(R = range.s.r+1; R<= range.e.r; ++R)
|
||||
seen[(ws[XLSX.utils.encode_cell({c:C,r:R})]||{t:"z"}).t] = true;
|
||||
if(seen.s || seen.str) _type = TYPES.t;
|
||||
else if(seen.n + seen.b + seen.d + seen.e > 1) _type = TYPES.t;
|
||||
else switch(true) {
|
||||
case seen.b: _type = TYPES.b; break;
|
||||
case seen.n: _type = TYPES.n; break;
|
||||
case seen.e: _type = TYPES.t; break;
|
||||
case seen.d: _type = TYPES.d; break;
|
||||
}
|
||||
types[C-range.s.c] = _type || TYPES.t;
|
||||
}
|
||||
|
||||
await knex.schema.dropTableIfExists(n);
|
||||
await knex.schema.createTable(n, (table) => { names.forEach((n, i) => { table[types[i] || "text"](n); }); });
|
||||
|
||||
for(R = range.s.r+1; R<= range.e.r; ++R) {
|
||||
var row = {};
|
||||
for(C = range.s.c; C<= range.e.c; ++C) {
|
||||
var cell = ws[XLSX.utils.encode_cell({c:C,r:R})];
|
||||
if(!cell) continue;
|
||||
var key = names[C-range.s.c], val = cell.v;
|
||||
if(types[C-range.s.c] == TYPES.n) if(cell.t == 'b' || typeof val == 'boolean' ) val = +val;
|
||||
row[key] = val;
|
||||
}
|
||||
await knex.insert(row).into(n);;
|
||||
}
|
||||
}
|
||||
|
||||
async function wb_to_knex(wb, knex) {
|
||||
for(var i = 0; i < wb.SheetNames.length; ++i) {
|
||||
var n = wb.SheetNames[i];
|
||||
var ws = wb.Sheets[n];
|
||||
await ws_to_knex(ws, knex, n);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
book_append_knex,
|
||||
wb_to_knex
|
||||
};
|
@ -67,6 +67,7 @@ async function wb_to_redis(wb, R) {
|
||||
await aoa_to_redis[M[i].type](aoa, R, M[i].key);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
redis_to_wb,
|
||||
wb_to_redis
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* global XLSX, require, module */
|
||||
var SheetJSSQL = (function() {
|
||||
|
||||
var X;
|
||||
@ -51,7 +52,7 @@ function sheet_to_sql(ws, sname, mode) {
|
||||
|
||||
var BT = mode == "PGSQL" ? "" : "`";
|
||||
var Q = mode == "PGSQL" ? "'" : '"';
|
||||
var R = mode == "PGSQL" ? /'/g : /"/g;
|
||||
var J = mode == "PGSQL" ? /'/g : /"/g;
|
||||
out.push("DROP TABLE IF EXISTS " + BT + sname + BT );
|
||||
out.push("CREATE TABLE " + BT + sname + BT + " (" + names.map(function(n, i) { return BT + n + BT + " " + (types[i]||"TEXT"); }).join(", ") + ");" );
|
||||
|
||||
@ -64,7 +65,7 @@ function sheet_to_sql(ws, sname, mode) {
|
||||
var val = cell.v;
|
||||
switch(types[C-range.s.c]) {
|
||||
case TYPES.n: if(cell.t == 'b' || typeof val == 'boolean' ) val = +val; break;
|
||||
default: val = Q + val.toString().replace(R, Q + Q) + Q;
|
||||
default: val = Q + val.toString().replace(J, Q + Q) + Q;
|
||||
}
|
||||
values.push(val);
|
||||
}
|
||||
|
@ -1,14 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- xlsx.js (C) 2013-present SheetJS http://sheetjs.com -->
|
||||
<!-- vim: set ts=2: -->
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>SheetJS FuseBox Test</title>
|
||||
<style>
|
||||
a { text-decoration: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript" src="/client.js"></script>
|
||||
<pre>
|
||||
<b><a href="http://sheetjs.com">SheetJS FuseBox Demo</a></b>
|
||||
|
||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
|
||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a>
|
||||
|
||||
Original script: <a href="sheetjs.ts">sheetjs.ts</a>
|
||||
|
||||
<b>Console Output:</b>
|
||||
</pre>
|
||||
<pre id="console"></pre>
|
||||
<b>
|
||||
<script>
|
||||
if(typeof console !== "undefined") console = {};
|
||||
console.__log = console.log || function(){};
|
||||
console.log = function(x) {
|
||||
console.__log.apply(console, arguments);
|
||||
document.getElementById('console').innerText += x + "\n";
|
||||
};
|
||||
console.error = console.debug = console.info = console.log
|
||||
</script>
|
||||
<script type="text/javascript" src="/client.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -114,6 +114,8 @@ Downloadify.create(element_id, {
|
||||
});
|
||||
```
|
||||
|
||||
#### Upload
|
||||
|
||||
The demo also includes an HTML file input element for updating the data table:
|
||||
|
||||
```js
|
||||
|
@ -15,7 +15,7 @@ native: ## Build react-native project
|
||||
|
||||
.PHONY: ios
|
||||
ios: native ## react-native ios sim
|
||||
cd SheetJS; react-native run-ios; cd -
|
||||
cd SheetJS; react-native run-ios --simulator="iPhone X"; cd -
|
||||
|
||||
.PHONY: android
|
||||
android: native ## react-native android sim
|
||||
|
@ -77,8 +77,7 @@ Reproducing the full project is straightforward:
|
||||
react-native init SheetJS
|
||||
cd SheetJS
|
||||
npm i -S xlsx react react-native react-native-table-component react-native-fs
|
||||
cp ../react-native.js index.ios.js
|
||||
cp ../react-native.js index.android.js
|
||||
cp ../react-native.js index.js
|
||||
react-native link
|
||||
```
|
||||
|
||||
@ -107,6 +106,9 @@ const wbout = XLSX.write(wb, {type:'binary', bookType:"xlsx"});
|
||||
writeFile(file, wbout, 'ascii').then((r)=>{/* :) */}).catch((e)=>{/* :( */});
|
||||
```
|
||||
|
||||
Note: for real app deployments, the `UIFileSharingEnabled` flag must be manually
|
||||
set in the iOS project `Info.plist` file.
|
||||
|
||||
## Other Demos
|
||||
|
||||
#### Preact
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
# xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
if [ ! -e SheetJS ]; then
|
||||
react-native init SheetJS
|
||||
react-native init --version="0.53.3" SheetJS
|
||||
cd SheetJS
|
||||
npm i -S xlsx react-native-table-component react-native-fs
|
||||
cd -
|
||||
|
32
demos/react/react-native.js
vendored
32
demos/react/react-native.js
vendored
@ -2,8 +2,8 @@
|
||||
import XLSX from 'xlsx';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { AppRegistry, StyleSheet, Text, View, Button, Alert, Image } from 'react-native';
|
||||
import { Table, Row, Rows } from 'react-native-table-component';
|
||||
import { AppRegistry, StyleSheet, Text, View, Button, Alert, Image, ScrollView, TouchableWithoutFeedback } from 'react-native';
|
||||
import { Table, Row, Rows, TableWrapper } from 'react-native-table-component';
|
||||
|
||||
// react-native-fs
|
||||
import { writeFile, readFile, DocumentDirectoryPath } from 'react-native-fs';
|
||||
@ -21,12 +21,14 @@ const output = str => str.split("").map(x => x.charCodeAt(0));
|
||||
*/
|
||||
|
||||
const make_cols = refstr => Array.from({length: XLSX.utils.decode_range(refstr).e.c + 1}, (x,i) => XLSX.utils.encode_col(i));
|
||||
const make_width = refstr => Array.from({length: XLSX.utils.decode_range(refstr).e.c + 1}, () => 60);
|
||||
|
||||
export default class SheetJS extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: [[1,2,3],[4,5,6]],
|
||||
widthArr: [60, 60, 60],
|
||||
cols: make_cols("A1:C2")
|
||||
};
|
||||
this.importFile = this.importFile.bind(this);
|
||||
@ -46,7 +48,7 @@ export default class SheetJS extends Component {
|
||||
const data = XLSX.utils.sheet_to_json(ws, {header:1});
|
||||
|
||||
/* update state */
|
||||
this.setState({ data: data, cols: make_cols(ws['!ref']) });
|
||||
this.setState({ data: data, cols: make_cols(ws['!ref']), widthArr: make_width(ws['!ref']) });
|
||||
}).catch((err) => { Alert.alert("importFile Error", "Error " + err.message); });
|
||||
}}
|
||||
]);
|
||||
@ -67,7 +69,8 @@ export default class SheetJS extends Component {
|
||||
}).catch((err) => { Alert.alert("exportFile Error", "Error " + err.message); });
|
||||
};
|
||||
render() { return (
|
||||
<View style={styles.container}>
|
||||
<ScrollView contentContainerStyle={styles.container} vertical={true}>
|
||||
<Text style={styles.welcome}> </Text>
|
||||
<Image style={{width: 128, height: 128}} source={require('./logo.png')} />
|
||||
<Text style={styles.welcome}>SheetJS React Native Demo</Text>
|
||||
<Text style={styles.instructions}>Import Data</Text>
|
||||
@ -76,11 +79,22 @@ export default class SheetJS extends Component {
|
||||
<Button disabled={!this.state.data.length} onPress={this.exportFile} title="Export data to XLSX" color="#841584" />
|
||||
|
||||
<Text style={styles.instructions}>Current Data</Text>
|
||||
<Table style={styles.table}>
|
||||
<Row data={this.state.cols} style={styles.thead} textStyle={styles.text}/>
|
||||
<Rows data={this.state.data} style={styles.tr} textStyle={styles.text}/>
|
||||
</Table>
|
||||
</View>
|
||||
|
||||
<ScrollView style={styles.table} horizontal={true} >
|
||||
<Table style={styles.table}>
|
||||
<TableWrapper>
|
||||
<Row data={this.state.cols} style={styles.thead} textStyle={styles.text} widthArr={this.state.widthArr}/>
|
||||
</TableWrapper>
|
||||
<TouchableWithoutFeedback>
|
||||
<ScrollView vertical={true}>
|
||||
<TableWrapper>
|
||||
<Rows data={this.state.data} style={styles.tr} textStyle={styles.text} widthArr={this.state.widthArr}/>
|
||||
</TableWrapper>
|
||||
</ScrollView>
|
||||
</TouchableWithoutFeedback>
|
||||
</Table>
|
||||
</ScrollView>
|
||||
</ScrollView>
|
||||
); };
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
.PHONY: test
|
||||
.PHONY: test ctest
|
||||
test:
|
||||
cp ../../dist/xlsx.full.min.js .
|
||||
node test.node.js
|
||||
|
||||
ctest:
|
||||
python -mSimpleHTTPServer
|
||||
|
@ -56,7 +56,7 @@ onmessage = function(evt) {
|
||||
/* xlsxworker.js */
|
||||
var XLSX = require('xlsx');
|
||||
|
||||
_cb = function (evt) { /* ... do work here ... */ };
|
||||
_cb = function(evt) { /* ... do work here ... */ };
|
||||
```
|
||||
|
||||
## Node
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
var XLSX = require('xlsx');
|
||||
console.log(XLSX);
|
||||
console.log(XLSX.version);
|
||||
var w = XLSX.read('abc,def\nghi,jkl', {type:'binary'});
|
||||
var j = XLSX.utils.sheet_to_json(w.Sheets[w.SheetNames[0]], {header:1});
|
||||
console.log(j);
|
||||
|
@ -1,4 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- xlsx.js (C) 2013-present SheetJS http://sheetjs.com -->
|
||||
<!-- vim: set ts=2: -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>SheetJS SystemJS Test</title>
|
||||
<style>
|
||||
a { text-decoration: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre>
|
||||
<b><a href="http://sheetjs.com">SheetJS SystemJS Demo</a></b>
|
||||
|
||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
|
||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a>
|
||||
|
||||
Original script: <a href="main.simple.js">main.simple.js</a>
|
||||
|
||||
<b>Console Output:</b>
|
||||
</pre>
|
||||
<pre id="console"></pre>
|
||||
<b>
|
||||
<script>
|
||||
if(typeof console !== "undefined") console = {};
|
||||
console.__log = console.log || function(){};
|
||||
console.log = function(x) {
|
||||
console.__log.apply(console, arguments);
|
||||
document.getElementById('console').innerText += x + "\n";
|
||||
};
|
||||
console.error = console.debug = console.info = console.log
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.20.16/system.js"></script>
|
||||
<script>
|
||||
SystemJS.config({
|
||||
@ -16,3 +48,5 @@ SystemJS.config({
|
||||
});
|
||||
SystemJS.import('main.simple.js');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,6 +1,10 @@
|
||||
.PHONY: all
|
||||
all:
|
||||
npm run build
|
||||
@npm run build
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
@npm run lint
|
||||
|
||||
.PHONY: init
|
||||
init:
|
||||
|
@ -1,2 +1,5 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/* eslint-env node */
|
||||
var readFirstSheet = require("./").readFirstSheet;
|
||||
console.log(readFirstSheet("../../sheetjs.xlsb", {type:"file", cellDates:true}));
|
@ -5,8 +5,8 @@ import * as XLSX from 'xlsx';
|
||||
|
||||
const { read, utils: { sheet_to_json } } = XLSX;
|
||||
|
||||
export function readFirstSheet(data:any, options:XLSX.ParsingOptions): any[][] {
|
||||
const wb: XLSX.WorkBook = read(data, options);
|
||||
const ws: XLSX.WorkSheet = wb.Sheets[wb.SheetNames[0]];
|
||||
return sheet_to_json(ws, {header:1, raw:true});
|
||||
};
|
||||
export function readFirstSheet(data: any, options: XLSX.ParsingOptions): any[][] {
|
||||
const wb: XLSX.WorkBook = read(data, options);
|
||||
const ws: XLSX.WorkSheet = wb.Sheets[wb.SheetNames[0]];
|
||||
return sheet_to_json(ws, { header: 1, raw: true });
|
||||
}
|
||||
|
@ -3,10 +3,10 @@
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "tsc && browserify -o dist/browser.js src/index.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"lint": "tslint lib/*.ts"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
|
@ -1,2 +1,6 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/* eslint-env browser */
|
||||
/* global require */
|
||||
var readFirstSheet = require("../").readFirstSheet;
|
||||
console.log(readFirstSheet("a,b,c\n1,2,3\n4,5,6", {type:"binary"}));
|
11
demos/typescript/tslint.json
Normal file
11
demos/typescript/tslint.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "tslint-config-airbnb",
|
||||
"rules": {
|
||||
"whitespace": false,
|
||||
"no-sparse-arrays": false,
|
||||
"only-arrow-functions": false,
|
||||
"no-consecutive-blank-lines": false,
|
||||
"prefer-conditional-expression": false,
|
||||
"one-variable-per-declaration": false
|
||||
}
|
||||
}
|
1
demos/xhr/.gitignore
vendored
Normal file
1
demos/xhr/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
files/
|
@ -16,14 +16,13 @@ The included demos focus on an editable table. There are two separate flows:
|
||||
|
||||
- When the upload button is clicked, the browser will generate a new worksheet
|
||||
using `table_to_book` and build up a new workbook. It will then attempt to
|
||||
generate a Base64-encoded XLSX string and upload it to the server.
|
||||
generate a file and upload it to the server.
|
||||
|
||||
### Demo Server
|
||||
|
||||
The `server.js` nodejs server serves static files on `GET` request. On a `POST`
|
||||
request to `/upload`, the server processes the body and looks for the `file` and
|
||||
`data` fields. It will write the Base64-decoded data from `data` to the file
|
||||
name specified in `file`.
|
||||
request to `/upload`, the server processes the body and looks for uploaded file.
|
||||
It will write the data for the first file to the indicated file name.
|
||||
|
||||
To start the demo, run `npm start` and navigate to <http://localhost:7262/>
|
||||
|
||||
@ -48,16 +47,16 @@ req.onload = function(e) {
|
||||
req.send();
|
||||
```
|
||||
|
||||
For uploading data, this demo populates a `FormData` object with string data
|
||||
generated with the `base64` output type:
|
||||
For uploading data, this demo populates a `FormData` object with an ArrayBuffer
|
||||
generated with the `array` output type:
|
||||
|
||||
```js
|
||||
/* generate XLSX as base64 string */
|
||||
var b64 = XLSX.write(workbook, {bookType:'xlsx', type:'base64'});
|
||||
/* generate XLSX as array buffer */
|
||||
var data = XLSX.write(workbook, {bookType: 'xlsx', type: 'array'});
|
||||
|
||||
/* build FormData with the generated file */
|
||||
var fd = new FormData();
|
||||
fd.append('data', b64);
|
||||
fd.append('data', new File([data], 'sheetjs.xlsx'));
|
||||
|
||||
/* send data */
|
||||
var req = new XMLHttpRequest();
|
||||
|
@ -47,8 +47,9 @@ document.getElementById('ulbutton').onclick = function() {
|
||||
var wb = XLSX.utils.table_to_book(document.getElementById('htmlout'));
|
||||
console.log(wb);
|
||||
var fd = new FormData();
|
||||
fd.append('file', demo + '.' + book);
|
||||
fd.append('data', XLSX.write(wb, {bookType:book, type:'base64'}));
|
||||
var data = XLSX.write(wb, {bookType:book, type:'array'});
|
||||
console.log(data);
|
||||
fd.append('data', new File([data], demo + '.' + book));
|
||||
axios("/upload", {method: "POST", data: fd});
|
||||
};
|
||||
</script>
|
||||
|
@ -56,8 +56,9 @@ document.getElementById('ulbutton').onclick = function() {
|
||||
var wb = XLSX.utils.table_to_book(document.getElementById('htmlout'));
|
||||
console.log(wb);
|
||||
var fd = new FormData();
|
||||
fd.append('file', demo + '.' + book);
|
||||
fd.append('data', XLSX.write(wb, {bookType:book, type:'base64'}));
|
||||
var data = XLSX.write(wb, {bookType:book, type:'array'});
|
||||
console.log(data);
|
||||
fd.append('data', new File([data], demo + '.' + book));
|
||||
fetch("/upload", {method: "POST", body: fd}).then(function(r) { return r.text(); }).then(function(t) { console.log(t); });
|
||||
};
|
||||
</script>
|
||||
|
@ -10,13 +10,19 @@ var cors = require('../server/_cors');
|
||||
var port = +process.argv[2] || +process.env.PORT || 7262;
|
||||
var basepath = process.cwd();
|
||||
|
||||
var dir = path.join(__dirname, "files");
|
||||
try { fs.mkdirSync(dir); } catch(e) {}
|
||||
|
||||
app.use(logit.mw);
|
||||
app.use(cors.mw);
|
||||
app.use(require('express-formidable')());
|
||||
app.use(require('express-formidable')({uploadDir: dir}));
|
||||
app.post('/upload', function(req, res) {
|
||||
fs.writeFile(req.fields.file, req.fields.data, 'base64', function(err, r) {
|
||||
res.end("wrote to " + req.fields.file);
|
||||
});
|
||||
console.log(req.files);
|
||||
var f = req.files[Object.keys(req.files)[0]];
|
||||
var newpath = path.join(dir, f.name);
|
||||
fs.renameSync(f.path, newpath);
|
||||
console.log("moved " + f.path + " to " + newpath);
|
||||
res.end("wrote to " + f.name);
|
||||
});
|
||||
app.use(express.static(path.resolve(basepath)));
|
||||
app.use(require('serve-index')(basepath, {'icons':true}));
|
||||
|
@ -49,8 +49,9 @@ document.getElementById('ulbutton').onclick = function() {
|
||||
var wb = XLSX.utils.table_to_book(document.getElementById('htmlout'));
|
||||
console.log(wb);
|
||||
var fd = new FormData();
|
||||
fd.append('file', demo + '.' + book);
|
||||
fd.append('data', XLSX.write(wb, {bookType:book, type:'base64'}));
|
||||
var data = XLSX.write(wb, {bookType:book, type:'array'});
|
||||
console.log(data);
|
||||
fd.append('data', new File([data], demo + '.' + book));
|
||||
superagent.post("/upload").send(fd).end(function(e,r) { console.log(r.text); });
|
||||
};
|
||||
</script>
|
||||
|
@ -55,8 +55,9 @@ document.getElementById('ulbutton').onclick = function() {
|
||||
var wb = XLSX.utils.table_to_book(document.getElementById('htmlout'));
|
||||
console.log(wb);
|
||||
var fd = new FormData();
|
||||
fd.append('file', demo + '.' + book);
|
||||
fd.append('data', XLSX.write(wb, {bookType:book, type:'base64'}));
|
||||
var data = XLSX.write(wb, {bookType:book, type:'array'});
|
||||
console.log(data);
|
||||
fd.append('data', new File([data], demo + '.' + book));
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("POST", "/upload", true);
|
||||
req.send(fd);
|
||||
|
28
dist/xlsx.core.min.js
generated
vendored
28
dist/xlsx.core.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.core.min.map
generated
vendored
2
dist/xlsx.core.min.map
generated
vendored
File diff suppressed because one or more lines are too long
21
dist/xlsx.extendscript.js
generated
vendored
21
dist/xlsx.extendscript.js
generated
vendored
@ -9141,7 +9141,7 @@ module.exports = ZStream;
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.12.4';
|
||||
XLSX.version = '0.12.5';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -18109,7 +18109,8 @@ function write_comments_vml(rId, comments) {
|
||||
];
|
||||
while(_shapeid < rId * 1000) _shapeid += 1000;
|
||||
|
||||
comments.map(function(x) { return decode_cell(x[0]); }).forEach(function(c) { o = o.concat([
|
||||
comments.forEach(function(x) { var c = decode_cell(x[0]);
|
||||
o = o.concat([
|
||||
'<v:shape' + wxt_helper({
|
||||
id:'_x0000_s' + (++_shapeid),
|
||||
type:"#_x0000_t202",
|
||||
@ -18225,13 +18226,11 @@ function write_comments_xml(data) {
|
||||
|
||||
var iauthor = [];
|
||||
o.push("<authors>");
|
||||
data.map(function(x) { return x[1]; }).forEach(function(comment) {
|
||||
comment.map(function(x) { return escapexml(x.a); }).forEach(function(a) {
|
||||
if(iauthor.indexOf(a) > -1) return;
|
||||
iauthor.push(a);
|
||||
o.push("<author>" + a + "</author>");
|
||||
});
|
||||
});
|
||||
data.forEach(function(x) { x[1].forEach(function(w) { var a = escapexml(w.a);
|
||||
if(iauthor.indexOf(a) > -1) return;
|
||||
iauthor.push(a);
|
||||
o.push("<author>" + a + "</author>");
|
||||
}); });
|
||||
o.push("</authors>");
|
||||
o.push("<commentList>");
|
||||
data.forEach(function(d) {
|
||||
@ -23440,6 +23439,8 @@ function xlml_clean_comment(comment) {
|
||||
function xlml_normalize(d) {
|
||||
if(has_buf && Buffer.isBuffer(d)) return d.toString('utf8');
|
||||
if(typeof d === 'string') return d;
|
||||
/* duktape */
|
||||
if(typeof Uint8Array !== 'undefined' && d instanceof Uint8Array) return utf8read(a2s(ab2a(d)));
|
||||
throw new Error("Bad input format: expected Buffer or string");
|
||||
}
|
||||
|
||||
@ -28883,7 +28884,9 @@ if(has_buf && typeof require != 'undefined') (function() {
|
||||
var rowinfo = o.skipHidden && sheet["!rows"] || [];
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colinfo[C]||{}).hidden)) cols[C] = encode_col(C);
|
||||
var R = r.s.r;
|
||||
var BOM = false;
|
||||
stream._read = function() {
|
||||
if(!BOM) { BOM = true; return stream.push("\uFEFF"); }
|
||||
if(R > r.e.r) return stream.push(null);
|
||||
while(R <= r.e.r) {
|
||||
++R;
|
||||
|
16
dist/xlsx.full.min.js
generated
vendored
16
dist/xlsx.full.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.full.min.map
generated
vendored
2
dist/xlsx.full.min.map
generated
vendored
File diff suppressed because one or more lines are too long
21
dist/xlsx.js
generated
vendored
21
dist/xlsx.js
generated
vendored
@ -4,7 +4,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.12.4';
|
||||
XLSX.version = '0.12.5';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -8972,7 +8972,8 @@ function write_comments_vml(rId, comments) {
|
||||
];
|
||||
while(_shapeid < rId * 1000) _shapeid += 1000;
|
||||
|
||||
comments.map(function(x) { return decode_cell(x[0]); }).forEach(function(c) { o = o.concat([
|
||||
comments.forEach(function(x) { var c = decode_cell(x[0]);
|
||||
o = o.concat([
|
||||
'<v:shape' + wxt_helper({
|
||||
id:'_x0000_s' + (++_shapeid),
|
||||
type:"#_x0000_t202",
|
||||
@ -9088,13 +9089,11 @@ function write_comments_xml(data) {
|
||||
|
||||
var iauthor = [];
|
||||
o.push("<authors>");
|
||||
data.map(function(x) { return x[1]; }).forEach(function(comment) {
|
||||
comment.map(function(x) { return escapexml(x.a); }).forEach(function(a) {
|
||||
if(iauthor.indexOf(a) > -1) return;
|
||||
iauthor.push(a);
|
||||
o.push("<author>" + a + "</author>");
|
||||
});
|
||||
});
|
||||
data.forEach(function(x) { x[1].forEach(function(w) { var a = escapexml(w.a);
|
||||
if(iauthor.indexOf(a) > -1) return;
|
||||
iauthor.push(a);
|
||||
o.push("<author>" + a + "</author>");
|
||||
}); });
|
||||
o.push("</authors>");
|
||||
o.push("<commentList>");
|
||||
data.forEach(function(d) {
|
||||
@ -14303,6 +14302,8 @@ function xlml_clean_comment(comment) {
|
||||
function xlml_normalize(d) {
|
||||
if(has_buf && Buffer.isBuffer(d)) return d.toString('utf8');
|
||||
if(typeof d === 'string') return d;
|
||||
/* duktape */
|
||||
if(typeof Uint8Array !== 'undefined' && d instanceof Uint8Array) return utf8read(a2s(ab2a(d)));
|
||||
throw new Error("Bad input format: expected Buffer or string");
|
||||
}
|
||||
|
||||
@ -19746,7 +19747,9 @@ if(has_buf && typeof require != 'undefined') (function() {
|
||||
var rowinfo = o.skipHidden && sheet["!rows"] || [];
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colinfo[C]||{}).hidden)) cols[C] = encode_col(C);
|
||||
var R = r.s.r;
|
||||
var BOM = false;
|
||||
stream._read = function() {
|
||||
if(!BOM) { BOM = true; return stream.push("\uFEFF"); }
|
||||
if(R > r.e.r) return stream.push(null);
|
||||
while(R <= r.e.r) {
|
||||
++R;
|
||||
|
16
dist/xlsx.min.js
generated
vendored
16
dist/xlsx.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.min.map
generated
vendored
2
dist/xlsx.min.map
generated
vendored
File diff suppressed because one or more lines are too long
@ -14,6 +14,7 @@ In the browser, just add a script tag:
|
||||
| `unpkg` | <https://unpkg.com/xlsx/> |
|
||||
| `jsDelivr` | <https://jsdelivr.com/package/npm/xlsx> |
|
||||
| `CDNjs` | <http://cdnjs.com/libraries/xlsx> |
|
||||
| `packd` | <https://bundle.run/xlsx?name=XLSX> |
|
||||
|
||||
`unpkg` makes the latest version available at:
|
||||
|
||||
|
@ -154,6 +154,7 @@ In the browser, just add a script tag:
|
||||
| `unpkg` | <https://unpkg.com/xlsx/> |
|
||||
| `jsDelivr` | <https://jsdelivr.com/package/npm/xlsx> |
|
||||
| `CDNjs` | <http://cdnjs.com/libraries/xlsx> |
|
||||
| `packd` | <https://bundle.run/xlsx?name=XLSX> |
|
||||
|
||||
`unpkg` makes the latest version available at:
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.12.4",
|
||||
"version": "0.12.5",
|
||||
"author": "sheetjs",
|
||||
"description": "SheetJS Spreadsheet data parser and writer",
|
||||
"keywords": [
|
||||
|
@ -205,7 +205,7 @@ filenames.forEach(function(r) {
|
||||
var ext = r[1] && r[1].bookType || r[0].split(".")[1];
|
||||
ext = {"htm":"html"}[ext] || ext;
|
||||
OUT.forEach(function(type) {
|
||||
if(type == "string" && ["xlsx", "xlsm", "xlsb", "xlam", "biff8", "biff5", "xla", "ods", "dbf"].indexOf(ext) > -1) return;
|
||||
if(type == "string" && ["xlsx", "xlsm", "xlsb", "xlam", "biff8", "biff5", "biff2", "xla", "ods", "dbf"].indexOf(ext) > -1) return;
|
||||
if(type == "array" && ["xlsx", "xlsm", "xlsb", "xlam", "ods"].indexOf(ext) > -1 && typeof Uint8Array === 'undefined') return;
|
||||
var datout = XLSX.write(wb, {type: type, bookType: ext, sheet:r[1] && r[1].sheet || null});
|
||||
XLSX.read(datout, {type:type});
|
||||
|
3
types/index.d.ts
vendored
3
types/index.d.ts
vendored
@ -730,6 +730,9 @@ export interface XLSX$Utils {
|
||||
/** Converts A1 range to 0-indexed form */
|
||||
decode_range(range: string): Range;
|
||||
|
||||
/** Format cell */
|
||||
format_cell(cell: CellObject, v?: any, opts?: any): string;
|
||||
|
||||
/* --- General Utilities --- */
|
||||
|
||||
/** Creates a new workbook */
|
||||
|
@ -28,13 +28,13 @@ const formulae: string[] = XLSX.utils.sheet_to_formulae(firstworksheet);
|
||||
const aoa: any[][] = XLSX.utils.sheet_to_json<any[]>(firstworksheet, {raw:true, header:1});
|
||||
|
||||
const aoa2: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet<number>([
|
||||
[1,2,3,4,5,6,7],
|
||||
[2,3,4,5,6,7,8]
|
||||
[1,2,3,4,5,6,7],
|
||||
[2,3,4,5,6,7,8]
|
||||
]);
|
||||
|
||||
const js2ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet<Tester>([
|
||||
{name:"Sheet", age: 12},
|
||||
{name:"JS", age: 24}
|
||||
{name:"Sheet", age: 12},
|
||||
{name:"JS", age: 24}
|
||||
]);
|
||||
|
||||
const WBProps = workbook.Workbook;
|
||||
@ -57,8 +57,23 @@ const wb_4: XLSX.WorkBook = XLSX.read(XLSX.write(newwb, {type: "file", bookType:
|
||||
const wb_5: XLSX.WorkBook = XLSX.read(XLSX.write(newwb, {type: "array", bookType: "xlsx" }), {type: "array"});
|
||||
const wb_6: XLSX.WorkBook = XLSX.read(XLSX.write(newwb, {type: "string", bookType: "xlsx" }), {type: "string"});
|
||||
|
||||
function get_header_row(sheet: XLSX.WorkSheet) {
|
||||
let headers: string[] = [];
|
||||
const range = XLSX.utils.decode_range(sheet['!ref']);
|
||||
let C: number = 0, R: number = range.s.r;
|
||||
for(C = range.s.c; C <= range.e.c; ++C) {
|
||||
const cell: XLSX.CellObject = sheet[XLSX.utils.encode_cell({c:C, r:R})];
|
||||
let hdr = "UNKNOWN " + C;
|
||||
if(cell && cell.t) hdr = XLSX.utils.format_cell(cell);
|
||||
headers.push(hdr);
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
const headers: string[] = get_header_row(aoa2);
|
||||
|
||||
const CFB = XLSX.CFB;
|
||||
const vbawb = XLSX.readFile("test.xlsm", {bookVBA:true});
|
||||
if(vbawb.vbaraw) {
|
||||
const cfb: XLSX.CFB.CFB$Container = CFB.read(vbawb.vbaraw, {type: "buffer"});
|
||||
const cfb: XLSX.CFB.CFB$Container = CFB.read(vbawb.vbaraw, {type: "buffer"});
|
||||
}
|
||||
|
21
xlsx.flow.js
21
xlsx.flow.js
@ -4,7 +4,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.12.4';
|
||||
XLSX.version = '0.12.5';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*:: declare var cptable:any; */
|
||||
/*global cptable:true */
|
||||
@ -9066,7 +9066,8 @@ function write_comments_vml(rId, comments) {
|
||||
];
|
||||
while(_shapeid < rId * 1000) _shapeid += 1000;
|
||||
|
||||
comments.map(function(x) { return decode_cell(x[0]); }).forEach(function(c) { o = o.concat([
|
||||
comments.forEach(function(x) { var c = decode_cell(x[0]);
|
||||
o = o.concat([
|
||||
'<v:shape' + wxt_helper({
|
||||
id:'_x0000_s' + (++_shapeid),
|
||||
type:"#_x0000_t202",
|
||||
@ -9182,13 +9183,11 @@ function write_comments_xml(data/*::, opts*/) {
|
||||
|
||||
var iauthor/*:Array<string>*/ = [];
|
||||
o.push("<authors>");
|
||||
data.map(function(x) { return x[1]; }).forEach(function(comment) {
|
||||
comment.map(function(x) { return escapexml(x.a); }).forEach(function(a) {
|
||||
if(iauthor.indexOf(a) > -1) return;
|
||||
iauthor.push(a);
|
||||
o.push("<author>" + a + "</author>");
|
||||
});
|
||||
});
|
||||
data.forEach(function(x) { x[1].forEach(function(w) { var a = escapexml(w.a);
|
||||
if(iauthor.indexOf(a) > -1) return;
|
||||
iauthor.push(a);
|
||||
o.push("<author>" + a + "</author>");
|
||||
}); });
|
||||
o.push("</authors>");
|
||||
o.push("<commentList>");
|
||||
data.forEach(function(d) {
|
||||
@ -14403,6 +14402,8 @@ function xlml_clean_comment(comment/*:any*/) {
|
||||
function xlml_normalize(d)/*:string*/ {
|
||||
if(has_buf &&/*::typeof Buffer !== "undefined" && d != null && d instanceof Buffer &&*/ Buffer.isBuffer(d)) return d.toString('utf8');
|
||||
if(typeof d === 'string') return d;
|
||||
/* duktape */
|
||||
if(typeof Uint8Array !== 'undefined' && d instanceof Uint8Array) return utf8read(a2s(ab2a(d)));
|
||||
throw new Error("Bad input format: expected Buffer or string");
|
||||
}
|
||||
|
||||
@ -19862,7 +19863,9 @@ if(has_buf && typeof require != 'undefined') (function() {
|
||||
var rowinfo/*:Array<RowInfo>*/ = o.skipHidden && sheet["!rows"] || [];
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colinfo[C]||{}).hidden)) cols[C] = encode_col(C);
|
||||
var R = r.s.r;
|
||||
var BOM = false;
|
||||
stream._read = function() {
|
||||
if(!BOM) { BOM = true; return stream.push("\uFEFF"); }
|
||||
if(R > r.e.r) return stream.push(null);
|
||||
while(R <= r.e.r) {
|
||||
++R;
|
||||
|
21
xlsx.js
generated
21
xlsx.js
generated
@ -4,7 +4,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.12.4';
|
||||
XLSX.version = '0.12.5';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -8972,7 +8972,8 @@ function write_comments_vml(rId, comments) {
|
||||
];
|
||||
while(_shapeid < rId * 1000) _shapeid += 1000;
|
||||
|
||||
comments.map(function(x) { return decode_cell(x[0]); }).forEach(function(c) { o = o.concat([
|
||||
comments.forEach(function(x) { var c = decode_cell(x[0]);
|
||||
o = o.concat([
|
||||
'<v:shape' + wxt_helper({
|
||||
id:'_x0000_s' + (++_shapeid),
|
||||
type:"#_x0000_t202",
|
||||
@ -9088,13 +9089,11 @@ function write_comments_xml(data) {
|
||||
|
||||
var iauthor = [];
|
||||
o.push("<authors>");
|
||||
data.map(function(x) { return x[1]; }).forEach(function(comment) {
|
||||
comment.map(function(x) { return escapexml(x.a); }).forEach(function(a) {
|
||||
if(iauthor.indexOf(a) > -1) return;
|
||||
iauthor.push(a);
|
||||
o.push("<author>" + a + "</author>");
|
||||
});
|
||||
});
|
||||
data.forEach(function(x) { x[1].forEach(function(w) { var a = escapexml(w.a);
|
||||
if(iauthor.indexOf(a) > -1) return;
|
||||
iauthor.push(a);
|
||||
o.push("<author>" + a + "</author>");
|
||||
}); });
|
||||
o.push("</authors>");
|
||||
o.push("<commentList>");
|
||||
data.forEach(function(d) {
|
||||
@ -14303,6 +14302,8 @@ function xlml_clean_comment(comment) {
|
||||
function xlml_normalize(d) {
|
||||
if(has_buf && Buffer.isBuffer(d)) return d.toString('utf8');
|
||||
if(typeof d === 'string') return d;
|
||||
/* duktape */
|
||||
if(typeof Uint8Array !== 'undefined' && d instanceof Uint8Array) return utf8read(a2s(ab2a(d)));
|
||||
throw new Error("Bad input format: expected Buffer or string");
|
||||
}
|
||||
|
||||
@ -19746,7 +19747,9 @@ if(has_buf && typeof require != 'undefined') (function() {
|
||||
var rowinfo = o.skipHidden && sheet["!rows"] || [];
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colinfo[C]||{}).hidden)) cols[C] = encode_col(C);
|
||||
var R = r.s.r;
|
||||
var BOM = false;
|
||||
stream._read = function() {
|
||||
if(!BOM) { BOM = true; return stream.push("\uFEFF"); }
|
||||
if(R > r.e.r) return stream.push(null);
|
||||
while(R <= r.e.r) {
|
||||
++R;
|
||||
|
Loading…
Reference in New Issue
Block a user