解析Swagge.Json生成Word文档

1.首先了解swagger.json数据格式

  

 

2.了解了json格式:所有内容基本都是key:value的形式,选用的技术:JObject,JArray,JToken;(本人了解不深,只是会基本使用,有大神请留言,不胜感激)

   直接上代码:

  public class SwaggerHelper
    {
        //递归结果集
        List<InterfaceRequestField> requestFieldList = new List<InterfaceRequestField>();
        public void Run(string path)
        {
            //文档标题信息
            InterfaceVersion interfaceVersion = new InterfaceVersion();
            //所有接口信息
            List<InterfaceMethod> interfaceMethods = new List<InterfaceMethod>();
            //所有接口字段信息
            List<InterfaceRequestField> requestFields = new List<InterfaceRequestField>();

            //读取Json
            JObject jToken = ReadJsonTxt(path);

            var info = jToken.SelectToken("info");
            var paths = jToken.SelectToken("paths");
            var schemas = jToken.SelectToken("components.schemas");

            //文档信息
            interfaceVersion.title = info["title"].ToString();
            interfaceVersion.version = info["version"].ToString();

            foreach (var item in paths)
            {
                InterfaceMethod model = new InterfaceMethod();
                model.route = ((JProperty)item).Name.ToString();
                model.type = ((JProperty)item.First().First()).Name.ToString();
               string controllerName= item.First().First().First["tags"][0].ToString();
                model.name = controllerName + "-" + RouteName(model.route);

                foreach (var item2 in item)
                {
                    model.summary = item2.SelectToken("post.['summary']").Value<string>();
                    interfaceMethods.Add(model);

                    //请求实体名称
                    var requestModelName = RequestModelName(item2);
                    //请求字段集合
                    requestFields.AddRange(SbRequestData(schemas, requestModelName, model.name, ParamTypeEnum.入参));
                    requestFieldList.Clear();

                    //返回实体及字段
                    var responseModelName = ResponseModelName(item2);
                    //请求字段集合
                    requestFields.AddRange(SbRequestData(schemas, responseModelName, model.name, ParamTypeEnum.出参));
                    requestFieldList.Clear();
                }
            }
            //生成word帮助类
            new WordHelper().CreateWordFile(interfaceVersion, interfaceMethods, requestFields);
        }

        /// <summary>
        /// 无限套娃 递归
        /// </summary>
        /// <param name="schemas">实体类集合</param>
        /// <param name="modelName">实体类名称</param>
        /// <param name="methodName">方法名称</param>
        /// <returns></returns>
        private List<InterfaceRequestField> SbRequestData(JToken schemas, string modelName, string methodName, ParamTypeEnum paramType)
        {
            List<InterfaceRequestField> result = new List<InterfaceRequestField>();
            string requestModelName = string.Empty;
            requestModelName = modelName;
            //获取请求字段
            foreach (var item in schemas.SelectToken($"{modelName}.properties"))
            {
                string fieldName = ((JProperty)item).Name.ToString();
                var fieldType = item.Parent.SelectToken($"{fieldName}.type").ToString();

                //必填参数集合
                var mustList = MustList(schemas, requestModelName);

                var fieldInfo = JsonConvert.DeserializeObject<FieldDescription>(item.First().ToString());
                requestFieldList.Add(FieldData(item, fieldInfo, mustList, methodName, paramType));

                //第一个集合没有参数
                if (fieldType == "array")
                {
                    requestModelName = RequestModelName2(item, fieldName);
                    //递归
                    SbRequestData(schemas, requestModelName, methodName, paramType);
                }
            }
            return requestFieldList;
        }

        /// <summary>
        /// 通过方法 找请求实体名称
        /// </summary>
        /// <param name="json">paths</param>
        /// <returns></returns>
        private string RequestModelName(JToken json)
        {
            var requestModelName = json.SelectToken("post.['requestBody'].['content'].['application/json'].schema")["$ref"].Value<string>();
            List<string> names = requestModelName.Split('/').ToList();
            return names[names.Count - 1];
        }

        /// <summary>
        /// 集合中包含集合 继续找下一个集合
        /// </summary>
        /// <param name="json"></param>
        /// <param name="name">字段名称</param>
        /// <returns></returns>
        private string RequestModelName2(JToken json, string name)
        {
            var requestModelName = json.Parent.SelectToken($"{name}.items")["$ref"].Value<string>();
            List<string> names = requestModelName.Split('/').ToList();
            return names[names.Count - 1];
        }

        /// <summary>
        /// 返回实体名称
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        private string ResponseModelName(JToken json)
        {
            var responseModelName = json.SelectToken("post.['responses'].200.['content'].['application/json'].schema")["$ref"].Value<string>();
            List<string> names = responseModelName.Split('/').ToList();
            return names[names.Count - 1];
        }


        /// <summary>
        /// 获取实体必填参数
        /// </summary>
        /// <param name="json"></param>
        /// <param name="name">方法实体类名称</param>
        /// <returns></returns>
        private List<string> MustList(JToken json, string name)
        {
            List<string> mustList = new List<string>();
            var str = json.SelectToken($"{name}.required");
            if (str == null)
            {
                return mustList;
            }
            if (string.IsNullOrWhiteSpace(str.ToString()))
            {
                return mustList;
            }
            var list = str.ToString().Split(',').ToList();
            foreach (var flied in list)
            {
                string f = flied.TrimStart('[').TrimEnd(']').Replace("\r\n", "").TrimStart('"').TrimEnd('"').Trim().TrimStart('"');
                mustList.Add(f);
            }
            return mustList;
        }

        private InterfaceRequestField FieldData(JToken json, FieldDescription field, List<string> mustList, string type, ParamTypeEnum paramType)
        {
            InterfaceRequestField result = new InterfaceRequestField();
            result.code = ((JProperty)json).Name.ToString();
            result.type = field.type;
            result.description = field.description;
            result.isMust = mustList.Contains(result.code) ? true : false;
            result.MethodType = type;
            result.paramType = paramType.GetHashCode();
            result.maxLength = field.maxLength;
            return result;
        }

        public JObject ReadJsonTxt(string path)
        {
            StreamReader SR = File.OpenText(path);
            JsonTextReader JTR = new JsonTextReader(SR);
            JObject json = (JObject)JToken.ReadFrom(JTR);
            json = JObject.Parse(JsonConvert.SerializeObject(json));
            return json;
        }


        /// <summary>
        /// 路由方法名称
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private string RouteName(string str)
        {
            string name = string.Empty;
            List<string> routes = str.Split('/').ToList();
            name = routes[routes.Count - 1];
            return name;
        }
    }

    public class InterfaceVersion
    {
        public string title { get; set; }
        public string version { get; set; }
    }

    public class InterfaceMethod
    {
        /// <summary>
        /// 路由
        /// </summary>
        public string route { get; set; }

        /// <summary>
        /// 请求方式
        /// </summary>
        public string type { get; set; }

        /// <summary>
        /// controller 名称
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// 接口说明
        /// </summary>
        public string summary { get; set; }

        /// <summary>
        /// 请求集合
        /// </summary>
        public string requesyBody { get; set; }

        /// <summary>
        /// 返回实体
        /// </summary>
        public string responses { get; set; }
    }


    public class InterfaceRequestField
    {
        /// <summary>
        /// 字段
        /// </summary>
        public string code { get; set; }

        /// <summary>
        /// 类型
        /// </summary>
        public string type { get; set; }

        /// <summary>
        /// 名称
        /// </summary>
        public string description { get; set; }

        /// <summary>
        /// 是否必填
        /// </summary>
        public bool isMust { get; set; }

        /// <summary>
        /// 方法类型
        /// </summary>
        public string MethodType { get; set; }


        /// <summary>
        /// 字段长度
        /// </summary>
        public int maxLength { get; set; }

        /// <summary>
        /// 1.入参 2.出参
        /// </summary>
        public int paramType { get; set; }
    }

    public enum ParamTypeEnum
    {
        入参 = 1,
        出参 = 2
    }

    public class FieldDescription
    {
        public string type { get; set; }

        public string description { get; set; }
        /// <summary>
        /// 字段长度
        /// </summary>
        public int maxLength { get; set; }
    }

