Home > Back-end >  Json to excel using python
Json to excel using python

Time:10-10

Json code:Below we have json data format which I am pulling from site using API

response={
      "result": [
        {
          "id": "1000",
          "title": "Fishing Team View",
          "sharedWithOrganization": True,
          "ownerId": "324425",
          "sharedWithUsers": ["1223","w2qee3"],
          "filters": [
            {
              "field": "tag5",
              "comparator": "==",
              "value": "fishing"
            }
          ]
        },
        {
          "id": "2000",
          "title": "Farming Team View",
          "sharedWithOrganization": False,
          "ownerId": "00000",
          "sharedWithUsers": [
            "00000",
            "11111"
          ],
          "filters": [
            {
              "field": "tag5",
              "comparator": "!@",
              "value": "farming"
            }
          ]
        }
      ]
    }

Python Code : I am using below code to parse the json data but I am unable to filters into different column specially filters part into separate column like Inside filter i a want to make field , comparator separate column

    records=[]
    for data in response['result']:
        id = data['id']
        title = data['title']
        sharedWithOrganization = data['sharedWithOrganization']
        ownerId = data['ownerId'] 
        sharedWithUsers = '|'.join(data['sharedWithUsers'])
        filters = data['filters']
        print(filters)
        records.append([id,title,sharedWithOrganization,ownerId,sharedWithUsers])
        
        #print(records)
    
        
        
    ExcelApp = win32.Dispatch('Excel.Application')
    ExcelApp.Visible= True
    
    #creating excel and renaming sheet
    
    wb = ExcelApp.Workbooks.Add()
    ws= wb.Worksheets(1)
    ws.Name="Get_Views"
        
        
        
    #assigning header value
    header_labels=('Id','Title','SharedWithOrganization','OwnerId','sharedWithUsers')
    for index,val in enumerate(header_labels):
        ws.Cells(1, index 1).Value=val
        
        
        
    row_tracker = 2
    column_size = len(header_labels)
    
    for row in records:
        ws.Range(ws.cells(row_tracker,1),ws.cells(row_tracker,column_size)).value = row
        row_tracker  =1
        
    

enter image description here

I am doing API pull i am getting this kind of format and I am passing that .json format to python to achieve the data into excel but I am unable to filters list data into separate column can you please help me with

CodePudding user response:

Try:

df = pd.Series(response).explode().apply(pd.Series).reset_index(drop=True)
df = df.join(df['filters'].explode().apply(pd.Series)).drop(columns=['filters'])
df['sharedWithUsers'] = df['sharedWithUsers'].str.join('|')

Output:

     id              title  sharedWithOrganization ownerId sharedWithUsers field comparator    value
0  1000  Fishing Team View                    True  324425     1223|w2qee3  tag5         ==  fishing
1  2000  Farming Team View                   False   00000     00000|11111  tag5         !@  farming

CodePudding user response:

You can use pd.json_normalize to normalize the Json: Specify different parameters record_path= to read up to different depths for fields under tag result and tag filters respectively.

Then, join the 2 resultant dataframes together, as follows:

# read fields under tag `result`
df_result = pd.json_normalize(response, record_path=['result'])

# read fields under tag `filters` within `result`
df_filters = pd.json_normalize(response, record_path=['result', 'filters'])

# Join 2 resultant dataframes together
df = df_result.join(df_filters).drop('filters', axis=1)

# Join fields in `sharedWithUsers`
df['sharedWithUsers'] = df['sharedWithUsers'].str.join('|')

Result:

print(df)

     id              title  sharedWithOrganization ownerId sharedWithUsers field comparator    value
0  1000  Fishing Team View                    True  324425     1223|w2qee3  tag5         ==  fishing
1  2000  Farming Team View                   False   00000     00000|11111  tag5         !@  farming

CodePudding user response:

You can see how I did it below because that returns a list you can select the first item of the list with [0], like datafield["filters"][0]["field"], also you can create a csv file and import that in excel instead.

import json
import csv

rows = []
headers = ["Id", "Title", "SharedWithOrganization", "OwnerId","SharedWithUsers","field", "comparator", "value"]

for datafield in response["result"] :
    susers = ""
    for u in datafield["sharedWithUsers"] :
        susers = susers   u   "|"
    susers = susers[:-1]
    if datafield["sharedWithOrganization"] :
        boolval = "TRUE"
    else :
        boolval = "FALSE"
    rows.append([datafield["id"], datafield["title"], boolval,     datafield["ownerId"], susers, datafield["filters"][0]["field"], datafield["filters"][0]["comparator"], datafield["filters"][0]["value"]])


with open('responseOutput.csv', 'w', encoding='UTF8', newline='') as f:
    writer = csv.writer(f)

    # write the header
    writer.writerow(headers)

    # write multiple rows
    writer.writerows(rows)

CodePudding user response:

The code below generates out.csv which can be opened by Excel.
Note that the code does not require any external library.

import csv

response={
      "result": [
        {
          "id": "1000",
          "title": "Fishing Team View",
          "sharedWithOrganization": True,
          "ownerId": "324425",
          "sharedWithUsers": ["1223","w2qee3"],
          "filters": [
            {
              "field": "tag5",
              "comparator": "==",
              "value": "fishing"
            }
          ]
        },
        {
          "id": "2000",
          "title": "Farming Team View",
          "sharedWithOrganization": False,
          "ownerId": "00000",
          "sharedWithUsers": [
            "00000",
            "11111"
          ],
          "filters": [
            {
              "field": "tag5",
              "comparator": "!@",
              "value": "farming"
            }
          ]
        }
      ]
    }
fields = ['id','title','sharedWithOrganization','ownerId','sharedWithUsers']
data = []
for entry in response['result']:
  data.append(['|'.join(entry[f]) if isinstance(entry[f],list) else entry[f] for f in fields])
with open('out.csv','w') as f:
  writer = csv.writer(f)
  writer.writerow(fields)
  for line in data:
    writer.writerow(line)

out.csv

id,title,sharedWithOrganization,ownerId,sharedWithUsers
1000,Fishing Team View,True,324425,1223|w2qee3
2000,Farming Team View,False,00000,00000|11111

CodePudding user response:

Using DictWriter you can write required columns into .csv file which you can open in Excel.

Code:

from csv import DictWriter

response = { ... }
with open("result.csv", "w", newline="") as f:
    writer = DictWriter(
        f,
        ("id", "title", "sharedWithOrganization", "ownerId", "sharedWithUsers"),
        extrasaction="ignore"
    )
    writer.writeheader()
    for obj in response["result"]:
        writer.writerow({**obj, "sharedWithUsers": "|".join(obj["sharedWithUsers"])})

Or you can use csv.writer (will consume a bit less memory as doesn't copy all fields):

import csv
from operator import itemgetter

response = { ... }

keys = "id", "title", "sharedWithOrganization", "ownerId", "sharedWithUsers"
getter = itemgetter(*keys)
with open("result.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(keys)
    for obj in response["result"]:
        row = getter(obj)
        writer.writerow(row[:-1]   ("|".join(row[-1]),))
  • Related