mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-16 23:04:50 +00:00
8de4583d6c
Thanks to @stevesunypoly for help with preparing the demo spreadsheet
149 lines
4.8 KiB
JavaScript
149 lines
4.8 KiB
JavaScript
/*\
|
|
title: $:/plugins/tiddlywiki/xlsx-utils/importer.js
|
|
type: application/javascript
|
|
module-type: library
|
|
|
|
Class to import an Excel file
|
|
|
|
\*/
|
|
(function(){
|
|
|
|
/*jslint node: true, browser: true */
|
|
/*global $tw: false */
|
|
"use strict";
|
|
|
|
var DEFAULT_IMPORT_SPEC_TITLE = "$:/config/plugins/tiddlywiki/xlsx-utils/default-import-spec";
|
|
|
|
var XLSX = require("$:/plugins/tiddlywiki/xlsx-utils/xlsx.js"),
|
|
JSZip = require("$:/plugins/tiddlywiki/jszip/jszip.js");
|
|
|
|
var XLSXImporter = function(options) {
|
|
this.filename = options.filename;
|
|
this.text = options.text;
|
|
this.importSpec = options.importSpec || $tw.wiki.getTiddlerText(DEFAULT_IMPORT_SPEC_TITLE);
|
|
};
|
|
|
|
XLSXImporter.prototype.importTiddlers = function() {
|
|
var self = this,
|
|
results = [],
|
|
workbook;
|
|
// Check for the JSZIP plugin
|
|
if(!JSZip) {
|
|
return results;
|
|
}
|
|
// Read the workbook
|
|
if(this.filename) {
|
|
workbook = XLSX.readFile(this.filename);
|
|
} else if(this.text) {
|
|
workbook = XLSX.read(this.text,{type:"base64"});
|
|
}
|
|
// Read the root import specification
|
|
var rootImportSpec = $tw.wiki.getTiddler(this.importSpec);
|
|
if(rootImportSpec) {
|
|
// Iterate through the sheets specified in the list field
|
|
$tw.utils.each(rootImportSpec.fields.list || [],function(sheetImportSpecTitle) {
|
|
// Get the sheet import specifier
|
|
var sheetImportSpec = $tw.wiki.getTiddler(sheetImportSpecTitle);
|
|
if(sheetImportSpec) {
|
|
var sheetName = sheetImportSpec.fields["import-sheet-name"],
|
|
sheet = workbook.Sheets[sheetName];
|
|
// Get the size of the sheet
|
|
var sheetSize = self.measureSheet(sheet);
|
|
// Read the column names from the first row
|
|
var columnsByName = self.findColumns(sheet,sheetSize);
|
|
// Iterate through the rows
|
|
for(var row=sheetSize.startRow+1; row<=sheetSize.endRow; row++) {
|
|
// Iterate through the row import specifiers
|
|
$tw.utils.each(sheetImportSpec.fields.list || [],function(rowImportSpecTitle) {
|
|
var rowImportSpec = $tw.wiki.getTiddler(rowImportSpecTitle);
|
|
if(rowImportSpec) {
|
|
var tiddlerFields = {};
|
|
// Iterate through the fields for the row
|
|
$tw.utils.each(rowImportSpec.fields.list || [],function(fieldImportSpecTitle) {
|
|
var fieldImportSpec = $tw.wiki.getTiddler(fieldImportSpecTitle);
|
|
if(fieldImportSpec) {
|
|
var fieldName = fieldImportSpec.fields["import-field-name"],
|
|
value;
|
|
switch(fieldImportSpec.fields["import-field-source"]) {
|
|
case "column":
|
|
var columnName = fieldImportSpec.fields["import-field-column"],
|
|
cell = sheet[XLSX.utils.encode_cell({c: columnsByName[columnName], r: row})];
|
|
if(cell) {
|
|
switch(fieldImportSpec.fields["import-field-type"] || "string") {
|
|
case "date":
|
|
if(cell.t === "n") {
|
|
value = $tw.utils.stringifyDate(new Date((cell.v - (25567 + 2)) * 86400 * 1000));
|
|
}
|
|
break;
|
|
case "string":
|
|
// Intentional fall-through
|
|
default:
|
|
value = cell.w;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case "constant":
|
|
value = fieldImportSpec.fields["import-field-value"]
|
|
break;
|
|
}
|
|
if(fieldImportSpec.fields["import-field-prefix"]) {
|
|
value = fieldImportSpec.fields["import-field-prefix"] + value;
|
|
}
|
|
if(fieldImportSpec.fields["import-field-suffix"]) {
|
|
value = value + fieldImportSpec.fields["import-field-suffix"];
|
|
}
|
|
if(fieldImportSpec.fields["import-field-replace-blank"] && (value || "").trim() === "") {
|
|
value = fieldImportSpec.fields["import-field-replace-blank"];
|
|
}
|
|
switch(fieldImportSpec.fields["import-field-list-op"] || "none") {
|
|
case "none":
|
|
tiddlerFields[fieldName] = value;
|
|
break;
|
|
case "append":
|
|
var list = $tw.utils.parseStringArray(tiddlerFields[fieldName] || "");
|
|
$tw.utils.pushTop(list,value)
|
|
tiddlerFields[fieldName] = list;
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
results.push(tiddlerFields);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
return results;
|
|
};
|
|
|
|
XLSXImporter.prototype.measureSheet = function(sheet) {
|
|
var sheetRange = XLSX.utils.decode_range(sheet["!ref"]);
|
|
return {
|
|
startRow: Math.min(sheetRange.s.r,sheetRange.e.r),
|
|
endRow: Math.max(sheetRange.s.r,sheetRange.e.r),
|
|
startCol: Math.min(sheetRange.s.c,sheetRange.e.c),
|
|
endCol: Math.max(sheetRange.s.c,sheetRange.e.c)
|
|
}
|
|
};
|
|
|
|
XLSXImporter.prototype.findColumns = function(sheet,sheetSize) {
|
|
var columnsByName = {};
|
|
for(var col=sheetSize.startCol; col<=sheetSize.endCol; col++) {
|
|
var cell = sheet[XLSX.utils.encode_cell({c: col, r: sheetSize.startRow})],
|
|
columnName;
|
|
if(cell) {
|
|
columnName = cell.w;
|
|
if(columnName) {
|
|
columnsByName[columnName] = col;
|
|
}
|
|
}
|
|
}
|
|
return columnsByName;
|
|
};
|
|
|
|
exports.XLSXImporter = XLSXImporter;
|
|
|
|
})();
|