omankame
omankame

Reputation: 59

JSON to Excel conversion, by using go lang map data structure does not produce same output every time

I am trying to build a JSON to Excel converter in the Go language. Here is some example JSON:

[{
    "App": "Instagram",
    "Company": "Facebook",
    "Category": "Social Media"
  },
  {
    "App": "WeChat",
    "Company": "Tencent",
    "Category": "Social Media"
  }
}]

I am not using structure here, as Data in JSON can be random, hence using interface to store data, unmarshaling JSON and then using assertion technique tried to extract data, but as data structure used as map, hence while iterating data columns are not stored in sequential manners in excel sheet, with every output columns sequence is random hence data stored inside excel sheet is not appropriate. As data is not fixed type in JSON can not use structure in go program.

With the below code, I am able to get column and set column in Excel as App, Company, Category. But with every iterations sequence of columns is not same, which should be as further step is to feed the value, but as traversing map always gives random output sequence, hence could not move further.

How to handle this part?

file, err  := ioutil.ReadFile("test.json")
 if err != nil {
    panic(err)
 }
 var data interface{}
 json.Unmarshal(file, &data) // reading all json data
 fmt.Println(data)
 t, ok := data.([]interface{})  // assertion Interface
 _ = ok
 fmt.Printf("%[1]v  %[1]T\n", t)  //map[string]interface {}
 myMap := t[0]   // aim here to get APP, Company and Category which will be the column name of Excel sheet 
columnData, _  := myMap.(map[string]interface {})  // extract the underlying concrete data from interface
keys := make([]string, 0, len(columnData)) // creating and initializing slice to store column 
for k := range columnData {
     fmt.Printf("%[1]v %[1]T\n", k)
     keys = append(keys, k)
  }

 xlsx := excelize.NewFile()
 sheetName := "Sheet1"
 xlsx.SetSheetName(xlsx.GetSheetName(1), sheetName)
 c := 'A'
 asciiValue := int(c)
 var a string
 for i := 0; i < len(keys); i++ {
    a = string(asciiValue)
    xlsx.SetCellValue(sheetName, a + "1", keys[i])
    asciiValue++
}
err := xlsx.SaveAs("./Onkar.xlsx")
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println("Excel file generated sucessfully")

Upvotes: 2

Views: 1918

Answers (1)

By looking the code, you are using for :=range, with on maps, does not guarantee order, so since order is important to you i suggest you use, sort the keys. Here you can find more info. How to iterate through a map in Golang in order?

Upvotes: 3

Related Questions