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"> | <$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=""/> | <$edit-text tiddler=<<field>> field="import-field-value" tag="input" placeholder="constant" default=""/> | ||||||
| </$reveal> | </$reveal> | ||||||
|  | <$checkbox tiddler=<<field>> field="import-field-skip-tiddler-if-blank" checked="yes" unchecked="no" default="no"> | ||||||
|  | Skip this tiddler when field blank | ||||||
| <br/> | <br/> | ||||||
| Title: | Title: | ||||||
| <$tiddler tiddler=<<field>>> | <$tiddler tiddler=<<field>>> | ||||||
|  | @ -192,6 +194,13 @@ Title: | ||||||
| </$tiddler> | </$tiddler> | ||||||
| </li> | </li> | ||||||
| <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"> | <$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-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[]]"/> | <$action-listops $tiddler=<<row>> $subfilter="[{$:/temp/newtiddler}] +[putfirst[]]"/> | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ exports["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"] = f | ||||||
| 			text: text | 			text: text | ||||||
| 		}); | 		}); | ||||||
| 	// Return the output tiddlers
 | 	// Return the output tiddlers
 | ||||||
| 	return importer.importTiddlers(); | 	return importer.getResults(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| })(); | })(); | ||||||
|  |  | ||||||
|  | @ -21,103 +21,151 @@ var XLSXImporter = function(options) { | ||||||
| 	this.filename = options.filename; | 	this.filename = options.filename; | ||||||
| 	this.text = options.text; | 	this.text = options.text; | ||||||
| 	this.importSpec = options.importSpec || $tw.wiki.getTiddlerText(DEFAULT_IMPORT_SPEC_TITLE); | 	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() { | XLSXImporter.prototype.getResults = function() { | ||||||
| 	var self = this, | 	return this.results; | ||||||
| 		results = [], | }; | ||||||
| 		workbook; | 
 | ||||||
| 	// Check for the JSZIP plugin
 | XLSXImporter.prototype.processWorkbook = function() { | ||||||
| 	if(!JSZip) { |  | ||||||
| 		return results; |  | ||||||
| 	} |  | ||||||
| 	// Read the workbook
 | 	// Read the workbook
 | ||||||
| 	if(this.filename) { | 	if(this.filename) { | ||||||
| 		workbook = XLSX.readFile(this.filename);	 | 		this.workbook = XLSX.readFile(this.filename);	 | ||||||
| 	} else if(this.text) { | 	} else if(this.text) { | ||||||
| 		workbook = XLSX.read(this.text,{type:"base64"}); | 		this.workbook = XLSX.read(this.text,{type:"base64"}); | ||||||
| 	} | 	} | ||||||
| 	// Read the root import specification
 | 	// Read the root import specification
 | ||||||
| 	var rootImportSpec = $tw.wiki.getTiddler(this.importSpec); | 	this.rootImportSpec = $tw.wiki.getTiddler(this.importSpec); | ||||||
| 	if(rootImportSpec) { | 	if(this.rootImportSpec) { | ||||||
| 		// Iterate through the sheets specified in the list field
 | 		// Iterate through the sheets specified in the list field
 | ||||||
| 		$tw.utils.each(rootImportSpec.fields.list || [],function(sheetImportSpecTitle) { | 		$tw.utils.each(this.rootImportSpec.fields.list || [],this.processSheet.bind(this)); | ||||||
| 			// 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.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) { | XLSXImporter.prototype.measureSheet = function(sheet) { | ||||||
| 	var sheetRange = XLSX.utils.decode_range(sheet["!ref"]); | 	var sheetRange = XLSX.utils.decode_range(sheet["!ref"]); | ||||||
| 	return { | 	return { | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ Command.prototype.execute = function() { | ||||||
| 			filename: filename, | 			filename: filename, | ||||||
| 			importSpec: importSpec | 			importSpec: importSpec | ||||||
| 		}); | 		}); | ||||||
| 	$tw.wiki.addTiddlers(importer.importTiddlers()); | 	$tw.wiki.addTiddlers(importer.getResults()); | ||||||
| 	return null; | 	return null; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 Jermolene
						Jermolene