前言
回顧之前的兩篇Swagger做Api介面檔案,我們大體上學會了如何在net core3.1的專案基礎上,搭建一套自動生產API介面說明檔案的框架,
本來在Swagger的基礎上,前后端開發人員在開發生產期間,可以借此進行更加便捷的溝通交流,可是總有些時候,遇到一些難纏的,又不講道理,偏偏覺得將Swagger檔案地址丟給客戶會不夠正式!死活要一份word檔案,

可是這個時候,如果介面數量上百個,甚至更多,一個一個手動輸入word,那將是一筆耗時的作業,但卻有什么辦法可以解決呢?
對了,利用Swagge生成的Json檔案轉換為word檔案不就可以了嗎?
思路
1. 獲取Swagger介面檔案的Json檔案
2. 決議Json檔案資料填充到Html的表格中
3.根據生成的html轉work檔案
模板
檔案模板
|
|
|||||||||||
|
URL |
/api/Movie/AddMovie |
||||||||||
|
請求方式 |
Post |
||||||||||
|
引數名 |
引數型別 |
是否必填 |
說明 |
||||||||
|
id |
Query |
False |
影視ID |
||||||||
|
Name |
Query |
False |
電影名稱 |
||||||||
|
Type |
Query |
False |
電影型別 |
||||||||
|
狀態碼 |
說明 |
||||||||||
|
200 |
Success |
||||||||||
|
示例 |
|||||||||||
|
請求引數 |
|
||||||||||
|
回傳值 |
|
||||||||||
開始
一、根據Swagger版本獲取Json資料
1.通過Swagger原始碼檔案可以看到

