diff --git a/.gitignore b/.gitignore index 6704566..f2b6599 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,7 @@ dist # TernJS port file .tern-port + +yarn.lock +package-lock.json +outputs/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..393342e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM cubetiq/calpine-node:latest +LABEL maintainer="sombochea@cubetiqs.com" + +VOLUME [ "/app/data" ] + +ENV INPUT_FILE './data/people.xlsx' +ENV OUTPUT_PATH './data/outputs' +ENV MAPPER_FILE './data/mapper.json' + +WORKDIR /app + +COPY . /app + +RUN yarn + +CMD [ "node" , "index.js"] \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..32140e5 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +DOCKER_IMAGE=cubetiq/node-excel2json + +build: + @echo "Building docker image..." + docker build . -t ${DOCKER_IMAGE} + +run: + @echo "Running container..." + docker run --rm -t ${DOCKER_IMAGE} + +.PHONY: build diff --git a/README.md b/README.md new file mode 100644 index 0000000..aff9367 --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# excel2json + +- Read file excel to json +- Custom mapping with custom columns and configs + +# Build + +```shell +bash build +``` + +OR + +```shell +make build run +``` + +# Example + +```shell +docker run -v /my/path:/app/data --rm -it cubetiq/node-excel2json +``` + +```shell +docker run -v /home/sombochea/excel2json:/app/data -e APP_NAME="EXCEL 2 JSON" -e MAPPER_FILE="./data/mapper.json" --rm -it cubetiq/node-excel2json +``` + +# Mapper Config + +```json +{ + "data": [ + { + "dataIndex": "Name", + "label": "Name" + }, + { + "dataIndex": "Age", + "label": "Age" + } + ], + "configs": { + "outputPath": "./data/outputs/exported", + "outputName": "my_exported_data", + "sheetName": "Sheet1", + "saveToOutput": true + } +} +``` + +# Environment + +```env +APP_NAME=custom app name +INPUT_FILE=./data/mydata.xlsx +OUTPUT_PATH=./data/outputs +MAPPER_FILE=./data/mapper.json +SHEET_NAME=Sheet1 +ENCODING=utf-8 +``` diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..7ece719 --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +make build run \ No newline at end of file diff --git a/data/mapper.json b/data/mapper.json new file mode 100644 index 0000000..80ff8e5 --- /dev/null +++ b/data/mapper.json @@ -0,0 +1,18 @@ +{ + "data": [ + { + "dataIndex": "Name", + "label": "Name" + }, + { + "dataIndex": "Age", + "label": "Age" + } + ], + "configs": { + "outputPath": "./data/outputs/exported", + "outputName": "my_exported_data", + "sheetName": "Sheet1", + "saveToOutput": true + } +} diff --git a/data/people.xlsx b/data/people.xlsx new file mode 100644 index 0000000..9162696 Binary files /dev/null and b/data/people.xlsx differ diff --git a/excel2json.js b/excel2json.js new file mode 100644 index 0000000..2797060 --- /dev/null +++ b/excel2json.js @@ -0,0 +1,102 @@ +const XLSX = require("xlsx"); +const fs = require("fs"); + +// do export for excel to json output or data json object +function _internalExport(props = {}) { + const NAME = process.env.APP_NAME || "excel2json"; + console.log("APP NAME =>", NAME, "\n"); + + // load from env + const INPUT_FILE = + props.inputFile || process.env.INPUT_FILE || "./data/people.xlsx"; + const OUTPUT_PATH = + props.outputPath || process.env.OUTPUT_PATH || "./data/outputs"; + const MAPPER_FILE = + props.mapperFile || process.env.MAPPER_FILE || "./data/mapper.json"; + const SHEET_NAME = props.sheetName || process.env.SHEET_NAME || "Sheet1"; + const ENCODING = props.encoding || process.env.ENCODING || "utf-8"; + + // get mapper in string + var mapperString = undefined; + try { + mapperString = fs.readFileSync( + MAPPER_FILE, + { encoding: ENCODING }, + (err) => { + if (err) { + console.error(err); + } + console.log("Load file suceed =>", MAPPER_FILE); + } + ); + } catch (err) { + console.error("read file error", err); + } + + // convert mapper from string to json object + const mapperJson = mapperString ? JSON.parse(mapperString) : {}; + const configs = { ...mapperJson.configs, ...props }; + console.log(configs); + const columsData = props.mappings || mapperJson.data || undefined; + + // read workbook from excel file + const wb = XLSX.readFile(configs.inputFile || INPUT_FILE); + const xlData = XLSX.utils.sheet_to_json( + wb.Sheets[configs.sheetName || SHEET_NAME] + ); + + // mapping the data from read excel file + const data = xlData.map((row) => { + if (columsData == undefined || !columsData) { + return row; + } + + var _r = {}; + + columsData.map((col) => { + _r[col.label] = row[col.dataIndex]; + }); + + return _r; + }); + + // able to save to output or not (default is true) + if (configs.saveToOutputput) { + // parse a new path + const outputPath = configs.outputPath || OUTPUT_PATH; + + // check directory and create it if not exist + if (!fs.existsSync(outputPath)) { + fs.mkdirSync(outputPath, { recursive: true }); + } + + // json data output + const jsonStringData = JSON.stringify(data); + + try { + // write to file + fs.writeFileSync( + `${outputPath}/${ + configs.outputName || "exported" + }_${new Date().getTime()}.json`, + jsonStringData, + (err) => { + if (err) throw err; + console.log("Write succeed!"); + } + ); + } catch (err) {} + } + + return data; +} + +/** + * excel2json + * Allow to export data from excel to json object or output of json. + * + * @returns JSON Object of result + */ +module.exports = excel2json = (props = {}) => { + return _internalExport(props); +}; diff --git a/index.js b/index.js new file mode 100644 index 0000000..ffd8463 --- /dev/null +++ b/index.js @@ -0,0 +1,16 @@ +// import excel2json module +const excel2json = require("./excel2json"); + +// called function export excel2json +const exported = excel2json({ + mappings: [ + { + "dataIndex": "Name", + "label": "Name" + } + ], + "saveToOutput": false +}); + +// output data from exported +console.log("Output =>\n", exported); diff --git a/package.json b/package.json new file mode 100644 index 0000000..984d7d3 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "excel2json", + "version": "1.0.0", + "description": "Excel to json", + "main": "index.js", + "scripts": { + "start": "node index.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Sambo Chea ", + "license": "MIT", + "dependencies": { + "xlsx": "^0.16.9" + } +}