python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python JSON转CSV

Python代码如何轻松将JSON转换为CSV格式

作者:E-iceblue

JSON 常用于存储和交换结构化数据,那么怎样才能将 JSON 转换为 CSV,本文将介绍 JSON 的基本结构以及如何使用 Spire.XLS for Python 将普通 JSON 和嵌套 JSON 转换为 CSV 文件,感兴趣的小伙伴可以了解下

JSON 常用于存储和交换结构化数据,例如 API 返回的数据、应用程序的配置以及各类业务记录。当需要将这些数据导入 Excel 进行查看、筛选或分析时,CSV 是一种实用的选择。它采用简单的行列结构,兼容多种表格软件,也方便在不同系统之间传递数据。

不过,JSON 和 CSV 的数据结构并不完全相同。对于简单的 JSON 对象数组,可以直接将字段和值映射到表格中;如果 JSON 包含嵌套对象或数组,就需要先处理这些层级关系,才能得到符合预期的 CSV 文件。

那么,怎样才能将 JSON 转换为 CSV?本文将介绍 JSON 的基本结构,以及如何使用 Spire.XLS for Python 将普通 JSON 和嵌套 JSON 转换为 CSV 文件,并解答转换过程中常见的问题。

理解 JSON 数据结构

在开始转换之前,有必要了解 JSON 的几种常见结构,因为它们会直接影响数据在 CSV 中的排列方式。

JSON 对象数组

这是最常见、也最适合直接转换为 CSV 的结构。例如,一个保存员工信息的 JSON 文件可能包含以下内容:

[
    {
        "name": "Alice",
        "department": "HR",
        "salary": 5000
    },
    {
        "name": "Bob",
        "department": "IT",
        "salary": 6500
    },
    {
        "name": "Charlie",
        "department": "Sales",
        "salary": 5800
    }
]

在这个例子中,最外层是一个数组,其中的每个元素都是一个 JSON 对象。每个对象都包含 name、department 和 salary 三个字段。

转换为 CSV 时,可以将这些字段作为列名,每个对象作为一行记录,得到如下结果:

name,department,salary
Alice,HR,5000
Bob,IT,6500
Charlie,Sales,5800

这种转换方式比较直接,因为所有记录都遵循相同的字段结构。

嵌套 JSON 对象

如果 JSON 对象中还包含其他对象,情况就会有所不同。例如:

[
    {
        "name": "Alice",
        "department": {
            "name": "Engineering",
            "location": "Singapore"
        },
        "skills": ["Python", "SQL", "Excel"]
    }
]

这里的 department 是一个嵌套对象,skills 则是一个数组。

CSV 没有与 JSON 对象和数组完全对应的层级结构,因此不能简单地将所有内容都当作普通字段处理。对于这类数据,可以先将嵌套对象展开为独立字段,并根据需要将数组转换为字符串,再写入 CSV。

了解这两种结构后,就可以根据实际数据选择合适的转换方法。

使用 Spire.XLS for Python 将 JSON 转换为 CSV

Spire.XLS for Python 是一款用于 Excel 文件处理的 Python 库。借助它,可以创建工作簿、向单元格写入数据,并将工作表导出为 CSV 文件。对于 JSON 转 CSV 任务,可以先使用 Python 的 json 模块读取数据,再将字段和值写入 Spire.XLS 创建的工作表,最后保存为 CSV。

将普通 JSON 转换为 CSV

假设有一个名为 data-zh.json 的文件,其中保存了多个具有相同字段结构的 JSON 对象。现在,希望将这些记录转换为 CSV 文件,以便在 Excel 中查看和处理。

可以使用以下 Python 代码完成转换:

import json
from spire.xls import *

# 加载 JSON 数据
with open("data-zh.json", encoding="utf-8") as f:
    data = json.load(f)

# 创建工作簿并获取工作表
workbook = Workbook()
sheet = workbook.Worksheets[0]

# 从 JSON 顶层对象中提取所有键作为表头
headers = list(data[0].keys())

# 将表头写入工作表的第一行
for col, header in enumerate(headers, start=1):
    sheet.Range[1, col].Value = header

# 将每个 JSON 对象的值填入后续行
for row_index, item in enumerate(data, start=2):
    for col_index, key in enumerate(headers, start=1):
        value = item.get(key, "")
        sheet.Range[row_index, col_index].Value = (
            str(value) if value is not None else ""
        )

