swagger-ui接口文档转换为html或word格式

swagger-ui生成的接口文档想来大家用者不少,但是有时候需要打印或者各种需求,那么怎么转换成html或者word格式呢,下面带大家一起看一下(代码可直接复制使用,部分已标注地方需根据各自项目进行修改)。

创建3个实体类+1个html

新建3个实体类和1个html文件,html文件可放在resources下的static包中。实体类参数用于接收接口数据,不建议修改。

package good.doctor.test.config;

import lombok.Data;

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

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

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

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

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

    /**
     * 说明
     */
    private String remark;
}
package good.doctor.test.config;

import lombok.Data;

@Data
public class SwaggerResponse {
     

    /**
     * 返回参数
     */
    private String description;

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

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

    public SwaggerResponse(String description, String name, String remark) {
     
        this.description = description;
        this.name = name;
        this.remark = remark;
    }

}
package good.doctor.test.config;

import lombok.Data;
import java.util.List;

@Data
public class SwaggerTable {
     
    /**
     * 大标题
     */
    private String title;
    /**
     * 小标题
     */
    private String tag;
    /**
     * url
     */
    private String url;

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

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

    /**
     * 请求体
     */
    private List<SwaggerRequest> swaggerRequestList;

    /**
     * 返回体
     */
    private List<SwaggerResponse> swaggerResponseList;

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

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

}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <title>接口文档</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="http://libs.baidu.com/jquery/1.9.1/jquery.js"></script>
</head>

<body>
<div id="app">
    <div class="item" v-for="(item,i) in data" :key="i">
        <h4>{
     {
      i + 1 }}{
     {
      item.title }}:{
     {
      item.url }}</h4>
        <table cellspacing="0" cellpadding="0" border="1" id="out-table">
            <thead class="bg">
            <tr>
                <th colspan="6">{
     {
      item.tag }}</th>
            </tr>
            </thead>
            <tbody>
            <tr>
                <td>URL</td>
                <td colspan="5">{
     {
      item.url }}</td>
            </tr>
            <tr>
                <td>请求方式</td>
                <td colspan="5">{
     {
      item.responseForm }}</td>
            </tr>
            <tr>
                <td>返回值类型</td>
                <td colspan="5">{
     {
      item.requestType }}</td>
            </tr>
            <tr class="bg">
                <td>请求参数</td>
                <td>参数名</td>
                <td>数据类型</td>
                <td>参数类型</td>
                <td>是否必填</td>
                <td>说明</td>
            </tr>
            <tr v-for="(r,inIndex) in item.swaggerRequestList">
                <td>{
     {
      r.description }}</td>
                <td>{
     {
      r.name }}</td>
                <td>{
     {
      r.type }}</td>
                <td>{
     {
      r.paramType }}</td>
                <td>{
     {
      r.require }}</td>
                <td>{
     {
      r.remark }}</td>
            </tr>
            <tr class="bg">
                <td>返回参数</td>
                <td>参数名</td>
                <td colspan="4">说明</td>
            </tr>
            <tr v-for="(r,inIndex) in item.swaggerResponseList">
                <td>{
     {
      r.description }}</td>
                <td>{
     {
      r.name }}</td>
                <td colspan="4">{
     {
      r.remark }}</td>
            </tr>
            <tr class="bg">
                <td colspan="6">示例</td>
            </tr>
            <tr>
                <td>请求参数</td>
                <td colspan="5">{
     {
      item.requestParam }}</td>
            </tr>
            <tr>
                <td>返回值</td>
                <td colspan="5">{
     {
      item.responseParam }}</td>
            </tr>
            </tbody>
        </table>
    </div>
</div>
</body>
</html>
<script>
    var app = new Vue({
     
        el: "#app",
        data() {
     
            return {
     
                data: []
            };
        },
        created() {
     
            let self = this;
            $.ajax({
     
                type: "POST",
                url: "/get/swagger/to/word", 
                //注意:controller会有一个接口用于将文档转换成html或word格式。
                //该处url即接口的完整路径,需要根据项目进行修改。
                data: "",
                dataType: "json",
                mimeType: "multipart/form-data",
                cache: false,
                processData: false,
                contentType: false,
                success: function(data) {
     
                    self.data = data;
                }
            });
        }
    });
