forked from sheetjs/docs.sheetjs.com
		
	
		
			
	
	
		
			115 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			115 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | const pg = require("pg"), format = require("pg-format"); | ||
|  | const XLSX = require("xlsx"); | ||
|  | const opts = { | ||
|  |   database:"SheetJSPG", | ||
|  |   host: "127.0.0.1", // localhost
 | ||
|  |   port: 5432, | ||
|  |   //user: "",
 | ||
|  |   //password: ""
 | ||
|  | }; | ||
|  | 
 | ||
|  | /* create table and load data given an array of objects and a PostgreSQL client */ | ||
|  | async function aoo_to_pg_table(client, aoo, table_name) { | ||
|  |   /* define types that can be converted (e.g. boolean can be stored in float) */ | ||
|  |   const T_FLOAT = ["float8", "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] = "float8"; 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 */ | ||
|  |   const query = format("DROP TABLE IF EXISTS %I;", table_name); | ||
|  |   await client.query(query); | ||
|  | 
 | ||
|  |   /* Create table */ | ||
|  |   { | ||
|  |     const entries = Object.entries(types); | ||
|  |     const Istr = entries.map(e => format(`%I ${e[1]}`, e[0])).join(", "); | ||
|  |     let query = format.withArray(`CREATE TABLE %I (${Istr});`, [ table_name ]); | ||
|  |     await client.query(query); | ||
|  |   } | ||
|  | 
 | ||
|  |   /* Insert each row */ | ||
|  |   for(let row of aoo) { | ||
|  |     const ent = Object.entries(row); | ||
|  |     const Istr = Array.from({length: ent.length}, ()=>"%I").join(", "); | ||
|  |     const Lstr = Array.from({length: ent.length}, ()=>"%L").join(", "); | ||
|  |     let query = format.withArray( | ||
|  |       `INSERT INTO %I (${Istr}) VALUES (${Lstr});`, | ||
|  |       [ table_name, ...ent.map(x => x[0]), ...ent.map(x => x[1]) ] | ||
|  |     ); | ||
|  |     await client.query(query); | ||
|  |   } | ||
|  | 
 | ||
|  |   return client; | ||
|  | } | ||
|  | 
 | ||
|  | (async() => { | ||
|  | 
 | ||
|  | /* read file and get first worksheet */ | ||
|  | const oldwb = XLSX.readFile("pres.numbers"); | ||
|  | const oldws = oldwb.Sheets[oldwb.SheetNames[0]]; | ||
|  | 
 | ||
|  | /* import data to postgres */ | ||
|  | let client = new pg.Client(opts); | ||
|  | try { | ||
|  |   /* open connection to PostgreSQL database */ | ||
|  |   await client.connect(); | ||
|  | 
 | ||
|  |   /* generate array of objects from worksheet */ | ||
|  |   const aoo = XLSX.utils.sheet_to_json(oldws); | ||
|  | 
 | ||
|  |   /* create table and load data */ | ||
|  |   await aoo_to_pg_table(client, aoo, "Presidents"); | ||
|  | } finally { | ||
|  |   /* disconnect */ | ||
|  |   await client.end(); | ||
|  | } | ||
|  | 
 | ||
|  | /* export data to xlsx */ | ||
|  | client = new pg.Client(opts); | ||
|  | try { | ||
|  |   /* open connection to PostgreSQL database */ | ||
|  |   await client.connect(); | ||
|  | 
 | ||
|  |   /* fetch all data from specified table */ | ||
|  |   const res = await client.query(format(`SELECT * FROM %I`, "Presidents")); | ||
|  | 
 | ||
|  |   /* export to file */ | ||
|  |   const newws = XLSX.utils.json_to_sheet(res.rows); | ||
|  |   const newwb = XLSX.utils.book_new(); | ||
|  |   XLSX.utils.book_append_sheet(newwb, newws, "Export"); | ||
|  |   XLSX.writeFile(newwb, "SheetJSPGExport.xlsx"); | ||
|  | } finally { | ||
|  |   /* disconnect */ | ||
|  |   await client.end(); | ||
|  | } | ||
|  | })(); |