kopia lustrzana https://github.com/miklobit/TiddlyWiki5
				
				
				
			Two improvements to xlsx-utils plugin
Add support for skipping an entire tiddler if a particular column is blank Add support for reading a row by column, making each of the columns into a fieldname. Also significantly refactored the code to break up the main, monolithic function.print-window-tiddler
							rodzic
							
								
									f7d81a00c2
								
							
						
					
					
						commit
						a485eb8588
					
				|  | @ -130,6 +130,8 @@ suffixed | |||
| <$reveal state="""$(field)$!!import-field-source""" type="match" text="constant" default="column" tag="span"> | ||||
| <$edit-text tiddler=<<field>> field="import-field-value" tag="input" placeholder="constant" default=""/> | ||||
| </$reveal> | ||||
| <$checkbox tiddler=<<field>> field="import-field-skip-tiddler-if-blank" checked="yes" unchecked="no" default="no"> | ||||
| Skip this tiddler when field blank | ||||
| <br/> | ||||
| Title: | ||||
| <$tiddler tiddler=<<field>>> | ||||
|  | @ -192,6 +194,13 @@ Title: | |||
| </$tiddler> | ||||
| </li> | ||||
| <li> | ||||
| Row type: | ||||
| <$select tiddler=<<row>> field="import-row-type" default="by-field"> | ||||
| <option value="by-field">By field</option> | ||||
| <option value="by-column">By column</option> | ||||
| </$select> | ||||
| </li> | ||||
| <li> | ||||
| <$button class="tc-btn-invisible"> | ||||
| <$action-createtiddler $basetitle="$:/_ExcelImporter/ImportSpecifiers/Field" $savetitle="$:/temp/newtiddler" import-spec-role="field" import-field-name="fieldname" import-field-type="string" import-field-source="column" import-field-column="Column Name" /> | ||||
| <$action-listops $tiddler=<<row>> $subfilter="[{$:/temp/newtiddler}] +[putfirst[]]"/> | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ exports["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"] = f | |||
| 			text: text | ||||
| 		}); | ||||
| 	// Return the output tiddlers
 | ||||
| 	return importer.importTiddlers(); | ||||
| 	return importer.getResults(); | ||||
| }; | ||||
| 
 | ||||
| })(); | ||||
|  |  | |||
|  | @ -21,103 +21,151 @@ var XLSXImporter = function(options) { | |||
| 	this.filename = options.filename; | ||||
| 	this.text = options.text; | ||||
| 	this.importSpec = options.importSpec || $tw.wiki.getTiddlerText(DEFAULT_IMPORT_SPEC_TITLE); | ||||
| 	this.logger = new $tw.utils.Logger("xlsx-utils"); | ||||
| 	this.results = []; | ||||
| 	if(JSZip) { | ||||
| 		this.processWorkbook();		 | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| XLSXImporter.prototype.importTiddlers = function() { | ||||
| 	var self = this, | ||||
| 		results = [], | ||||
| 		workbook; | ||||
| 	// Check for the JSZIP plugin
 | ||||
| 	if(!JSZip) { | ||||
| 		return results; | ||||
| 	} | ||||
| XLSXImporter.prototype.getResults = function() { | ||||
| 	return this.results; | ||||
| }; | ||||
| 
 | ||||
| XLSXImporter.prototype.processWorkbook = function() { | ||||
| 	// Read the workbook
 | ||||
| 	if(this.filename) { | ||||
| 		workbook = XLSX.readFile(this.filename);	 | ||||
| 		this.workbook = XLSX.readFile(this.filename);	 | ||||
| 	} else if(this.text) { | ||||
| 		workbook = XLSX.read(this.text,{type:"base64"}); | ||||
| 		this.workbook = XLSX.read(this.text,{type:"base64"}); | ||||
| 	} | ||||
| 	// Read the root import specification
 | ||||
| 	var rootImportSpec = $tw.wiki.getTiddler(this.importSpec); | ||||
| 	if(rootImportSpec) { | ||||
| 	this.rootImportSpec = $tw.wiki.getTiddler(this.importSpec); | ||||
| 	if(this.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); | ||||
| 						} | ||||
| 					});					 | ||||
| 				} | ||||
| 			} | ||||
| 		}); | ||||
| 		$tw.utils.each(this.rootImportSpec.fields.list || [],this.processSheet.bind(this)); | ||||
| 	} | ||||
| 	return results; | ||||
| }; | ||||
| 
 | ||||