</script>
<style>
    .item {
     
        width: 800px;
        margin: 0 auto;
    }
    table {
     
        width: 100%;
    }
    table td {
     
        padding: 10px;
    }
    table tr td:first-child {
     
        min-width: 80px;
    }
    .item + .item {
     
        margin-top: 20px;
    }
    .bg {
     
        color: #fff;
        background: #5079a9;
    }
</style>

获取Json数据

回到我们的swagger页面:
swagger-ui接口文档转换为html或word格式_第1张图片
点击链接即可获取接口文档的JSON形式数据,复制保存,如下所示:
swagger-ui接口文档转换为html或word格式_第2张图片

解析JSON数据

创建SwaggerUtil类,具体代码如下:

package good.doctor.test.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

public class SwaggerUtil {
     
    public static List<SwaggerTable> getTableList() throws Exception{
     

        List<SwaggerTable> list = new LinkedList();
        try {
     
        
        //注意:此处json即我们上一步复制的json数据,
        //有的作者是把这些字段复制在文档中,然后读取该文档。小编这里偷个懒,直接复制在代码里。
            String json="{\"swagger\":\"2.0\",\"info\":{\"description\":\"测试接口描述\",\"version\":\"1.0\",\"title\":\"测试项目\",\"contact\":{\"name\":\"name\",\"url\":\"url\",\"email\":\"email\"}},\"host\":\"localhost:7096\",\"basePath\":\"/\",\"tags\":[{\"name\":\"basic-error-controller\",\"description\":\"Basic Error Controller\"},{\"name\":\"地区相关接口\",\"description\":\"controller\"}],\"paths\":{\"/error\":{\"get\":{\"tags\":[\"basic-error-controller\"],\"summary\":\"error\",\"operationId\":\"errorUsingGET\",\"produces\":[\"*/*\"],\"responses\":{\"200\":{\"description\":\"OK\",\"schema\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"object\"}}},\"401\":{\"description\":\"Unauthorized\"},\"403\":{\"description\":\"Forbidden\"},\"404\":{\"description\":\"Not Found\"}},\"deprecated\":false},\"head\":{\"tags\":[\"basic-error-controller\"],\"summary\":\"error\",\"operationId\":\"errorUsingHEAD\",\"consumes\":[\"application/json\"],\"produces\":[\"*/*\"],\"responses\":{\"200\":{\"description\":\"OK\",\"schema\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"object\"}}},\"204\":{\"description\":\"No Content\"},\"401\":{\"description\":\"Unauthorized\"},\"403\":{\"description\":\"Forbidden\"}},\"deprecated\":false},\"post\":{\"tags\":[\"basic-error-controller\"],\"summary\":\"error\",\"operationId\":\"errorUsingPOST\",\"consumes\":[\"application/json\"],\"produces\":[\"*/*\"],\"responses\":{\"200\":{\"description\":\"OK\",\"schema\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"object\"}}},\"201\":{\"description\":\"Created\"},\"401\":{\"description\":\"Unauthorized\"},\"403\":{\"description\":\"Forbidden\"},\"404\":{\"description\":\"Not Found\"}},\"deprecated\":false},\"put\":{\"tags\":[\"basic-error-controller\"],\"summary\":\"error\",\"operationId\":\"errorUsingPUT\",\"consumes\":[\"application/json\"],\"produces\":[\"*/*\"],\"responses\":{\"200\":{\"description\":\"OK\",\"schema\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"object\"}}},\"201\":{\"description\":\"Created\"},\"401\":{\"description\":\"Unauthorized\"},\"403\":{\"description\":\"Forbidden\"},\"404\":{\"description\":\"Not Found\"}},\"deprecated\":false},\"delete\":{\"tags\":[\"basic-error-controller\"],\"summary\":\"error\",\"operationId\":\"errorUsingDELETE\",\"produces\":[\"*/*\"],\"responses\":{\"200\":{\"description\":\"OK\",\"schema\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"object\"}}},\"204\":{\"description\":\"No Content\"},\"401\":{\"description\":\"Unauthorized\"},\"403\":{\"description\":\"Forbidden\"}},\"deprecated\":false},\"options\":{\"tags\":[\"basic-error-controller\"],\"summary\":\"error\",\"operationId\":\"errorUsingOPTIONS\",\"consumes\":[\"application/json\"],\"produces\":[\"*/*\"],\"responses\":{\"200\":{\"description\":\"OK\",\"schema\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"object\"}}},\"204\":{\"description\":\"No Content\"},\"401\":{\"description\":\"Unauthorized\"},\"403\":{\"description\":\"Forbidden\"}},\"deprecated\":false},\"patch\":{\"tags\":[\"basic-error-controller\"],\"summary\":\"error\",\"operationId\":\"errorUsingPATCH\",\"consumes\":[\"application/json\"],\"produces\":[\"*/*\"],\"responses\":{\"200\":{\"description\":\"OK\",\"schema\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"object\"}}},\"204\":{\"description\":\"No Content\"},\"401\":{\"description\":\"Unauthorized\"},\"403\":{\"description\":\"Forbidden\"}},\"deprecated\":false}},\"/get/amap/swagger/toword\":{\"post\":{\"tags\":[\"地区相关接口\"],\"summary\":\"把swagger-ui里的API转换为word文档\",\"operationId\":\"towordUsingPOST\",\"consumes\":[\"application/json\"],\"produces\":[\"*/*\"],\"responses\":{\"200\":{\"description\":\"OK\",\"schema\":{\"type\":\"object\"}},\"201\":{\"description\":\"Created\"},\"401\":{\"description\":\"Unauthorized\"},\"403\":{\"description\":\"Forbidden\"},\"404\":{\"description\":\"Not Found\"}},\"deprecated\":false}},\"/get/area\":{\"post\":{\"tags\":[\"地区相关接口\"],\"summary\":\"获取地区信息列表\",\"description\":\"获取地区信息列表\",\"operationId\":\"helloUsingPOST\",\"consumes\":[\"application/json\"],\"produces\":[\"*/*\"],\"parameters\":[{\"name\":\"试验参数\",\"in\":\"query\",\"description\":\"参数\",\"required\":true,\"type\":\"string\",\"allowEmptyValue\":false}],\"responses\":{\"200\":{\"description\":\"OK\",\"schema\":{\"type\":\"string\"}},\"201\":{\"description\":\"Created\"},\"401\":{\"description\":\"Unauthorized\"},\"403\":{\"description\":\"Forbidden\"},\"404\":{\"description\":\"Not Found\"}},\"deprecated\":false}},\"/get/town\":{\"get\":{\"tags\":[\"地区相关接口\"],\"summary\":\"获取县镇列表\",\"description\":\"获取县镇列表\",\"operationId\":\"getTownUsingGET\",\"produces\":[\"*/*\"],\"parameters\":[{\"name\":\"str\",\"in\":\"query\",\"description\":\"参数\",\"required\":false,\"type\":\"string\",\"allowEmptyValue\":false}],\"responses\":{\"200\":{\"description\":\"OK\",\"schema\":{\"type\":\"string\"}},\"401\":{\"description\":\"Unauthorized\"},\"403\":{\"description\":\"Forbidden\"},\"404\":{\"description\":\"Not Found\"}},\"deprecated\":false}}},\"definitions\":{\"ModelAndView\":{\"type\":\"object\",\"properties\":{\"empty\":{\"type\":\"boolean\"},\"model\":{\"type\":\"object\"},\"modelMap\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"object\"}},\"reference\":{\"type\":\"boolean\"},\"status\":{\"type\":\"string\",\"enum\":[\"100 CONTINUE\",\"101 SWITCHING_PROTOCOLS\",\"102 PROCESSING\",\"103 CHECKPOINT\",\"200 OK\",\"201 CREATED\",\"202 ACCEPTED\",\"203 NON_AUTHORITATIVE_INFORMATION\",\"204 NO_CONTENT\",\"205 RESET_CONTENT\",\"206 PARTIAL_CONTENT\",\"207 MULTI_STATUS\",\"208 ALREADY_REPORTED\",\"226 IM_USED\",\"300 MULTIPLE_CHOICES\",\"301 MOVED_PERMANENTLY\",\"302 FOUND\",\"302 MOVED_TEMPORARILY\",\"303 SEE_OTHER\",\"304 NOT_MODIFIED\",\"305 USE_PROXY\",\"307 TEMPORARY_REDIRECT\",\"308 PERMANENT_REDIRECT\",\"400 BAD_REQUEST\",\"401 UNAUTHORIZED\",\"402 PAYMENT_REQUIRED\",\"403 FORBIDDEN\",\"404 NOT_FOUND\",\"405 METHOD_NOT_ALLOWED\",\"406 NOT_ACCEPTABLE\",\"407 PROXY_AUTHENTICATION_REQUIRED\",\"408 REQUEST_TIMEOUT\",\"409 CONFLICT\",\"410 GONE\",\"411 LENGTH_REQUIRED\",\"412 PRECONDITION_FAILED\",\"413 PAYLOAD_TOO_LARGE\",\"413 REQUEST_ENTITY_TOO_LARGE\",\"414 URI_TOO_LONG\",\"414 REQUEST_URI_TOO_LONG\",\"415 UNSUPPORTED_MEDIA_TYPE\",\"416 REQUESTED_RANGE_NOT_SATISFIABLE\",\"417 EXPECTATION_FAILED\",\"418 I_AM_A_TEAPOT\",\"419 INSUFFICIENT_SPACE_ON_RESOURCE\",\"420 METHOD_FAILURE\",\"421 DESTINATION_LOCKED\",\"422 UNPROCESSABLE_ENTITY\",\"423 LOCKED\",\"424 FAILED_DEPENDENCY\",\"425 TOO_EARLY\",\"426 UPGRADE_REQUIRED\",\"428 PRECONDITION_REQUIRED\",\"429 TOO_MANY_REQUESTS\",\"431 REQUEST_HEADER_FIELDS_TOO_LARGE\",\"451 UNAVAILABLE_FOR_LEGAL_REASONS\",\"500 INTERNAL_SERVER_ERROR\",\"501 NOT_IMPLEMENTED\",\"502 BAD_GATEWAY\",\"503 SERVICE_UNAVAILABLE\",\"504 GATEWAY_TIMEOUT\",\"505 HTTP_VERSION_NOT_SUPPORTED\",\"506 VARIANT_ALSO_NEGOTIATES\",\"507 INSUFFICIENT_STORAGE\",\"508 LOOP_DETECTED\",\"509 BANDWIDTH_LIMIT_EXCEEDED\",\"510 NOT_EXTENDED\",\"511 NETWORK_AUTHENTICATION_REQUIRED\"]},\"view\":{\"$ref\":\"#/definitions/View\"},\"viewName\":{\"type\":\"string\"}},\"title\":\"ModelAndView\"},\"View\":{\"type\":\"object\",\"properties\":{\"contentType\":{\"type\":\"string\"}},\"title\":\"View\"}}}";
            ObjectMapper mapper = new ObjectMapper();
            Map map = JSONObject.toJavaObject(JSON.parseObject(json), Map.class);;
            //得到host,用于模拟http请求
            String host = String.valueOf(map.get("host"));
            String basePath = String.valueOf(map.get("basePath"));
            //解析paths
            Map<String, Map> paths = (Map) map.get("paths");
            System.out.println(paths);
            if (paths != null) {
     
                Iterator<Map.Entry<String, Map>> iterator = paths.entrySet().iterator();
                while (iterator.hasNext()) {
     
                    SwaggerTable swaggerTable = new SwaggerTable();
                    List<SwaggerRequest> swaggerRequestList = new LinkedList<SwaggerRequest>();
                    String requestType = "";

                    Map.Entry<String, Map> next = iterator.next();
                    String url = next.getKey();//得到url
                    if(url.startsWith("/error")){
     
                        continue;
                    }
                    Map<String, Map> value = next.getValue();
                    //得到请求方式,输出结果类似为 get/post/delete/put 这样
                    Set<String> requestTypes = value.keySet();
                    for (String str : requestTypes) {
     
                        requestType += str + "/";
                    }
                    Iterator<Map.Entry<String, Map>> it2 = value.entrySet().iterator();
                    //解析请求
                    Map.Entry<String, Map> get = it2.next();//得到get
                    Map getValue = get.getValue();
                    String title = (String) ((List) getValue.get("tags")).get(0);//得到大标题
                    String tag = String.valueOf(getValue.get("summary"));
                    //请求体
                    List parameters = (List) getValue.get("parameters");
                    System.out.println(parameters);
                    if (parameters != null && parameters.size() > 0) {
     
                        for (int i = 0; i < parameters.size(); i++) {
     
                            SwaggerRequest swaggerRequest = new SwaggerRequest();
                            Map<String, Object> param = (Map) parameters.get(i);
                            swaggerRequest.setDescription(String.valueOf(param.get("description")));
                            swaggerRequest.setName(String.valueOf(param.get("name")));
                            swaggerRequest.setType(String.valueOf(param.get("type")));
                            swaggerRequest.setParamType(String.valueOf(param.get("in")));
                            swaggerRequest.setRequire((Boolean) param.get("required"));
                            swaggerRequestList.add(swaggerRequest);
                        }
                    }
                    //返回体,比较固定
                    List<SwaggerResponse> swaggerResponseList = listResponse();
                    //模拟一次HTTP请求,封装请求体和返回体,如果是Restful的文档可以再补充

                    if (requestType.contains("post")) {
     
                        String stringStringMap = toPostBody(swaggerRequestList);
                        swaggerTable.setRequestParam(stringStringMap.toString());
                        swaggerTable.setResponseParam("code:\"200\",{\"description\":\"OK\",code:\"401\":{\"description\":\"Unauthorized\"},\"403\":{\"description\":\"Forbidden\"},\"404\":{\"description\":\"Not Found\"}");

                    } else if (requestType.contains("get")) {
     
                        String s = toGetHeader(swaggerRequestList);
                        swaggerTable.setRequestParam(s);
                        swaggerTable.setResponseParam("code:\"200\",{\"description\":\"OK\",\"schema\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"object\"}}},\"401\":{\"description\":\"Unauthorized\"},\"403\":{\"description\":\"Forbidden\"},\"404\":{\"description\":\"Not Found\"}");
                    }
                    //封装Table
                    swaggerTable.setTitle(title);
                    swaggerTable.setUrl(url);
                    swaggerTable.setTag(tag);
                    swaggerTable.setResponseForm("application/json");
                    swaggerTable.setRequestType(StringUtils.removeEnd(requestType, "/"));
                    swaggerTable.setSwaggerRequestList(swaggerRequestList);
                    swaggerTable.setSwaggerResponseList(swaggerResponseList);
                    list.add(swaggerTable);
                }
            }
            return list;

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

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

    //封装post请求体
    private static String toPostBody(List<SwaggerRequest> list) {
     
        StringBuffer stringBuffer = new StringBuffer();
        if (list != null && list.size() > 0) {
     
            for (SwaggerRequest swaggerRequest : list) {
     
                String name = swaggerRequest.getName();
                String type = swaggerRequest.getType();
                switch (type) {
     
                    case "string":
                        stringBuffer.append(name).append("=string");
                        break;
                    case "integer":
                        stringBuffer.append(name).append("=0");
                        break;
                    case "double":
                        stringBuffer.append(name).append("=0.0");
                        break;
                    default:
                        stringBuffer.append(name).append("=null");
                        break;
                }
            }
        }
        return stringBuffer.toString();
    }

    //封装get请求头
    private static String toGetHeader(List<SwaggerRequest> list) {
     
        StringBuffer stringBuffer = new StringBuffer();

        if (list != null && list.size() > 0) {
     
            for (SwaggerRequest swaggerRequest : list) {
     
                System.out.println(swaggerRequest.getType());
                String name = swaggerRequest.getName();
                String type = swaggerRequest.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, "&");
    }

}

controller文件创建接口,启动

此时工作已经完成了九成,在controller类中添加接口即可,代码如下:

ApiOperation(value="将swagger-ui文档转换为word")
@PostMapping(value = "/get/swagger/to/word")
@ResponseBody
public Object toword() throws Exception{
     
    List<SwaggerTable> list = SwaggerUtil.getTableList();
    return list;
}

查看结果

访问路径:http://localhost:7096/swagger.html
localhost即ip;
7096为端口号(根据项目进行修改,未设置时默认8080);
swagger.html为我们第一步创建的html文件,我将它命名为swagger;
得到结果如下:swagger-ui接口文档转换为html或word格式_第3张图片
这就得到了接口文档的html页面。如果要得到word格式,将表格复制进word文档即可。

你可能感兴趣的:(java,java,json,html)