问题:如何将apidoc生成的html格式的接口文档转换成doc格式的接口文档?
解决:通过网页抓取,然后生成doc文档
语言:
python
模块:
requests==2.18.4
python-docx==0.8.7
方法:
#!.venv/bin/python
# -*- coding: utf-8 -*-
"""
根据apidoc生成的接口文档url生成接口文档的doc版本
"""
import os
import json
import requests
from docx import Document, shared
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT, WD_ALIGN_VERTICAL
from docx.shared import Cm
# 运行前修改这两个参数
url_prefix = '/campus'
api_url = 'http://10.16.32.80/campus/static/apidoc/'
if 'index' in api_url:
api_url = '/'.join(api_url.split('/')[:-1])
project_url = '%sapi_project.js' % api_url
data_url = '%sapi_data.js' % api_url
"""
http://10.16.32.80/cockpit/static/apidoc/api_project.js?v=1594365925675
http://10.16.32.80/cockpit/static/apidoc/api_data.js?v=1594365925675
"""
# 基础数据
r = requests.get(project_url)
project_html = r.text
project_data = json.loads(project_html[7:-3])
# 接口数据
dr = requests.get(data_url)
data_html = dr.text
api_data = json.loads(data_html[7:-3])
apis = api_data['api']
def paragraph_init(doc, content):
paragraph = doc.add_paragraph(content)
ph_format = paragraph.paragraph_format
ph_format.space_after = shared.Pt(0)
ph_format.line_spacing = 1.5
return paragraph
project_name = project_data['title']
# 将数据保存到doc文档中
# 文档对象
document = Document()
document.styles['Normal'].font.name = u'宋体'
document.styles['Normal'].font.color.rgb = shared.RGBColor(0, 0, 0)
document.styles['Normal'].font.size = shared.Pt(10)
# 项目名
p_title = paragraph_init(document, '')
p_title.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
r_title = p_title.add_run(project_name)
r_title.font.bold = True
r_title.font.name = u'黑体'
r_title.font.size = shared.Pt(18)
# 副标题
p_title2 = paragraph_init(document, '')
p_title2.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
r_title2 = p_title2.add_run('接口文档')
r_title2.font.bold = True
r_title2.font.name = u'黑体'
r_title2.font.size = shared.Pt(18)
# 增加接口信息
group_title = '' # 模块名称
group_num = 0 # 模块序号
title_num = 0 # 模块内接口序号
for api in apis:
# 模块名
if group_title != api['groupTitle']:
group_title = api['groupTitle']
group_num = group_num + 1
title_num = 0
group = '%s、%s' % (group_num, group_title)
p_group = paragraph_init(document, '')
group_p = p_group.add_run(group)
group_p.font.bold = True
group_p.font.name = u'黑体'
group_p.font.size = shared.Pt(14)
# 接口名
title_num = title_num + 1
title = '%d.%d %s' % (group_num, title_num, api['title'])
p_title = paragraph_init(document, '')
title_p = p_title.add_run(title)
title_p.font.bold = True
title_p.font.name = u'黑体'
title_p.font.size = shared.Pt(12)
# 接口协议
atype = '协议:HTTPS %s 短链接' % api['type'].upper()
paragraph_init(document, atype)
# 方向
paragraph_init(document, '方向:用户—>服务器')
# 接口URL
url = 'URL:%s%s' % (url_prefix, api['url'])
paragraph_init(document, url)
# 功能描述
if 'description' in api:
desc = '功能描述:%s' % api['description'][3:-4]
paragraph_init(document, desc)
# 请求参数
if 'parameter' in api:
paragraph_init(document, '请求参数:')
pars = api['parameter']['fields']['Parameter']
table = document.add_table(rows=1, cols=4, style='Medium Grid 1 Accent 1')
table.alignment = WD_TABLE_ALIGNMENT.CENTER
hdr_cells = table.rows[0].cells
hdr_cells[0].text = '字段'
hdr_cells[1].text = '必须'
hdr_cells[2].text = '类型'
hdr_cells[3].text = '描述'
hdr_cells[0].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
hdr_cells[1].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
hdr_cells[2].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
hdr_cells[3].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
for s in pars:
row_cells = table.add_row().cells
row_cells[0].text = s['field']
row_cells[1].text = s['optional'] and '是' or ''
row_cells[2].text = ('type' in s) and s['type'] or ''
row_cells[3].text = s['description'][3:-4]
row_cells[0].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
row_cells[1].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
row_cells[2].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
row_cells[3].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
for row in table.rows:
row.height = Cm(0.7)
# Success 200
if 'success' in api:
paragraph_init(document, '响应200:')
sucs = api['success']['fields']['Success 200']
# 表格
table = document.add_table(rows=1, cols=3, style='Medium Grid 1 Accent 3')
table.alignment = WD_TABLE_ALIGNMENT.CENTER
hdr_cells = table.rows[0].cells
hdr_cells[0].text = '字段'
hdr_cells[1].text = '类型'
hdr_cells[2].text = '描述'
hdr_cells[0].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
hdr_cells[1].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
hdr_cells[2].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
for s in sucs:
row_cells = table.add_row().cells
row_cells[0].text = s['field']
row_cells[1].text = ('type' in s) and s['type'] or ''
row_cells[2].text = s['description'][3:-4]
row_cells[0].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
row_cells[1].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
row_cells[2].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
for row in table.rows:
row.height = Cm(0.7)
# Error 4xx
if 'error' in api:
paragraph_init(document, '响应失败:')
errs = api['error']['fields']['Error 4xx']
# 表格
table = document.add_table(rows=1, cols=2, style='Medium Grid 1 Accent 2')
table.alignment = WD_TABLE_ALIGNMENT.CENTER
hdr_cells = table.rows[0].cells
hdr_cells[0].text = '字段'
hdr_cells[1].text = '描述'
hdr_cells[0].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
hdr_cells[1].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
for e in errs:
row_cells = table.add_row().cells
row_cells[0].text = e['field']
row_cells[1].text = e['description'][3:-4]
row_cells[0].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
row_cells[1].vertical_alignment = WD_ALIGN_VERTICAL.CENTER
for row in table.rows:
row.height = Cm(0.7)
# 每个接口换一行
paragraph_init(document, '')
final_name = project_name + '——接口文档.docx'
final_path = os.path.join('./', final_name)
document.save(final_path)