| XLSXImporter.prototype.processSheet = function(sheetImportSpecTitle) { | ||||
| 	// Get the sheet import specifier
 | ||||
| 	this.sheetImportSpec = $tw.wiki.getTiddler(sheetImportSpecTitle); | ||||
| 	if(this.sheetImportSpec) { | ||||
| 		this.sheetName = this.sheetImportSpec.fields["import-sheet-name"]; | ||||
| 		this.sheet = this.workbook.Sheets[this.sheetName]; | ||||
| 		if(!this.sheet) { | ||||
| 			this.logger.alert("Missing sheet '" + this.sheetName + "'"); | ||||
| 		} else { | ||||
| 			// Get the size of the sheet
 | ||||
| 			this.sheetSize = this.measureSheet(this.sheet); | ||||
| 			// Read the column names from the first row
 | ||||
| 			this.columnsByName = this.findColumns(this.sheet,this.sheetSize); | ||||
| 			// Iterate through the rows
 | ||||
| 			for(this.row=this.sheetSize.startRow+1; this.row<=this.sheetSize.endRow; this.row++) { | ||||
| 				// Iterate through the row import specifiers
 | ||||
| 				$tw.utils.each(this.sheetImportSpec.fields.list || [],this.processRow.bind(this));					 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| XLSXImporter.prototype.processRow = function(rowImportSpecTitle) { | ||||
| 	this.rowImportSpec = $tw.wiki.getTiddler(rowImportSpecTitle); | ||||
| 	if(this.rowImportSpec) { | ||||
| 		this.tiddlerFields = {}; | ||||
| 		this.skipTiddler = false; | ||||
| 		// Determine the type of row
 | ||||
| 		this.rowType = this.rowImportSpec.fields["import-row-type"] || "by-field"; | ||||
| 		switch(this.rowType) { | ||||
| 			case "by-column": | ||||
| 				this.processRowByColumn(); | ||||
| 				break; | ||||
| 			case "by-field": | ||||
| 				this.processRowByField(); | ||||
| 				break; | ||||
| 		} | ||||
| 		// Save the tiddler if not skipped
 | ||||
| 		if(!this.skipTiddler) { | ||||
| 			if(!this.tiddlerFields.title) { | ||||
| 				this.logger.alert("Missing title field for " + JSON.stringify(this.tiddlerFields)); | ||||
| 			} | ||||
| 			this.results.push(this.tiddlerFields);								 | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| XLSXImporter.prototype.processRowByColumn = function() { | ||||
| 	var self = this; | ||||
| 	// Iterate through the columns for the row
 | ||||
| 	$tw.utils.each(this.columnsByName,function(index,name) { | ||||
| 		var cell = self.sheet[XLSX.utils.encode_cell({c: self.columnsByName[name], r: self.row})]; | ||||
| 		name = name.toLowerCase(); | ||||
| 		if(cell && cell.w && $tw.utils.isValidFieldName(name)) { | ||||
| 			self.tiddlerFields[name] = cell.w;		 | ||||
| 		} | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| XLSXImporter.prototype.processRowByField = function() { | ||||
| 	// Iterate through the fields for the row
 | ||||
| 	$tw.utils.each(this.rowImportSpec.fields.list || [],this.processField.bind(this)); | ||||
| }; | ||||
| 
 | ||||
| XLSXImporter.prototype.processField = 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 = this.sheet[XLSX.utils.encode_cell({c: this.columnsByName[columnName], r: this.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((value || "").trim() === "") { | ||||
| 			if((fieldImportSpec.fields["import-field-skip-tiddler-if-blank"] || "").trim().toLowerCase() === "yes") { | ||||
| 				this.skipTiddler = true; | ||||
| 			} | ||||
| 			if(fieldImportSpec.fields["import-field-replace-blank"]) { | ||||
| 				value = fieldImportSpec.fields["import-field-replace-blank"]; | ||||
| 			} | ||||
| 		} | ||||
| 		switch(fieldImportSpec.fields["import-field-list-op"] || "none") { | ||||
| 			case "none": | ||||
| 				this.tiddlerFields[fieldName] = value; | ||||
| 				break; | ||||
| 			case "append": | ||||
| 				var list = $tw.utils.parseStringArray(this.tiddlerFields[fieldName] || ""); | ||||
| 				$tw.utils.pushTop(list,value) | ||||
| 				this.tiddlerFields[fieldName] = list; | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| XLSXImporter.prototype.measureSheet = function(sheet) { | ||||
| 	var sheetRange = XLSX.utils.decode_range(sheet["!ref"]); | ||||
| 	return { | ||||
|  |  | |||
|  | @ -36,7 +36,7 @@ Command.prototype.execute = function() { | |||
| 			filename: filename, | ||||
| 			importSpec: importSpec | ||||
| 		}); | ||||
| 	$tw.wiki.addTiddlers(importer.importTiddlers()); | ||||
| 	$tw.wiki.addTiddlers(importer.getResults()); | ||||
| 	return null; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Jermolene
						Jermolene