Swagger转Word文档

一、思路

 解析Swagger的接口返回值

 使用代码将其转化为Word文档

二、实现

1.封装三个参数类

Table类

@Data
public class Table {
    /**
     * 配置组
     */
    private String group;
    /**
     * 大标题
     */
    private String title;
    /**
     * 小标题
     */
    private String tag;
    /**
     * url
     */
    private String url;

    /**
     * 响应参数格式
     */
    private String responseForm;

    /**
     * 请求方式
     */
    private String requestType;

    /**
     * 请求体
     */
    private List<Request> requestList;

    /**
     * 返回体
     */
    private List<Response> responseList;

    /**
     * 请求参数
     */
    private String requestParam;

    /**
     * 返回值
     */
    private String responseParam;
}

Request类

@Data
public class Request {
    /**
     * 请求参数
     */
    private String description;

    /**
     * 参数名
     */
    private String name;

    /**
     * 数据类型
     */
    private String type;

    /**
     * 参数类型
     */
    private String paramType;

    /**
     * 是否必填
     */
    private Boolean require;

    /**
     * 说明
     */
    private String remark;
}

Response类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Response {
    /**
     * 返回参数
     */
    private String description;

    /**
     * 参数名
     */
    private String name;

    /**
     * 说明
     */
    private String remark;
}

2.解析swagger的接口返回值

解析接口 ,采用了hutool的HttpUtil进行接口访问,以及alibaba的JOSN

/**
 * 解析swagger2生成Word接口文档
 *
 */