# 保存为 CSV 文件
sheet.SaveToFile("output.csv", ",", Encoding.get_UTF8())

# 释放资源
workbook.Dispose()

这段代码主要完成四项工作。

第一步:读取 JSON 文件。

使用 Python 内置的 json 模块读取 data-zh.json。json.load() 会将文件内容解析为 Python 对象,方便后续访问其中的字段和值。

第二步:创建工作簿并设置表头。

通过 Workbook() 创建一个新的工作簿,并使用 workbook.Worksheets[0] 获取第一个工作表。

接下来,list(data[0].keys()) 提取第一个 JSON 对象中的所有键,并将它们作为 CSV 的列名。循环中的 sheet.Range[1, col].Value 则用于将这些表头写入工作表的第一行。

第三步:将 JSON 数据写入单元格。

外层循环遍历每个 JSON 对象,内层循环根据表头依次获取对应的值,并将其写入工作表。

item.get(key, "") 可以在指定字段不存在时返回空字符串;如果字段的值为 None,代码也会将其转换为空字符串。对于其他值,代码会先转换为字符串再写入单元格。

第四步:导出 CSV 文件。

最后,调用 sheet.SaveToFile() 保存工作表。参数 "," 指定使用逗号作为分隔符,Encoding.get_UTF8() 则指定 UTF-8 编码。运行代码后,就能在指定的输出路径下获得 output.csv 文件。如果输入数据与前面的示例一致,生成的 CSV 就会按照字段和记录的对应关系排列。

需要注意的是,这段代码默认 JSON 文件包含至少一个对象,而且所有对象都具有相同的字段结构。如果后续对象包含第一个对象中没有的字段,这些额外字段不会自动加入表头。对于字段不一致的数据,需要先统一表头,再执行转换。

将嵌套 JSON 转换为 CSV

如果 JSON 包含嵌套对象或数组,直接提取第一层字段可能无法得到理想的表格结构。这时,可以先对数据进行扁平化处理,再将处理后的结果写入工作表。

继续使用前面的示例,原始 JSON 数据如下:

[
    {
        "name": "Alice",
        "department": {
            "name": "Engineering",
            "location": "Singapore"
        },
        "skills": ["Python", "SQL", "Excel"]
    },
    {
        "name": "Bob",
        "department": {
            "name": "IT",
            "location": "Tokyo"
        },
        "skills": ["Java", "SQL"]
    }
]

这里,department 包含部门名称和所在地,skills 则保存了每位员工掌握的技能。如果直接将这些嵌套数据写入表格,就需要先确定如何表示它们。

下面的代码使用一个 flatten_json() 函数处理这些字段,再将扁平化后的数据导出为 CSV。

import json
from spire.xls import *

# 扁平化嵌套 JSON
def flatten_json(item):
    flat = {}

    for key, value in item.items():
        if isinstance(value, dict):
            # 将嵌套对象展开为“父键.子键”
            for sub_key, sub_value in value.items():
                flat[f"{key}.{sub_key}"] = sub_value

        elif isinstance(value, list):
            # 使用分号连接数组元素
            flat[key] = "; ".join(map(str, value))

        else:
            flat[key] = value

    return flat


# 加载 JSON 数据
with open("nested.json", encoding="utf-8") as f:
    data = json.load(f)

# 扁平化每个 JSON 对象
flat_data = [flatten_json(item) for item in data]

# 创建工作簿并获取工作表
workbook = Workbook()
sheet = workbook.Worksheets[0]

# 从扁平化数据中提取表头
headers = list(flat_data[0].keys())

for col, header in enumerate(headers, start=1):
    sheet.Range[1, col].Value = header

# 将扁平化数据写入工作表
for row_index, item in enumerate(flat_data, start=2):
    for col_index, key in enumerate(headers, start=1):
        value = item.get(key, "")
        sheet.Range[row_index, col_index].Value = (
            str(value) if value is not None else ""
        )

# 保存为 CSV 文件
sheet.SaveToFile("output.csv", ",", Encoding.get_UTF8())

# 释放资源
workbook.Dispose()

