在现代业务场景中,JSON 是 API 响应、配置文件、数据库导出中最常用的数据格式。但将结构化数据呈现给非技术人员或用于正式报告时,直接展示 JSON 原文并不友好。手动复制粘贴效率低、易出错。本文介绍如何使用 Python 和 Free Spire.Doc for Python 库,自动将 JSON 数据写入 Word 文档,支持段落、表格、嵌套数据合并单元格,以及从文件批量生成多表格。
首先安装依赖库:- pip install spire.doc.free
复制代码
一、读取 JSON 数据并写入 Word 段落
当 JSON 为简单键值对结构时,可以用段落形式输出每个字段,适合生成配置说明、信息卡片等。- import json
- from spire.doc import *
- from spire.doc.common import *
- json_data = {
- "项目名称": "智慧城市数据平台",
- "版本": "v3.2.1",
- "负责人": "张伟",
- "状态": "进行中",
- "启动日期": "2024-01-15",
- "预计完成": "2024-12-31",
- "技术栈": "Python, Kafka, PostgreSQL, Docker",
- "描述": "基于物联网传感器数据构建城市级实时监控与分析平台"
- }
- document = Document()
- section = document.AddSection()
- # 添加标题
- title = section.AddParagraph()
- title_text = title.AppendText("项目信息概览")
- title.Format.HorizontalAlignment = HorizontalAlignment.Center
- title_text.CharacterFormat.FontName = "微软雅黑"
- title_text.CharacterFormat.Bold = True
- title_text.CharacterFormat.FontSize = 18
- section.AddParagraph()
- # 遍历键值对写入段落
- for key, value in json_data.items():
- para = section.AddParagraph()
- text_range = para.AppendText(f"{key}:{value}")
- text_range.CharacterFormat.FontSize = 12
- text_range.CharacterFormat.FontName = "微软雅黑"
- document.SaveToFile("ProjectInfo.docx", FileFormat.Docx)
- document.Close()
复制代码 说明:Document() 创建文档,AddSection() 添加节,AppendText() 写入内容,通过 CharacterFormat 设置字体字号。适合数据量少、扁平的 JSON。
二、将 JSON 数组数据写入 Word 表格
2.1 基础员工信息表- import json
- from spire.doc import *
- from spire.doc.common import *
- json_employees = [
- {"姓名": "张三", "部门": "技术部", "职位": "高级工程师", "入职日期": "2020-03-15", "薪资": "25000"},
- {"姓名": "李四", "部门": "市场部", "职位": "市场经理", "入职日期": "2019-06-20", "薪资": "22000"},
- {"姓名": "王五", "部门": "人力资源部", "职位": "HR专员", "入职日期": "2021-01-10", "薪资": "15000"},
- {"姓名": "赵六", "部门": "财务部", "职位": "财务主管", "入职日期": "2018-11-05", "薪资": "20000"},
- {"姓名": "钱七", "部门": "技术部", "职位": "产品经理", "入职日期": "2020-08-22", "薪资": "23000"}
- ]
- document = Document()
- section = document.AddSection()
- title = section.AddParagraph()
- title_text = title.AppendText("员工信息表")
- title.Format.HorizontalAlignment = HorizontalAlignment.Center
- title_text.CharacterFormat.Bold = True
- title_text.CharacterFormat.FontSize = 18
- section.AddParagraph()
- headers = list(json_employees[0].keys())
- table = section.AddTable(True)
- table.ResetCells(len(json_employees) + 1, len(headers))
- # 表头行
- header_row = table.Rows[0]
- header_row.IsHeader = True
- header_row.Height = 30
- header_row.HeightType = TableRowHeightType.Exactly
- for i, header in enumerate(headers):
- cell = header_row.Cells[i]
- cell.CellFormat.VerticalAlignment = VerticalAlignment.Middle
- cell.CellFormat.Shading.BackgroundPatternColor = Color.get_Gray()
- paragraph = cell.AddParagraph()
- paragraph.Format.HorizontalAlignment = HorizontalAlignment.Center
- text_range = paragraph.AppendText(header)
- text_range.CharacterFormat.Bold = True
- text_range.CharacterFormat.FontSize = 12
- # 数据行
- for row_idx, employee in enumerate(json_employees):
- data_row = table.Rows[row_idx + 1]
- data_row.Height = 25
- data_row.HeightType = TableRowHeightType.Exactly
- for col_idx, key in enumerate(headers):
- cell = data_row.Cells[col_idx]
- cell.CellFormat.VerticalAlignment = VerticalAlignment.Middle
- paragraph = cell.AddParagraph()
- paragraph.Format.HorizontalAlignment = HorizontalAlignment.Center
- paragraph.AppendText(str(employee[key]))
- # 隔行变色
- for row_idx in range(1, table.Rows.Count):
- if row_idx % 2 == 0:
- row = table.Rows[row_idx]
- for i in range(row.Cells.Count):
- row.Cells[i].CellFormat.Shading.BackgroundPatternColor = Color.get_LightBlue()
- document.SaveToFile("EmployeeJsonTable.docx", FileFormat.Docx)
- document.Close()
复制代码 关键点:list(json_employees[0].keys()) 动态提取表头,ResetCells() 初始化表格,表头灰色背景粗体,数据居中并隔行变色。
2.2 带样式的季度销售表格- import json
- from spire.doc import *
- from spire.doc.common import *
- json_sales = [
- {"产品名称": "笔记本电脑", "第一季度": "120万", "第二季度": "135万", "第三季度": "150万", "第四季度": "168万"},
- {"产品名称": "平板电脑", "第一季度": "85万", "第二季度": "92万", "第三季度": "105万", "第四季度": "118万"},
- {"产品名称": "智能手机", "第一季度": "200万", "第二季度": "220万", "第三季度": "245万", "第四季度": "280万"},
- {"产品名称": "智能手表", "第一季度": "45万", "第二季度": "52万", "第三季度": "60万", "第四季度": "72万"}
- ]
- document = Document()
- section = document.AddSection()
- title = section.AddParagraph()
- title_text = title.AppendText("2024年度季度销售报表")
- title.Format.HorizontalAlignment = HorizontalAlignment.Center
- title_text.CharacterFormat.Bold = True
- title_text.CharacterFormat.FontSize = 18
- section.AddParagraph()
- headers = list(json_sales[0].keys())
- table = section.AddTable(True)
- table.ResetCells(len(json_sales) + 1, len(headers))
- for i, header in enumerate(headers):
- cell = table.Rows[0].Cells[i]
- cell.CellFormat.VerticalAlignment = VerticalAlignment.Middle
- cell.CellFormat.Shading.BackgroundPatternColor = Color.get_DarkSeaGreen()
- paragraph = cell.AddParagraph()
- paragraph.Format.HorizontalAlignment = HorizontalAlignment.Center
- text_range = paragraph.AppendText(header)
- text_range.CharacterFormat.Bold = True
- text_range.CharacterFormat.FontSize = 12
- text_range.CharacterFormat.TextColor = Color.get_White()
- for row_idx, item in enumerate(json_sales):
- for col_idx, key in enumerate(headers):
- cell = table.Rows[row_idx + 1].Cells[col_idx]
- cell.CellFormat.VerticalAlignment = VerticalAlignment.Middle
- paragraph = cell.AddParagraph()
- paragraph.Format.HorizontalAlignment = HorizontalAlignment.Center
- paragraph.AppendText(str(item[key]))
- table.ApplyStyle(DefaultTableStyle.ColorfulListAccent1)
- table.Format.Borders.BorderType = BorderStyle.Single
- table.Format.Borders.LineWidth = 1.0
- table.Format.Borders.Color = Color.get_Black()
- document.SaveToFile("SalesJsonReport.docx", FileFormat.Docx)
- document.Close()
复制代码 ApplyStyle() 快速应用预设样式,Format.Borders 自定义边框。深绿色表头配白色字增强层次。
三、处理嵌套 JSON 数据:合并单元格表格
实际数据常含嵌套结构,如产品分类。通过 ApplyVerticalMerge 合并分类列单元格实现层级关系。- import json
- from spire.doc import *
- from spire.doc.common import *
- json_catalog = {
- "电子产品": [
- {"型号": "SP-2024", "名称": "智能手机", "价格": "3999元"},
- {"型号": "TB-2024", "名称": "平板电脑", "价格": "2999元"}
- ],
- "家居用品": [
- {"型号": "RC-2024", "名称": "电饭煲", "价格": "599元"},
- {"型号": "AP-2024", "名称": "空气净化器", "价格": "1299元"}
- ],
- "办公用品": [
- {"型号": "PR-2024", "名称": "打印机", "价格": "1599元"},
- {"型号": "SH-2024", "名称": "碎纸机", "价格": "399元"}
- ]
- }
- document = Document()
- section = document.AddSection()
- title = section.AddParagraph()
- title_text = title.AppendText("产品目录")
- title.Format.HorizontalAlignment = HorizontalAlignment.Center
- title_text.CharacterFormat.Bold = True
- title_text.CharacterFormat.FontSize = 18
- section.AddParagraph()
- total_rows = 1 + sum(len(items) for items in json_catalog.values())
- col_count = 4 # 分类、型号、名称、价格
- table = section.AddTable(True)
- table.ResetCells(total_rows, col_count)
- headers = ["分类", "型号", "名称", "价格"]
- for i, header in enumerate(headers):
- cell = table.Rows[0].Cells[i]
- cell.CellFormat.VerticalAlignment = VerticalAlignment.Middle
- cell.CellFormat.Shading.BackgroundPatternColor = Color.get_Gray()
- paragraph = cell.AddParagraph()
- paragraph.Format.HorizontalAlignment = HorizontalAlignment.Center
- text_range = paragraph.AppendText(header)
- text_range.CharacterFormat.Bold = True
- current_row = 1
- for category, items in json_catalog.items():
- start_row = current_row
- for item in items:
- row = table.Rows[current_row]
- row.Cells[1].AddParagraph().AppendText(item["型号"])
- row.Cells[2].AddParagraph().AppendText(item["名称"])
- row.Cells[3].AddParagraph().AppendText(item["价格"])
- current_row += 1
- # 写入分类名并合并单元格
- table.Rows[start_row].Cells[0].AddParagraph().AppendText(category)
- if len(items) > 1:
- table.ApplyVerticalMerge(0, start_row, start_row + len(items) - 1)
- table.Rows[start_row].Cells[0].CellFormat.VerticalAlignment = VerticalAlignment.Middle
- table.ApplyStyle(DefaultTableStyle.ColorfulGridAccent3)
- document.SaveToFile("CatalogJsonTable.docx", FileFormat.Docx)
- document.Close()
复制代码 ApplyVerticalMerge(列索引, 起始行, 结束行) 垂直合并同一分类的单元格,更直观展示层级。
四、从 JSON 文件批量写入多个表格
同一 JSON 可包含多组数据集,循环创建各自独立的表格,适合生成汇总报告。- import json
- from spire.doc import *
- from spire.doc.common import *
- json_file_data = {
- "员工信息": [
- {"姓名": "张三", "部门": "技术部", "职位": "工程师"},
- {"姓名": "李四", "部门": "市场部", "职位": "经理"},
- {"姓名": "王五", "部门": "财务部", "职位": "会计"}
- ],
- "项目列表": [
- {"项目": "数据平台", "状态": "进行中", "进度": "75%"},
- {"项目": "移动应用", "状态": "已完成", "进度": "100%"},
- {"项目": "AI模型", "状态": "规划中", "进度": "10%"}
- ],
- "设备清单": [
- {"设备": "服务器A", "IP": "192.168.1.10", "状态": "运行中"},
- {"设备": "服务器B", "IP": "192.168.1.11", "状态": "维护中"},
- {"设备": "交换机", "IP": "192.168.1.1", "状态": "运行中"}
- ]
- }
- document = Document()
- section = document.AddSection()
- doc_title = section.AddParagraph()
- doc_title_text = doc_title.AppendText("数据汇总报告")
- doc_title.Format.HorizontalAlignment = HorizontalAlignment.Center
- doc_title_text.CharacterFormat.Bold = True
- doc_title_text.CharacterFormat.FontSize = 22
- section.AddParagraph()
- for table_name, records in json_file_data.items():
- # 每个表格的标题
- table_title = section.AddParagraph()
- table_title_text = table_title.AppendText(table_name)
- table_title_text.CharacterFormat.Bold = True
- table_title_text.CharacterFormat.FontSize = 14
- section.AddParagraph()
- headers = list(records[0].keys())
- table = section.AddTable(True)
- table.ResetCells(len(records) + 1, len(headers))
- for i, header in enumerate(headers):
- cell = table.Rows[0].Cells[i]
- cell.CellFormat.VerticalAlignment = VerticalAlignment.Middle
- cell.CellFormat.Shading.BackgroundPatternColor = Color.get_Gray()
- paragraph = cell.AddParagraph()
- paragraph.Format.HorizontalAlignment = HorizontalAlignment.Center
- text_range = paragraph.AppendText(header)
- text_range.CharacterFormat.Bold = True
- for row_idx, record in enumerate(records):
- for col_idx, key in enumerate(headers):
- cell = table.Rows[row_idx + 1].Cells[col_idx]
- cell.CellFormat.VerticalAlignment = VerticalAlignment.Middle
- paragraph = cell.AddParagraph()
- paragraph.Format.HorizontalAlignment = HorizontalAlignment.Center
- paragraph.AppendText(str(record[key]))
- table.ApplyStyle(DefaultTableStyle.ColorfulListAccent1)
- table.AutoFit(AutoFitBehaviorType.AutoFitToWindow)
- section.AddParagraph() # 表格间空行
- document.SaveToFile("JsonDataReport.docx", FileFormat.Docx)
- document.Close()
复制代码 实际使用 json.load() 从 .json 文件读取数据替换示例字典。AutoFitToWindow 让表格自适应页面宽度。
关键类与方法一览
- Document:Word 文档对象,支持创建、加载、保存。
- AddSection():添加节作为内容容器。
- AddTable():在节中创建表格。
- ResetCells(rows, cols):初始化表格行列。
- ApplyStyle(DefaultTableStyle.*):应用预设样式(如 ColorfulListAccent1、ColorfulGridAccent3)。
- ApplyVerticalMerge(column, startRow, endRow):垂直合并单元格。
- AutoFit(AutoFitBehaviorType.AutoFitToWindow):自动调整表格宽度。
- Rows/ Cells:行/列集合。
- CellFormat.Shading.BackgroundPatternColor:单元格背景色。
- CellFormat.VerticalAlignment:垂直对齐。
- AddParagraph() / AppendText():单元格或段落中添加文本。
- SaveToFile(path, FileFormat.Docx):保存为 .docx。
以上方法均可灵活组合,满足从简单段落到复杂嵌套表格的自动化生成需求。代码可直接用于 API 报告、配置文档、数据导出等场景。 |