@GetMapping("/getInterfaceDoc")
public void getInterfaceDoc() {
    // 组
    String resp = HttpUtil.get(this.projectPath + "/swagger-resources");
    JSONArray groupJsonArray = JSONArray.parseArray(resp);
    ArrayList<String> groupNames = new ArrayList<>();
    for (Object o : groupJsonArray) {
        JSONObject group = (JSONObject) o;
        groupNames.add(group.getString("name"));
    }

    // 接口信息
    JSONArray apiInfos = new JSONArray();
    groupNames.forEach(group -> {

        Map<String, Object> param = new HashMap<>();
        param.put("group", group);
        String result = HttpUtil.get(this.projectPath + "/v2/api-docs", param);
        JSONObject jsonObject = JSONObject.parseObject(result);
        jsonObject.put("group",group);
        apiInfos.add(jsonObject);
        System.out.println(jsonObject.getString("group"));
    });
    List<Table> tables = dataCollectionUtil.generateInterfaceDoc(apiInfos);
    test(tables);
}
/**
     * 生成接口文档
     */
    public  List<Table> generateInterfaceDoc(JSONArray apiInfos){
        List<Table> list = new LinkedList();

        for (Object info : apiInfos) {
            JSONObject api = (JSONObject) info;
            //解析paths
//            LinkedHashMap<String, LinkedHashMap> paths = (LinkedHashMap) api.getJSONObject("paths");
            String group = api.getString("group");
            LinkedHashMap<String, Object> paths = JSON.parseObject(api.getJSONObject("paths").toJSONString(),LinkedHashMap.class, Feature.OrderedField);
            if (paths != null) {
                Iterator<Map.Entry<String, Object>> iterator = paths.entrySet().iterator();
                while (iterator.hasNext()) {
                    Table table = new Table();
                    List<Request> requestList = new LinkedList<Request>();
                    String requestType = "";

                    Map.Entry<String, Object> next = iterator.next();
                    //得到url
                    String url = next.getKey();
                    LinkedHashMap<String, Object> value = JSON.parseObject(next.getValue().toString(),LinkedHashMap.class, Feature.OrderedField);
                    //得到请求方式,输出结果类似为 get/post/delete/put 这样
                    Set<String> requestTypes = value.keySet();
                    for (String str : requestTypes) {
                        requestType += str + "/";
                    }
                    Iterator<Map.Entry<String, Object>> it2 = value.entrySet().iterator();
                    //解析请求,得到请求类型
                    Map.Entry<String, Object> get = it2.next();
                    JSONObject getValue = (JSONObject)get.getValue();
                    String title = (String) ((List) getValue.get("tags")).get(0);//得到大标题
                    String tag = String.valueOf(getValue.get("summary"));
                    //请求体
                    JSONArray parameters = getValue.getJSONArray("parameters");
//                    ArrayList parameters = (ArrayList) getValue.get("parameters");
                    if (parameters != null && parameters.size() > 0) {
                        for (int i = 0; i < parameters.size(); i++) {
                            Request request = new Request();
                            LinkedHashMap<String, Object> param = JSON.parseObject(parameters.get(i).toString(),LinkedHashMap.class, Feature.OrderedField);
                            request.setDescription(String.valueOf(param.get("description")));
                            request.setName(String.valueOf(param.get("name")));
                            request.setType(String.valueOf(param.get("type")));
                            request.setParamType(String.valueOf(param.get("in")));
                            request.setRequire((Boolean) param.get("required"));
                            requestList.add(request);
                        }
                    }
                    //返回体,比较固定
                    List<Response> responseList = listResponse();
                    //模拟一次HTTP请求,封装请求体和返回体,如果是Restful的文档可以再补充
                    if (requestType.contains("post")) {
                        Map<String, Object> stringStringMap = toPostBody(requestList);
                        table.setRequestParam(stringStringMap.toString());
                        String post =HttpUtil.post(this.projectPath+ url, stringStringMap);
                        table.setResponseParam(post);
                    } else if (requestType.contains("get")) {
                        String s = toGetHeader(requestList);
                        table.setResponseParam(s);
                        String getStr = HttpUtil.get(this.projectPath + url + s);
                        table.setResponseParam(getStr);
                    }

                    //封装Table
                    table.setGroup(group);
                    table.setTitle(title);
                    table.setUrl(url);
                    table.setTag(tag);
                    table.setResponseForm("application/json");
                    table.setRequestType(StringUtils.removeEnd(requestType, "/"));
                    table.setRequestList(requestList);
                    table.setResponseList(responseList);
                    list.add(table);
                }
            }
            return list;
        }
        return null;
    }

    //封装返回信息,可能需求不一样,可以自定义
    private List<Response> listResponse() {
        List<Response> responseList = new LinkedList<Response>();
        responseList.add(new Response("受影响的行数", "counts", null));
        responseList.add(new Response("结果说明信息", "msg", null));
        responseList.add(new Response("是否成功", "success", null));
        responseList.add(new Response("返回对象", "data", null));
        responseList.add(new Response("错误代码", "errCode", null));
        return responseList;
    }

    //封装post请求体
    private  Map<String, Object> toPostBody(List<Request> list) {
        Map<String, Object> map = new HashMap<>(16);
        if (list != null && list.size() > 0) {
            for (Request request : list) {
                String name = request.getName();
                String type = request.getType();
                switch (type) {
                    case "string":
                        map.put(name, "string");
                        break;
                    case "integer":
                        map.put(name, "0");
                        break;
                    case "double":
                        map.put(name, "0.0");
                        break;
                    default:
                        map.put(name, "null");
                        break;
                }
            }
        }
        return map;
    }

    //封装get请求头
    private  String toGetHeader(List<Request> list) {
        StringBuffer stringBuffer = new StringBuffer();
        if (list != null && list.size() > 0) {
            for (Request request : list) {
                String name = request.getName();
                String type = request.getType();
                switch (type) {
                    case "string":
                        stringBuffer.append(name+"&=string");
                        break;
                    case "integer":
                        stringBuffer.append(name+"&=0");
                        break;
                    case "double":
                        stringBuffer.append(name+"&=0.0");
                        break;
                    default:
                        stringBuffer.append(name+"&=null");
                        break;
                }
            }
        }
        String s = stringBuffer.toString();
        if ("".equalsIgnoreCase(s)){
            return "";
        }
        return "?" + StringUtils.removeStart(s, "&");
    }

3.使用代码生成Word文档(没有使用原作者的JSP方法,因为项目中再集成很麻烦)

