Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kecci committed Dec 7, 2022
0 parents commit 72e43b9
Show file tree
Hide file tree
Showing 14 changed files with 430 additions and 0 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: goreleaser

on:
push:
# run only against tags
tags:
- '*'

permissions:
contents: write
# packages: write
# issues: write

jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: git fetch --force --tags
- uses: actions/setup-go@v3
with:
go-version: '>=1.19.3'
cache: true
# More assembly might be required: Docker logins, GPG, etc. It all depends
# on your needs.
- uses: goreleaser/goreleaser-action@v2
with:
# either 'goreleaser' (default) or 'goreleaser-pro':
distribution: goreleaser
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro'
# distribution:
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.DS_Store
dist/
36 changes: 36 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
# you may remove this if you don't need go generate
- go generate ./...
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
archives:
- replacements:
darwin: Darwin
linux: Linux
windows: Windows
386: i386
amd64: x86_64
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'

# modelines, feel free to remove those if you don't want/use them:
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# json-converter

![image](asset/excel.png)

json-converter is CLI to convert JSON to Any other files like:
- Excel
- CSV
- and more

## Installation

### Using the github repository
```sh
git clone https://github.com/kecci/json-converter.git
cd json-converter
go build -o json-converter .
./json-converter --help
```

## Usage
```
./json-converter excel
```

## Example

### Example JSON
`./example/example.json`
```json
[
{
"isbn": "123-456-222",
"author": {
"lastname": "Doe",
"firstname": "Jane"
},
"editor": {
"lastname": "Smith",
"firstname": "Jane"
},
"title": "The Ultimate Database Study Guide",
"category": [
"Non-Fiction",
"Technology"
]
},
{
"isbn": "345-666-777",
"author": {
"lastname": "Han",
"firstname": "Some"
},
"editor": {
"lastname": "Marry",
"firstname": "Jane"
},
"title": "The Story Behind Spiderman",
"category": [
"Fiction",
"Comic"
]
}
]
```

### Running Command json-converter excel
```sh
./json-converter excel ./example/example.json ./example/example.xlsx
```

### Result
| author.firstname | author.lastname | category.0 | category.1 | editor.firstname | editor.lastname | isbn | title |
|------------------|-----------------|-------------|------------|------------------|-----------------|-------------|-----------------------------------|
| Jane | Doe | Non-Fiction | Technology | Jane | Smith | 123-456-222 | The Ultimate Database Study Guide |
| Some | Han | Fiction | Comic | Jane | Marry | 345-666-777 | The Story Behind Spiderman |
Binary file added asset/excel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
108 changes: 108 additions & 0 deletions cmd/json_converter/json_converter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package json_converter

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"sort"

"github.com/nqd/flat"
"github.com/xuri/excelize/v2"
)

// JsonToExcel converter
func JsonToExcel(jsonLocation, excelLocation string) {

// Location file path
// > /Users/kecci/Downloads/example.json
// > C:/Program Files/Documents/example.json
jsonFile, err := os.Open(jsonLocation)
if err != nil {
log.Fatal(err)
return
}
defer jsonFile.Close()

byteValue, _ := ioutil.ReadAll(jsonFile)

var jsonMaps []map[string]interface{}
err = json.Unmarshal([]byte(byteValue), &jsonMaps)
if err != nil {
log.Fatal(err)
return
}

jsonNormalized := BulkNormalize(jsonMaps)
if len(jsonNormalized) == 0 {
return
}

f := excelize.NewFile()
sheetName := "Sheet1"
sheetIndex := f.GetSheetIndex(sheetName)

// Header
jsonFirst := jsonNormalized[0]
headerKeys := make([]string, 0, len(jsonFirst))
for k := range jsonFirst {
headerKeys = append(headerKeys, k)
}
sort.Strings(headerKeys)

columnHeaderCount := 1
for _, k := range headerKeys {
f.SetCellValue(sheetName, fmt.Sprintf("%s1", GetColumnName(columnHeaderCount)), k)
columnHeaderCount += 1
}

rowCount := 2
for _, jsonData := range jsonNormalized {
columnCount := 1
for _, k := range headerKeys {
f.SetCellValue(sheetName, fmt.Sprintf("%s%v", GetColumnName(columnCount), rowCount), jsonData[k])
columnCount += 1
}
rowCount += 1
}

// Set active sheet of the workbook.
f.SetActiveSheet(sheetIndex)

// Save spreadsheet by the given path.
// Location file path
// > /Users/kecci/Downloads/example.xlsx
// > C:/Program Files/Documents/example.xlsx
if err := f.SaveAs(excelLocation); err != nil {
log.Fatal(err)
}

println("Success saved on", excelLocation)
}

