记录工作中遇到的问题,swagger生成html导出docx,pdf,xml,svg,doc
思路
获取Swagger接口文档的Json文件
解析Json文件数据填充到Html的表格中
根据生成的html转work文档
nuget包
根据开发环境版本自选
RazorEngine.NetCore
Spire.Doc
Swashbuckle.AspNetCore
image.png
帮助类
ByteHelper
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;
}
}
HtmlHelper**
public class HtmlHelper
{
/// <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;
}
}
SpireDocHelper
根据生成的html转work文档
public class SpireDocHelper
{
private readonly IWebHostEnvironment _hostingEnvironment;
public SpireDocHelper(IWebHostEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}
/// <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 = Encoding.Default.GetBytes(html);
var stream = ByteHelper.BytesToStream(data);
//创建Document实例
Document document = new Document();
//加载HTML文档
document.LoadFromStream(stream, FileFormat.Html, XHTMLValidationType.None);
switch (type)
{
case ".docx":
document.SaveToFile(addrUrl, FileFormat.Docx);
break;
case ".pdf":
document.SaveToFile(addrUrl, FileFormat.PDF);
break;
case ".html":
//document.SaveToFile(addrUrl, FileFormat.Html);
//当然了,html 如果不用spire,也可以直接生成
FileStream fs = new FileStream(addrUrl, FileMode.Append, FileAccess.Write, FileShare.None);//html直接写入不用spire.doc
StreamWriter sw = new StreamWriter(fs); // 创建写入流
sw.WriteLine(html); // 写入Hello World
sw.Close(); //关闭文件
fs.Close();
break;
case ".xml":
document.SaveToFile(addrUrl, FileFormat.Xml);
break;
case ".svg":
document.SaveToFile(addrUrl, FileFormat.SVG);
break;
default:
//保存为Word
document.SaveToFile(addrUrl, FileFormat.Docx);
break;
}
document.Close();
fileStream = File.Open(addrUrl, FileMode.OpenOrCreate);
var filedata = ByteHelper.StreamToBytes(fileStream);
var outdata = ByteHelper.BytesToStream(filedata);
return outdata;
}
catch (Exception)
{
throw;
}
finally
{
if (fileStream != null)
fileStream.Close();
if (File.Exists(addrUrl))
File.Delete(addrUrl);//删掉文件
}
}
}
4.js、css、cshtml
文档作用:增加导出按钮
下载后放在wwwroot路径下
下载链接:pan.baidu.com/s/14igpqgh_…
提取码:v6o7 image.png
SwaggerController
[Route("api/[controller]/[action]")]
[ApiExplorerSettings(IgnoreApi = true)]
public class SwaggerController: ControllerBase
{
private readonly IWebHostEnvironment _webHostEnvironment;
private readonly SwaggerGenerator _swaggerGenerator;
private readonly SpireDocHelper _spireDocHelper;
public SwaggerController(IWebHostEnvironment hostingEnvironment,SpireDocHelper spireDocHelper,SwaggerGenerator swaggerGenerator)
{
_webHostEnvironment = hostingEnvironment;
_spireDocHelper = spireDocHelper;
_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对象。
var html = HtmlHelper.GeneritorSwaggerHtml($"{_webHostEnvironment.WebRootPath}\\SwaggerDoc.cshtml", model); //2. 根据模板引擎生成html
var op = _spireDocHelper.SwaggerConversHtml(html, type, out contenttype); //3.将html导出文件类型
return File(op, contenttype, $"XUnit.Core接口文档{type}");
}
}
复制代码
5、startup配置
ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<SwaggerGenerator>(); //注入SwaggerGenerator,后面可以直接使用这个方法
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("V1", new OpenApiInfo
{
Version = "V1", //版本
Title = $"项目名称 接口文档-NetCore3.1", //标题
Description = $"项目名称 Http API v1", //描述
});
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)
//var basePath = AppContext.BaseDirectory;
var xmlPath = Path.Combine(basePath, "项目名称.xml");//这个就是刚刚配置的xml文件名
// c.IncludeXmlComments(xmlPath);//默认的第二个参数是false,对方法的注释
c.IncludeXmlComments(xmlPath,true); // 这个是controller的注释
});
services.AddScoped<SpireDocHelper>();
services.AddControllers();
}
复制代码
Configure
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
#region Swagger 只在开发环节中使用
app.UseSwagger();
app.UseSwaggerUI(c => {
c.SwaggerEndpoint($"/swagger/V1/swagger.json", $"项目名称 V1");
c.RoutePrefix = string.Empty; //如果是为空 访问路径就为 根域名/index.html,注意localhost:8001/swagger是访问不到的
//路径配置,设置为空,表示直接在根域名(localhost:8001)访问该文件
// c.RoutePrefix = "swagger"; // 如果你想换一个路径,直接写名字即可,比如直接写c.RoutePrefix = "swagger"; 则访问路径为 根域名/swagger/index.html
c.DocumentTitle = "项目名称 在线文档调试";
#region 自定义样式
//css 注入
c.InjectStylesheet("/css/swaggerdoc.css");
c.InjectStylesheet("/css/app.min.css");
//js 注入
c.InjectJavascript("/js/jquery.js");
c.InjectJavascript("/js/swaggerdoc.js");
c.InjectJavascript("/js/app.min.js");
#endregion
});
#endregion
}
app.UseRouting();
app.UseAuthorization();
app.UseStaticFiles();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
参考:www.cnblogs.com/i3yuan/