与前一个示例相比,这段代码增加了数据预处理步骤。关键在于 flatten_json() 函数,它会根据不同的值类型采用不同的处理方式。

完成扁平化后,代码会像前一个示例一样提取表头、写入单元格,并使用 Spire.XLS 导出 CSV。由于这一部分的工作簿操作与普通 JSON 转换基本相同,因此不需要再逐步解释相同的 API。

转换后,CSV 文件的内容如下:

name,department.name,department.location,skills
Alice,Engineering,Singapore,Python; SQL; Excel
Bob,IT,Tokyo,Java; SQL

可以看到,原本位于 department 对象中的字段现在成为独立的列,而 skills 数组则被合并为一个字符串。这样,原本具有层级关系的数据就能以二维表格的形式保存。

需要注意的是,这里的扁平化函数只展开一层嵌套对象,并将数组合并为字符串。如果 JSON 包含更深层的嵌套结构,或者数组中包含其他对象,就需要进一步调整处理逻辑。此外,这段代码同样使用第一个对象的键生成表头,因此适用于各对象具有相同字段结构的情况。

JSON 转 CSV 的常见问题

在实际转换过程中,除了数据结构本身,还有一些细节值得注意。提前了解这些问题,可以减少导出结果与预期不符的情况。

JSON 转 CSV 后中文乱码怎么办?

如果 JSON 文件包含中文,读取文件时可以通过 encoding="utf-8" 指定 UTF-8 编码,避免因读取编码不一致而出现乱码。

导出时,示例代码使用 Encoding.get_UTF8() 指定 CSV 文件的编码。如果使用 Excel 打开生成的 CSV 后仍然出现乱码,可以尝试使用支持 UTF-8 BOM 的导出方式,或者通过 Excel 的数据导入功能明确指定文件编码。

需要注意,文件本身采用 UTF-8 编码,并不意味着所有软件都会自动以正确的编码方式打开它。 如果 CSV 在其他编辑器中显示正常,但在某些 Excel 环境中出现乱码,问题可能出在文件的打开方式,而不一定是转换过程出错。

JSON 对象包含不同的字段怎么办?

前面的示例使用第一个 JSON 对象的键生成表头,因此默认所有对象的字段结构一致。但在实际数据中,不同对象可能包含不同的字段。例如:

[
    {
        "name": "Alice",
        "age": 28
    },
    {
        "name": "Bob",
        "department": "IT"
    }
]

如果直接运行前面的代码,department 不会被添加到表头中,因此 Bob 的部门信息可能被遗漏。

对于这种情况,可以在写入工作表之前遍历所有对象,收集全部字段并统一生成表头。之后,每条记录都按照统一的字段顺序写入;如果某个对象缺少相应字段,就填入空值。这样可以避免因字段不一致而丢失数据。不过,如果不同记录包含含义相同但名称不同的字段,还需要先对字段名称进行统一处理。

多层嵌套 JSON 应该怎么转换?

前面的 flatten_json() 只处理一层嵌套对象,并将数组元素合并为字符串。这种方式适用于结构相对简单的数据,但并不能直接处理任意深度的嵌套 JSON。如果数据包含多层对象,可以使用递归方式展开字段;如果数组中包含多个对象,则需要进一步决定是将对象展开为多个字段、将数组单独保存,还是转换为 JSON 字符串。

具体采用哪种方式,取决于后续如何使用这些数据。例如,如果目标是生成便于查看的简单表格,将部分数组合并为字符串可能已经足够;如果需要保留复杂的数据关系,则可能需要拆分成多个 CSV 文件,或者继续使用 JSON 等能够表示层级结构的格式。

总结

将 JSON 转换为 CSV 时,最重要的是根据原始数据的结构选择合适的处理方式。对于字段一致的 JSON 对象数组,可以直接提取表头并将数据写入工作表,再使用 Spire.XLS for Python 导出 CSV;对于包含嵌套对象或数组的数据,则可以先进行扁平化处理,再完成转换。如果还需要处理字段不一致、中文编码或多层嵌套等情况,就应当在导出之前补充相应的数据预处理逻辑。通过合理组织数据结构和转换流程,可以生成更符合实际使用需求的 CSV 文件。

到此这篇关于Python代码如何轻松将JSON转换为CSV格式的文章就介绍到这了,更多相关Python JSON转CSV内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文