forked from sheetjs/docs.sheetjs.com
		
	
		
			
	
	
		
			89 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			89 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								const Knex = require('knex');
							 | 
						||
| 
								 | 
							
								const XLSX = require("xlsx");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* read file and get first worksheet */
							 | 
						||
| 
								 | 
							
								const oldwb = XLSX.readFile("pres.numbers");
							 | 
						||
| 
								 | 
							
								const oldws = oldwb.Sheets[oldwb.SheetNames[0]];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* create table and load data given an array of objects and a Knex connection */
							 | 
						||
| 
								 | 
							
								async function aoo_to_knex_table(knex, aoo, table_name) {
							 | 
						||
| 
								 | 
							
								  /* define types that can be converted (e.g. boolean can be stored in float) */
							 | 
						||
| 
								 | 
							
								  const T_FLOAT = ["float", "boolean"];
							 | 
						||
| 
								 | 
							
								  const T_BOOL = ["boolean"];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* types is a map from column headers to Knex schema column type */
							 | 
						||
| 
								 | 
							
								  const types = {};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* names is an ordered list of the column header names */
							 | 
						||
| 
								 | 
							
								  const names = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* loop across each row object */
							 | 
						||
| 
								 | 
							
								  aoo.forEach(row =>
							 | 
						||
| 
								 | 
							
								    /* Object.entries returns a row of [key, value] pairs */
							 | 
						||
| 
								 | 
							
								    Object.entries(row).forEach(([k,v]) => {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      /* If this is first occurrence, mark unknown and append header to names */
							 | 
						||
| 
								 | 
							
								      if(!types[k]) { types[k] = ""; names.push(k); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      /* skip null and undefined values */
							 | 
						||
| 
								 | 
							
								      if(v == null) return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      /* check and resolve type */
							 | 
						||
| 
								 | 
							
								      switch(typeof v) {
							 | 
						||
| 
								 | 
							
								        /* change type if it is empty or can be stored in a float */
							 | 
						||
| 
								 | 
							
								        case "number": if(!types[k] || T_FLOAT.includes(types[k])) types[k] = "float"; break;
							 | 
						||
| 
								 | 
							
								        /* change type if it is empty or can be stored in a boolean */
							 | 
						||
| 
								 | 
							
								        case "boolean": if(!types[k] || T_BOOL.includes(types[k])) types[k] = "boolean"; break;
							 | 
						||
| 
								 | 
							
								        /* no other type can hold strings */
							 | 
						||
| 
								 | 
							
								        case "string": types[k] = "text"; break;
							 | 
						||
| 
								 | 
							
								        default: types[k] = "text"; break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								  );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Delete table if it exists in the DB */
							 | 
						||
| 
								 | 
							
								  await knex.schema.dropTableIfExists(table_name);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* use column type info to create table */
							 | 
						||
| 
								 | 
							
								  await knex.schema.createTable(table_name, (table) => {
							 | 
						||
| 
								 | 
							
								    names.forEach(h => {
							 | 
						||
| 
								 | 
							
								      /* call schema function e.g. table.text("Name"); table.float("Index"); */
							 | 
						||
| 
								 | 
							
								      table[types[h] || "text"](h);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* insert each row */
							 | 
						||
| 
								 | 
							
								  await knex.insert(aoo).into(table_name);
							 | 
						||
| 
								 | 
							
								  return knex;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(async() => {
							 | 
						||
| 
								 | 
							
								  /* open connection to SheetJSKnex.db */
							 | 
						||
| 
								 | 
							
								  let knex = Knex({ client: 'better-sqlite3', connection: { filename: "SheetJSKnex.db" }, useNullAsDefault: true });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  try {
							 | 
						||
| 
								 | 
							
								    /* generate array of objects from worksheet */
							 | 
						||
| 
								 | 
							
								    const aoo = XLSX.utils.sheet_to_json(oldws);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* create table and load data */
							 | 
						||
| 
								 | 
							
								    await aoo_to_knex_table(knex, aoo, "Test_Table");
							 | 
						||
| 
								 | 
							
								  } finally {
							 | 
						||
| 
								 | 
							
								    /* disconnect */
							 | 
						||
| 
								 | 
							
								    knex.destroy();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* reconnect to SheetJSKnex.db */
							 | 
						||
| 
								 | 
							
								  knex = Knex({ client: 'better-sqlite3', connection: { filename: "SheetJSKnex.db" }, useNullAsDefault: true });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  try {
							 | 
						||
| 
								 | 
							
								    /* get data from db */
							 | 
						||
| 
								 | 
							
								    const aoo = await knex.select("*").from("Test_Table");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* export to file */
							 | 
						||
| 
								 | 
							
								    const newws = XLSX.utils.json_to_sheet(aoo);
							 | 
						||
| 
								 | 
							
								    const newwb = XLSX.utils.book_new();
							 | 
						||
| 
								 | 
							
								    XLSX.utils.book_append_sheet(newwb, newws, "Export");
							 | 
						||
| 
								 | 
							
								    XLSX.writeFile(newwb, "SheetJSKnex.xlsx");
							 | 
						||
| 
								 | 
							
								  } finally { knex.destroy(); }
							 | 
						||
| 
								 | 
							
								})();
							 |