/**
     * 生成文档
     * @param tables
     */
    private void test(List<Table> tables) {
        // 创建文档
        XWPFDocument document = new XWPFDocument();

        // 添加标题
        XWPFParagraph titleParagraph = document.createParagraph();
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun titleRun = titleParagraph.createRun();
        titleRun.setText("后台API接口文档");
        titleRun.setBold(true);
        titleRun.setFontSize(20);

        // 添加接口信息表格
        // 获取接口详细信息数据

//        for (int i = 0; i < interfaceList.size(); i++) {
//            Table table = interfaceList.get(i);
        createTable(document, tables);
//        }

        // 保存文档
        try (FileOutputStream fileOutputStream = new FileOutputStream("F:/数据导入/后台API接口文档.docx")) {
            document.write(fileOutputStream);
            System.out.println("接口文档生成成功!");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 在文档中添加一个表格,将接口详细信息填充到表格中
     *
     * @param document 文档对象
     */
    private XWPFDocument createTable(XWPFDocument document, List<Table> tables) {
        tables.forEach(table -> {
            // 添加小标题
            XWPFParagraph tagParagraph = document.createParagraph();
            XWPFRun run = tagParagraph.createRun();
            run.setText(table.getGroup());
            run.setBold(true);
            run.setFontSize(16);

            // 添加表格
            XWPFTable xwpfTable = document.createTable(table.getRequestList().size() + 5, 6);
            xwpfTable.setWidth("100%");

            // 设置表头
            setCellText(xwpfTable.getRow(0).getCell(0), table.getTag(),true);
            setCellText(xwpfTable.getRow(1).getCell(0), "URL");
            setCellText(xwpfTable.getRow(2).getCell(0), "请求类型");
            setCellText(xwpfTable.getRow(3).getCell(0), "返回值类型");

            mergeCellsHorizontal(xwpfTable.getRow(0), 0, 5);
            setCellText(xwpfTable.getRow(4).getCell(0), "请求参数", true);
            setCellText(xwpfTable.getRow(4).getCell(1), "参数名", true);
            setCellText(xwpfTable.getRow(4).getCell(2), "数据类型", true);
            setCellText(xwpfTable.getRow(4).getCell(3), "参数类型", true);
            setCellText(xwpfTable.getRow(4).getCell(4), "是否必填", true);
            setCellText(xwpfTable.getRow(4).getCell(5), "说明", true);

            // 填充表格内容
            mergeCellsHorizontal(xwpfTable.getRow(1), 1, 5);
            setCellText(xwpfTable.getRow(1).getCell(1), table.getUrl());

            mergeCellsHorizontal(xwpfTable.getRow(2), 1, 5);
            setCellText(xwpfTable.getRow(2).getCell(1), table.getRequestType());

            mergeCellsHorizontal(xwpfTable.getRow(3), 1, 5);
            setCellText(xwpfTable.getRow(3).getCell(1), table.getResponseForm());

            for (int i = 0; i < table.getRequestList().size(); i++) {
                Request request = table.getRequestList().get(i);
                if (ObjectUtils.isEmpty(request)) {
                    break;
                }
                XWPFTableRow row = xwpfTable.getRow(i + 5);
                setCellText(row.getCell(0), request.getDescription());
                setCellText(row.getCell(1), request.getName());
                setCellText(row.getCell(2), request.getType());
                setCellText(row.getCell(3), request.getParamType());
                setCellText(row.getCell(4), request.getRequire() ? "是" : "否");
                setCellText(row.getCell(5), request.getRemark());
            }
            // 返回
            XWPFTableRow respRow = xwpfTable.createRow();

            mergeCellsHorizontal(respRow, 0, 1);
            mergeCellsHorizontal(respRow, 2, 3);
            mergeCellsHorizontal(respRow, 4, 5);

            setCellText(respRow.getCell(0), "返回参数", true);
            setCellText(respRow.getCell(2), "参数名", true);
            setCellText(respRow.getCell(4), "说明", true);

            for (int i = 0; i < table.getResponseList().size(); i++) {
                Response response = table.getResponseList().get(i);
                XWPFTableRow dataRow = xwpfTable.createRow();
                mergeCellsHorizontal(dataRow, 0, 1);
                mergeCellsHorizontal(dataRow, 2, 3);
                mergeCellsHorizontal(dataRow, 4, 5);
                setCellText(dataRow.getCell(0), response.getDescription());
                setCellText(dataRow.getCell(2), response.getName());
                setCellText(dataRow.getCell(4), response.getRemark());
            }
        });
        return document;
    }

    private void setCellText(XWPFTableCell cell, String text) {
        setCellTextCenterAlignment(cell);
        XWPFParagraph paragraph = cell.getParagraphs().get(0);
        XWPFRun run = paragraph.createRun();
        run.setText(text);
    }

    private void setCellText(XWPFTableCell cell, String text, boolean izBold) {
        setCellTextCenterAlignment(cell);
        XWPFParagraph paragraph = cell.getParagraphs().get(0);
        XWPFRun run = paragraph.createRun();
        run.setText(text);
//        run.setBold(izBold);
        cell.setColor("5881AF");
    }

    /**
     * 单元格文字居中
     *
     * @param cell
     */
    private void setCellTextCenterAlignment(XWPFTableCell cell) {
        List<XWPFParagraph> paragraphs = cell.getParagraphs();
        if (paragraphs.isEmpty()) {
            // 如果单元格中没有段落,则创建一个新的段落对象
            XWPFParagraph paragraph = cell.addParagraph();
            paragraph.setAlignment(ParagraphAlignment.CENTER);
        } else {
            // 否则,获取第一个段落对象并设置对齐方式
            XWPFParagraph firstParagraph = paragraphs.get(0);
            firstParagraph.setAlignment(ParagraphAlignment.CENTER);
        }
    }
/**
 * 合并单元格
 *
 * @param row
 */
public void mergeCellsHorizontal(XWPFTableRow row, int fromCell, int toCell) {
    for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
        XWPFTableCell cell = row.getCell(cellIndex);
        if (cellIndex == fromCell) {
            // The first merged cell is set with RESTART merge value
            cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
        } else {
            // Cells which join (merge) the first one, are set with CONTINUE
            cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
        }
    }
}

4.示例

最后通过给某些标签加上目录结构即可

三、原作者地址:

​​​​​​https://www.cnblogs.com/jmcui/p/8298823.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Swagger是一种用于创建、设计、构建和编写API文档的工具,它提供了多种功能,包括自动生成文档的能力。然而,Swagger默认只提供了HTML和JSON格式的文档输出,没有直接支持将Swagger文档换为Word格式的选项。 要将Swagger在线换为Word文档,可以使用以下步骤: 第一步是下载Swagger文档Swagger文档通常以JSON格式或YAML格式提供。通过访问Swagger UI界面,我们可以获取到Swagger文档的URL或下载链接。 第二步是将Swagger文档换为OpenAPI规范(也称为Swagger规范)。可以使用Swagger Editor或Swagger CLI工具加载Swagger文档,并将其另存为OpenAPI YAML文件。这个规范文件将作为后续步骤的输入。 第三步是使用一些在线或本地的工具来将OpenAPI规范换为Word文档。这些工具通常支持将YAML文件换为Word文档,并按照预定的格式和样式来呈现API文档内容。 一些在线工具或服务提供了SwaggerWord文档换功能。你可以通过搜索引擎查找这些工具,如"Swagger to Word converter online"或"OpenAPI to Word converter"。选择合适的工具,并根据其提供的说明上传OpenAPI规范文件,然后选择换为Word文档的选项。 最后,下载并保存换完成的Word文档。根据换工具的要求,可能需要进行一些格式或样式的调整,以使文档符合个人或组织的需求。 需要注意的是,换工具的质量和功能各有不同。建议在选择换工具时,查看其用户评价和使用示例,以确保它能够满足你的具体需求。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值