3.Json解析完成,调用生成Word方法(网上找的)

public class WordHelper
    {
        public void CreateWordFile(InterfaceVersion list1, List<InterfaceMethod> list2, List<InterfaceRequestField> list3)
        {
            var ss = new List<InterfaceVersion>();
            ss.Add(list1);

            //去重操作
            var distinctList2 = list2.Distinct().ToList();
            var distinctList3 = list3.Distinct().ToList();


            System.Data.DataTable dt, dt2, dt3;
            dt = ToDataTable<InterfaceVersion>(ss);
            dt2 = ToDataTable<InterfaceMethod>(distinctList2);
            dt3 = ToDataTable<InterfaceRequestField>(distinctList3);

            string filePath = $@"{System.IO.Directory.GetCurrentDirectory()}\swagger.docx";
            try
            {
                CreateFile(filePath);
                //
                //MessageFilter.Register();
                object wdLine = WdUnits.wdLine;
                object oMissing = Missing.Value;
                object fileName = filePath;
                object heading2 = WdBuiltinStyle.wdStyleHeading2;
                object heading3 = WdBuiltinStyle.wdStyleHeading3;

                _Application wordApp = new Application();
                wordApp.Visible = true;
                _Document wordDoc = wordApp.Documents.Open(ref fileName, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

                int ii = 0;
                //目录
                foreach (DataRow dr in dt.Rows)
                {
                    string dept = dr["title"].ToString();
                    //string type = dr["Type"].ToString();
                    Paragraph oPara0 = wordDoc.Content.Paragraphs.Add(ref oMissing);
                    oPara0.Range.Text = string.Format("{0}-{1}", ii + 1, dept);
                    //oPara0.Range.Font.Bold = 1;
                    //oPara0.Format.SpaceAfter = 5;
                    oPara0.Range.Select();
                    oPara0.set_Style(ref heading2);
                    oPara0.Range.InsertParagraphAfter();
                    int jj = 0;
                    //子目录
                    foreach (DataRow dr1 in dt2.Rows)
                    {
                        string type = dr1["name"].ToString();
                        string interRoute = dr1["route"].ToString();
                        string ajaxType = dr1["type"].ToString();
                        string controllerName = dr1["name"].ToString();
                        string interDescription = dr1["summary"].ToString();

                        int count = distinctList3.Where(w => w.MethodType == type).Count();
                        int row = count + 5;
                        int column = 5;
                        object ncount = 1;

                        //请求参数table

                        wordApp.Selection.MoveDown(ref wdLine, ref ncount, ref oMissing);
                        wordApp.Selection.TypeParagraph();
                        Paragraph oPara1 = wordDoc.Content.Paragraphs.Add(ref oMissing);
                        oPara1.Range.Select();
                        oPara1.Range.Text = string.Format("{0}-{1}、{2}", ii + 1, jj + 1, interDescription);

                        oPara1.set_Style(ref heading3);
                        oPara1.Range.InsertParagraphAfter();
                        wordApp.Selection.MoveDown(ref wdLine, ref ncount, ref oMissing);
                        wordApp.Selection.TypeParagraph();
                        //设置表格
                        Table table = wordDoc.Tables.Add(wordApp.Selection.Range, row, column, ref oMissing, ref oMissing);

                        table.Borders.OutsideLineStyle = WdLineStyle.wdLineStyleSingle;
                        table.Borders.InsideLineStyle = WdLineStyle.wdLineStyleSingle;
                        table.Range.Font.Bold = 0;
                        table.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthAuto;
                        table.Columns[1].Width = 120f;
                        table.Columns[2].Width = 60f;
                        table.Columns[3].Width = 150f;
                        table.Columns[4].Width = 60f;
                        table.Columns[5].Width = 60f;
                        //列的合并
                        Cell cell = table.Cell(1, 2);
                        cell.Merge(table.Cell(1, 5));
                        Cell cell2 = table.Cell(2, 2);
                        cell2.Merge(table.Cell(2, 5));
                        Cell cell3 = table.Cell(3, 2);
                        cell3.Merge(table.Cell(3, 5));
                        Cell cell4 = table.Cell(4, 2);
                        cell4.Merge(table.Cell(4, 5));
                        //赋值
                        table.Cell(1, 1).Range.Text = "接口路由:";
                        table.Cell(2, 1).Range.Text = "请求类型:";
                        table.Cell(3, 1).Range.Text = "控制器名称:";
                        table.Cell(4, 1).Range.Text = "接口说明";

                        table.Cell(5, 1).Range.Text = "编号";
                        table.Cell(5, 2).Range.Text = "类型";
                        table.Cell(5, 3).Range.Text = "注解";
                        table.Cell(5, 4).Range.Text = "字段长度";
                        table.Cell(5, 5).Range.Text = "是否必填";

                        table.Cell(1, 2).Range.Text = interRoute;
                        table.Cell(2, 2).Range.Text = ajaxType;
                        table.Cell(3, 2).Range.Text = controllerName;
                        table.Cell(4, 2).Range.Text = interDescription;
                        int kk = 6;
                        //table值
                        foreach (DataRow dr2 in dt3.Rows)
                        {
                            if (dr2["MethodType"].ToString() != type)
                            {
                                continue;
                            }

                            if (dr2["type"].ToString() == "array")
                            {
                                table.Cell(kk, 1).Range.Shading.ForegroundPatternColor = WdColor.wdColorYellow; //背景颜色
                            }
                            //返回实体
                            if (dr2["paramType"].ToString() == "2")
                            {
                                table.Cell(kk, 1).Range.Shading.ForegroundPatternColor = WdColor.wdColorGreen; //背景颜色
                            }
                            table.Cell(kk, 1).Range.Text = dr2["code"].ToString();
                            table.Cell(kk, 2).Range.Text = dr2["type"].ToString();
                            table.Cell(kk, 3).Range.Text = dr2["description"].ToString();
                            table.Cell(kk, 4).Range.Text = dr2["maxLength"].ToString();
                            table.Cell(kk, 5).Range.Text = dr2["isMust"].ToString();
                            kk++;
                        }

                        table.Cell(kk - 1, 5).Range.Select();

                        wordApp.Selection.MoveDown(ref wdLine, ref ncount, ref oMissing);//移动焦点
                        wordApp.Selection.TypeParagraph();//插入段落

                        jj++;
                    }
                    ii++;
                }

                //保存
                wordDoc.Save();
                wordDoc.Close(ref oMissing, ref oMissing, ref oMissing);
                wordApp.Quit(ref oMissing, ref oMissing, ref oMissing);
                //MessageFilter.Revoke();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
            }
        }

        private static void CreateFile(string filePath)
        {
            if (!File.Exists(filePath))
            {
                using (FileStream fs = File.Create(filePath))
                {

                }
            }
        }

        private System.Data.DataTable ToDataTable<T>(List<T> items)
        {
            var tb = new System.Data.DataTable(typeof(T).Name);

            PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (PropertyInfo prop in props)
            {
                Type t = GetCoreType(prop.PropertyType);
                tb.Columns.Add(prop.Name, t);
            }

            foreach (T item in items)
            {
                var values = new object[props.Length];

                for (int i = 0; i < props.Length; i++)
                {
                    values[i] = props[i].GetValue(item, null);
                }

                tb.Rows.Add(values);
            }

            return tb;
        }

        /// <summary>
        /// Determine of specified type is nullable
        /// </summary>
        public static bool IsNullable(Type t)
        {
            return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
        }

        /// <summary>
        /// Return underlying type if type is Nullable otherwise return the type
        /// </summary>
        public static Type GetCoreType(Type t)
        {
            if (t != null && IsNullable(t))
            {
                if (!t.IsValueType)
                {
                    return t;
                }
                else
                {
                    return Nullable.GetUnderlyingType(t);
                }
            }
            else
            {
                return t;
            }
        }
    }

4.引用包:

Newtonsoft.Json

Newtonsoft.Json.Linq

Microsoft.Office.Interop.Word

5:文件生成预览:

 

6.代码考下来能够直接使用,如有又更优方案欢迎指点:

 

posted @ 2021-09-16 22:23  有意思7  阅读(2165)  评论(2编辑  收藏  举报