// BulkNormalize returns a BulkNormalize
func BulkNormalize(jsonMaps []map[string]interface{}) (res []map[string]interface{}) {
for _, jsonMap := range jsonMaps {
out, err := flat.Flatten(jsonMap, nil)
if err != nil {
return res
}

res = append(res, out)
}
return res
}

// GetColumnName excel
func GetColumnName(col int) string {
name := make([]byte, 0, 3) // max 16,384 columns (2022)
const aLen = 'Z' - 'A' + 1 // alphabet length
for ; col > 0; col /= aLen + 1 {
name = append(name, byte('A'+(col-1)%aLen))
}
for i, j := 0, len(name)-1; i < j; i, j = i+1, j-1 {
name[i], name[j] = name[j], name[i]
}
return string(name)
}
20 changes: 20 additions & 0 deletions cmd/json_converter/json_to_excel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package json_converter

import (
"github.com/spf13/cobra"
)

var excelCmd = &cobra.Command{
Use: "excel",
Short: "Convert json to excel file",
Example: "json-converter excel /Users/kecci/Downloads/message_transaction_2022_nov.json /Users/kecci/Downloads/message_transaction_2022_nov.xlsx",
Aliases: []string{"xlsx"},
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
JsonToExcel(args[0], args[1])
},
}

func init() {
rootCmd.AddCommand(excelCmd)
}
30 changes: 30 additions & 0 deletions cmd/json_converter/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package json_converter

import (
"fmt"
"os"

"github.com/spf13/cobra"
)

var version = "v0.0.1"

var rootCmd = &cobra.Command{
Use: "",
Version: version,
Short: "json-converter - a simple CLI to conversion json and excel files.",
Long: `json-converter - a simple CLI to conversion json and excel files.`,
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
},
}

func Execute() {
rootCmd.CompletionOptions = cobra.CompletionOptions{
DisableDefaultCmd: true,
}
if err := rootCmd.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "Whoops. There was an error while executing your CLI '%s'", err)
os.Exit(1)
}
}
34 changes: 34 additions & 0 deletions example/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[
{
"isbn": "123-456-222",
"author": {
"lastname": "Doe",
"firstname": "Jane"
},
"editor": {
"lastname": "Smith",
"firstname": "Jane"
},
"title": "The Ultimate Database Study Guide",
"category": [
"Non-Fiction",
"Technology"
]
},
{
"isbn": "345-666-777",
"author": {
"lastname": "Han",
"firstname": "Some"
},
"editor": {
"lastname": "Marry",
"firstname": "Jane"
},
"title": "The Story Behind Spiderman",
"category": [
"Fiction",
"Comic"
]
}
]
Binary file added example/example.xlsx
Binary file not shown.
23 changes: 23 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module github.com/kecci/json-converter

go 1.17

require (
github.com/nqd/flat v0.2.0
github.com/spf13/cobra v1.6.1
github.com/xuri/excelize/v2 v2.6.1
)

require (
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.3 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 // indirect
golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect
golang.org/x/text v0.3.7 // indirect
)
Loading

0 comments on commit 72e43b9

Please sign in to comment.