可以拿到swagger生成的檔案資料,所以我們可以新建一個控制器SwaggerController.cs,
private readonly SwaggerGenerator _swaggerGenerator; public SwaggerController(SwaggerGenerator swaggerGenerator) { _swaggerGenerator = swaggerGenerator; } /// <summary> /// 匯出檔案 /// </summary> /// <param name="type">檔案型別</param> /// <param name="version">版本號V1</param> /// <returns></returns> [HttpGet] public FileResult ExportWord(string type,string version) { string contenttype = string.Empty; var model = _swaggerGenerator.GetSwagger(version); //1. 根據指定版本獲取指定版本的json物件, }
2. 在Startup.cs檔案中,利用net core的ioc容器,注入SwaggerGenerator實體化,這樣在后面的呼叫中可以直接使用這個方法
services.AddScoped<SwaggerGenerator>(); //注入SwaggerGenerator,后面可以直接使用這個方法
二、檔案資料填充到Html的表格中
根據上面獲取的model檔案資料,這個時候,我們利用Razor檔案,結合html的table模板,將資料遍歷填充到頁面中,生成完整的頁面
Html模板
@using Swashbuckle.AspNetCore.Swagger; <!DOCTYPE html> <html> <head> <title>Swagger API檔案代碼檔案</title> <style type='text/css'> table, table td, table th { border: 1px solid #000000; border-collapse: collapse; } table { table-layout: fixed; word-break: break-all; } tr { height: 20px; font-size: 12px; } </style> </head> <body> <div style='width:1000px; margin: 0 auto'> <span><i>Word介面檔案</i></span> <h1 align="center">@Model.Info.Title</h1> <h1 align="center">介面檔案 @Model.Info.Version</h1> <h4>聯系方式</h4> <span>作者:@Model.Info.Contact.Name</span> <br> <a href="mailto:@Model.Info.Contact.Email" rel="noopener noreferrer" class="link">Send email to Xunit.Core</a> <br> <a href="@Model.Info.Contact.Url" target="_blank" rel="noopener noreferrer" class="link">@Model.Info.Contact.Name - Website</a> <br> <h3>介面描述</h3> <span>@Model.Info.Description</span> <br> <table border='1' cellspacing='0' cellpadding='0' style="table-layout: fixed; word-break: break-all;border: 1px solid #000000;border-collapse: collapse;" width='100%'> <tr style="border: 1px solid #000000;border-collapse: collapse;"> <td align="center" style="background-color: rgb(84, 127, 177);">說明</td> <td></td> </tr> <tr style="border: 1px solid #000000;border-collapse: collapse;"> <td align="center" style="background-color: rgb(84, 127, 177);">型別</td> <td></td> </tr> </table> @foreach (var item in Model.Paths) { if (item.Value.Operations != null) { foreach (var operation in item.Value.Operations) { <h3>@operation.Value.Summary</h3> <table border='1' cellspacing='0' cellpadding='0' width='100%' style="table-layout: fixed; word-break: break-all;border: 1px solid #000000;border-collapse: collapse;"> <tr style="background-color: rgb(84, 127, 177);" align="center"> <td colspan='5'></td> </tr> <tr style="border: 1px solid #000000;border-collapse: collapse;"> <td style="border: 1px solid #000000;border-collapse: collapse;">URL</td> <td colspan='4'>@item.Key</td> </tr> <tr style="border: 1px solid #000000;border-collapse: collapse;"> <td style="border: 1px solid #000000;border-collapse: collapse;">請求方式</td> <td colspan='4'> @operation.Key </td> </tr> @if (operation.Value.Parameters != null && operation.Value.Parameters.Count > 0) { <tr style="background-color: rgb(84, 127, 177);" align='center'> <td style="border: 1px solid #000000;border-collapse: collapse;">引數名</td> <td style="border: 1px solid #000000;border-collapse: collapse;">引數型別</td> <td style="border: 1px solid #000000;border-collapse: collapse;">是否必填</td> <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='2'>說明</td> </tr> @foreach (var param in operation.Value.Parameters) { <tr align='center' style="border: 1px solid #000000;border-collapse: collapse;"> <td style="border: 1px solid #000000;border-collapse: collapse;">@param.Name</td> <td style="border: 1px solid #000000;border-collapse: collapse;">@param.In</td> <td style="border: 1px solid #000000;border-collapse: collapse;">@param.Required</td> <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='2'>@param.Description</td> </tr> } } <tr style="background-color: rgb(84, 127, 177);" align='center'> <td style="border: 1px solid #000000;border-collapse: collapse;">狀態碼</td> <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='4'>說明</td> </tr> @if (operation.Value.Responses != null && operation.Value.Responses.Count > 0) { foreach (var response in operation.Value.Responses) { <tr align='center' style="border: 1px solid #000000;border-collapse: collapse;"> <td style="border: 1px solid #000000;border-collapse: collapse;">@response.Key</td> <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='4'>@response.Value.Description</td> </tr> } } <tr style="background-color: rgb(84, 127, 177);"> <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='5'>示例</td> </tr> <tr style="height: 40px;" style="border: 1px solid #000000;border-collapse: collapse;"> <td style="background-color: rgb(84, 127, 177);">請求引數</td> <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='4'></td> </tr> <tr style="height: 40px;" style="border: 1px solid #000000;border-collapse: collapse;"> <td style="background-color: rgb(84, 127, 177);">回傳值</td> <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='4'></td> </tr> </table> <br> } } } </div> </body> </html>
將資料遍歷到靜態頁面中,
/// <summary> /// 將資料遍歷靜態頁面中 /// </summary> /// <param name="templatePath">靜態頁面地址</param> /// <param name="model">獲取到的檔案資料</param> /// <returns></returns> public static string GeneritorSwaggerHtml(string templatePath, OpenApiDocument model) { var template = System.IO.File.ReadAllText(templatePath); var result = Engine.Razor.RunCompile(template, "i3yuan", typeof(OpenApiDocument), model); return result; }
三、根據生成的html轉work檔案
/// <summary> /// 靜態頁面轉檔案 /// </summary> /// <param name="html">靜態頁面html</param> /// <param name="type">檔案型別</param> /// <param name="contenttype">背景關系型別</param> /// <returns></returns> public Stream SwaggerConversHtml(string html, string type, out string contenttype) { string fileName = Guid.NewGuid().ToString() + type; //檔案存放路徑 string webRootPath = _hostingEnvironment.WebRootPath; string path = webRootPath + @"\Files\TempFiles\"; var addrUrl = path + $"{fileName}"; FileStream fileStream = null; var provider = new FileExtensionContentTypeProvider(); contenttype = provider.Mappings[type]; try { if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } var data =https://www.cnblogs.com/i3yuan/p/ Encoding.Default.GetBytes(html); var stream = ByteHelper.BytesToStream(data); //創建Document實體 Document document = new Document(); //加載HTML檔案 document.LoadFromStream(stream, FileFormat.Html, XHTMLValidationType.None); //保存為Word document.SaveToFile(addrUrl, FileFormat.Docx); document.Close(); fileStream = File.Open(addrUrl, FileMode.OpenOrCreate); var filedata =https://www.cnblogs.com/i3yuan/p/ ByteHelper.StreamToBytes(fileStream); var outdata =https://www.cnblogs.com/i3yuan/p/ ByteHelper.BytesToStream(filedata); return outdata; } catch (Exception) { throw; } finally { if (fileStream != null) fileStream.Close(); if (File.Exists(addrUrl)) File.Delete(addrUrl);//刪掉檔案 } }
public class ByteHelper { public static byte[] StreamToBytes(Stream stream) { byte[] bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); // 設定當前流的位置為流的開始 stream.Seek(0, SeekOrigin.Begin); return bytes; } /// 將 byte[] 轉成 Stream public static Stream BytesToStream(byte[] bytes) { Stream stream = new MemoryStream(bytes); return stream; } }
四、最終效果
將html轉換為word后,我們就可以看到帶有 .doc 的效果了!差不多是如下效果

總結
1. 到這基本就結束了,通過簡易的幾個介面的方式,展示了如何通過將Swagger介面檔案生成word檔案,可以根據自己的html模板生成各式的word樣式檔案說明,
2.寫這篇番外主要是因為之前介紹了關于如何使用Swagger生成在線檔案,但實際作業中,可能也會遇到這種要各種正式word檔案的客戶,所以在此分享一些想法和思路,同時希望大家不吝指教,
3.后續還會不斷修改和完善,可以更多的生成不同的檔案型別和按需生成不同版本的介面檔案,持續更新,,,
4 .注:搜索關注公眾號【DotNet技術谷】--回復【檔案生成器】,可獲取本篇Swagger轉換work檔案
5. 參考資料:Spire.Doc檔案 、Swagger開源地址
6.原始碼下載
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/46992.html
標籤:.NET Core
