swagger导出到pdf、html文档

2022-09-06 11:18:17

最近工作中接到一个任务,就是项目要一份接口文档,之前项目用的文档是swagger的自动生成的,再导入一些好看的UI(也没好看到哪里去,比如springfox-swagger-ui)来使用,其实也是一直这样。但是项目的接口太多了,这要是让我去手写到文档,可能得写到兔年了。于是乎我在想,能不能把swagger的接口导出来,直接完成任务。
起先,我在项目的swagger上面看到有导出这个功能,于是我很高兴得点击了其中 的一个,然后它就转呀转,转了好几个小时都还停,那个时候我就绝望了,所以我就去网上搜索资料,各个方法都去尝试一下,发现其实是可以的,可能是因为我那个项目太大了,接口太多,一直转个不停。后来我还尝试了其他的实现办法,找到了另外两个,遇到了很多的坑,这里一起介绍。

swagger UI离线文档

首先swagger有个比原生好看的UI(swagger基本配置我就不过多介绍,网上一大堆),叫springfox-swagger-ui,这个UI相对于原生的UI好看了很多的,更加符合中国人的审美。下面是springboot整合swagger-bootstrap-ui的介绍。

  1. 导入依赖springfox-swagger-ui
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>swagger-bootstrap-ui</artifactId><version>1.9.6</version><!-- 截止发布,最高版本是1.9.6 --></dependency>
  1. 在swagger的配置类上加上注解

导入UI依赖

  1. 静态资源配置

放行静态资源
访问地址:
http:// {ip地址}: {端口号} /doc.html
打开页面后是这样的,提供了拷贝md格式的文本,可以将文本复制到软件 Typora 中去查看
swagger文档页面
拷贝到Typora后
拷贝出来的接口描述

但是我们项目使用的是另外一个UI,叫 knife4j,这个其实是 swagger-bootstrap-ui 的增强版,增加了很多的功能,详情参考官方

  1. 导入依赖
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>2.0.7</version><!-- 截止发布,最高版本是3.0.3--></dependency>

说明:3.0.3 版本的knife4j依赖包需要更高版本的swagger依赖包,我用 2.9.2版本的时候报错

<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency>

报错:

 springfox/documentation/common/ClassPresentInClassPathCondition

升级版本即可

<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>3.0.0</version></dependency>
  1. 在swagger的配置类上加上注解
    把 swagger-bootstrap-ui 的注解 @EnableSwaggerBootstrapUI 改成 @EnableKnife4j 即可
    添加@EnableKnife4j注解
  2. 静态资源配置
    静态资源配置资源配置和 swagger-bootstrap-ui 一样
    访问的地址一样: http:// {ip地址}: {端口号} /doc.html
    会发现这里增加了导出的功能,比如导出md 、work文档、html等不同类型的接口文档
    swagger UI自带的导出功能
    试着是可以用的,但是下载出来的work格式不敢恭维

导出后的work文档
不过html接口页面还是挺好看的
导出后的html文档

我之所以后面还去尝试其他的办法,是因为开头说过,点击下载后一直在转圈,可能是因为版本不够高,亦或者接口太多。
在这里插入图片描述

所以我在网上参考了其他人的办法,我也遇到了很多的坑

代码实现导出功能

  1. 导入依赖
<dependency><groupId>io.github.swagger2markup</groupId><artifactId>swagger2markup</artifactId><version>1.3.3</version></dependency>
  1. 编写代码
importio.github.swagger2markup.GroupBy;importio.github.swagger2markup.Language;importio.github.swagger2markup.Swagger2MarkupConfig;importio.github.swagger2markup.Swagger2MarkupConverter;importio.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;importio.github.swagger2markup.markup.builder.MarkupLanguage;importjava.net.MalformedURLException;importjava.net.URL;importjava.nio.file.Paths;/**
 * @author weiming wu
 * @date 2022/1/26 11:49
 */publicclassSwaggerUtils{privatestaticfinalString url="http://localhost:8003/v2/api-docs";/**
     * 生成AsciiDocs格式文档
     * @throws MalformedURLException
     */publicstaticvoidgenerateAsciiDocs()throwsMalformedURLException{Swagger2MarkupConfig config=newSwagger2MarkupConfigBuilder().withMarkupLanguage(MarkupLanguage.ASCIIDOC).withOutputLanguage(Language.ZH).withPathsGroupedBy(GroupBy.TAGS).withGeneratedExamples().withoutInlineSchema().build();Swagger2MarkupConverter.from(newURL(url)).withConfig(config).build().toFolder(Paths.get("./docs/asciidoc/generated"));}/**
     * 生成AsciiDocs格式文档,并汇总成一个文件
     * @throws MalformedURLException
     */publicstaticvoidgenerateAsciiDocsToFile()throwsMalformedURLException{Swagger2MarkupConfig config=newSwagger2MarkupConfigBuilder().withMarkupLanguage(MarkupLanguage.ASCIIDOC).withOutputLanguage(Language.ZH).withPathsGroupedBy(GroupBy.TAGS).withGeneratedExamples().withoutInlineSchema().build();Swagger2MarkupConverter.from(newURL(url)).withConfig(config).build().toFile(Paths.get("./docs/asciidoc/generated/all"));}/**
     * 生成Markdown格式文档
     * @throws MalformedURLException
     */publicstaticvoidgenerateMarkdownDocs()throwsMalformedURLException{Swagger2MarkupConfig config=newSwagger2MarkupConfigBuilder().withMarkupLanguage(MarkupLanguage.MARKDOWN).withOutputLanguage(Language.ZH).withPathsGroupedBy(GroupBy.TAGS).withGeneratedExamples().withoutInlineSchema().build();Swagger2MarkupConverter.from(newURL(url)).withConfig(config).build().toFolder(Paths.get("./docs/markdown/generated"));}/**
     * 生成Markdown格式文档,并汇总成一个文件
     * @throws MalformedURLException
     */publicstaticvoidgenerateMarkdownDocsToFile()throwsMalformedURLException{Swagger2MarkupConfig config=newSwagger2MarkupConfigBuilder().withMarkupLanguage(MarkupLanguage.MARKDOWN).withOutputLanguage(Language.ZH).withPathsGroupedBy(GroupBy.TAGS).withGeneratedExamples().withoutInlineSchema().build();Swagger2MarkupConverter.from(newURL(url)).withConfig(config).build().toFile(Paths.get("./docs/markdown/generated/wwm"));}/**
     * 生成Confluence格式文档
     * @throws MalformedURLException
     */publicstaticvoidgenerateConfluenceDocs()throwsMalformedURLException{Swagger2MarkupConfig config=newSwagger2MarkupConfigBuilder().withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP).withOutputLanguage(Language.ZH).withPathsGroupedBy(GroupBy.TAGS).withGeneratedExamples().withoutInlineSchema().build();Swagger2MarkupConverter.from(newURL(url)).withConfig(config).build().toFolder(Paths.get("./docs/confluence/generated"));}/**
     * 生成Confluence格式文档,并汇总成一个文件
     * @throws MalformedURLException
     */publicstaticvoidgenerateConfluenceDocsToFile()throwsMalformedURLException{Swagger2MarkupConfig config=newSwagger2MarkupConfigBuilder().withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP).withOutputLanguage(Language.ZH).withPathsGroupedBy(GroupBy.TAGS).withGeneratedExamples().withoutInlineSchema().build();Swagger2MarkupConverter.from(newURL(url)).withConfig(config).build().toFile(Paths.get("./docs/confluence/generated/all"));}}

说明:

(1)这个依赖只能生成三种格式的文档 adoc、md 和 txt格式的文件

(2) 这里需要使用到swagger的json格式,代码是通过json数据来生成相应的文档的

(3)如果是使用目录路径,会生成四个文件,分别是controller、 实体类,接口等相关信息;

如果是指定一个文件,可以直接生成一个总文件

(4)注意:代码中用到的url是swagger的json格式的数据,访问接口一般是

http://{ip地址}:{端口}/项目访问根路径/v2/api-docs

生成adoc文件
3. 调用接口执行
调用执行想要的文件格式的接口即可,这里调用方法 generateAsciiDocsToFile 生成的ASSIIDOC文件如下:
生成的ASSIIDOC文件

上面的代码生成的目录结构如下:

src--docs----confluence------generated--------definitions.txt--------overview.txt--------paths.txt--------security.txt----markdown------generated--------definitions.md--------overview.md--------paths.md--------security.md
  1. 导出 html、pdf、xml 格式
    如果要生成其他的格式,需要使用到插件,这个插件是通过第一步生成的ASSIIDOC文件来生成其他格式的接口文档的
asciidoctor-maven-plugin

在pom文件中添加插件

<plugin><groupId>org.asciidoctor</groupId><artifactId>asciidoctor-maven-plugin</artifactId><version>1.5.3</version><!-- <version>2.0.0-RC.1</version> --><!-- Include Asciidoctor PDF for pdf generation --><dependencies><dependency><groupId>org.asciidoctor</groupId><artifactId>asciidoctorj-pdf</artifactId><version>1.5.0-alpha.10.1</version></dependency><dependency><groupId>org.jruby</groupId><artifactId>jruby-complete</artifactId><version>1.7.21</version></dependency></dependencies><configuration><sourceDirectory>./docs/asciidoc/generated</sourceDirectory><outputDirectory>./docs/asciidoc/html</outputDirectory><backend>html</backend><!-- <outputDirectory>./docs/asciidoc/pdf</outputDirectory>
                    <backend>pdf</backend> --><headerFooter>true</headerFooter><doctype>book</doctype><sourceHighlighter>coderay</sourceHighlighter><attributes><!-- 菜单栏在左边 --><toc>left</toc><!-- 多标题排列 --><toclevels>3</toclevels><!-- 自动打数字序号 --><sectnums>true</sectnums></attributes></configuration></plugin>

说明:
configuration.sourceDirectory :该标签用于指定利用ASSIIDOC文件(第一步中代码生成的ASSIIDOC文件)生成html的资源目录,即该标签需要与swagger2markup生成的ASSIIDOC文件在同一个目录,一般来说该标签目录设置与swagger2markup插件configuration.outputDir标签内容一致即可

  1. 执行插件
    这里直接执行右边maven菜单中的插件即可:asclidoctor:process-asclidoc

在这里插入图片描述
生成的html如图:

生成的htm接口文档
生成的htm接口文档

生成的pdf:
生成的pdf接口文档
生成的pdf接口文档

插件实现导出功能

  1. pom导入插件
<plugin><groupId>io.github.swagger2markup</groupId><artifactId>swagger2markup-maven-plugin</artifactId><version>1.3.3</version><configuration><swaggerInput>http://localhost:8003/v2/api-docs</swaggerInput><!-- 生成asciidoc格式 --><outputFile>src/docs/asciidoc/generated/all</outputFile><!--                    <outputDir>src/docs/asciidoc/generated</outputDir>--><!-- 生成markdown格式 --><!-- <outputFile>src/docs/markdown/generated/all</outputFile>--><config><!-- 生成asciidoc格式 --><swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage><!-- 生成markdown格式 --><!--                        <swagger2markup.markupLanguage>MARKDOWN</swagger2markup.markupLanguage>--><swagger2markup.outputLanguage>ZH</swagger2markup.outputLanguage><swagger2markup.generatedExamplesEnabled>true</swagger2markup.generatedExamplesEnabled><swagger2markup.inlineSchemaEnabled>false</swagger2markup.inlineSchemaEnabled><swagger2markup.pathsGroupedBy>TAGS</swagger2markup.pathsGroupedBy></config></configuration></plugin>

说明:

(1)configuration.swaggerInput :该标签内容需修改为需要导出接口项目的/v2/api-docs 路径
(2)configuration.outputFile :该标签为生成单个文档指定文档生成路径,如生成txt、md等文件,可随意修改;但注意,该标签与outputDir标签二选一;
(3)configuration.outputDir :该标签为生成多个文档指定文档目录,如生成ASCIIDOC文件,该类文件可用于结合asciidoctor插件生成html文件;
(4)configuration.config :该标签内定义的swagger2markup.markupLanguage子标签,只能同时存在一个,如指定生成markdown 即md文件时,就不能指定生成其他类型;
注意:指定生成ASCIIDOC文件类型时,需与configuration.outputDir标签配合使用

  1. 执行插件
    依旧直接执行右边的maven菜单中的插件: swagger2markup:convertSwagger2markup
    不过我执行的时候,一直报下面这个错误:
ch.netzwerg.paleo.ColumnIds$StringColumnId

网上的答案都是一样的,就是
在这里插入图片描述

添加或者替换<repositories><repository><snapshots><enabled>false</enabled></snapshots><id>jcenter-releases</id><name>jcenter</name><url>http://jcenter.bintray.com</url></repository></repositories>


再不济就是改成这样<repositories><repository><id>spring-libs-milestone</id><url>https://repo.spring.io/libs-milestone</url><snapshots><enabled>false</enabled></snapshots></repository><!-- jhipster-needle-maven-repository--></repositories><pluginRepositories><pluginRepository><id>spring-plugins-release</id><url>https://repo.spring.io/plugins-release</url><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories>

参考:https://blog.csdn.net/oceanBin1995/article/details/104833086

但是以上两个方法我都没解决问题,所以这里我其实采用的是第一种方法中的第一步。
说明:这个插件的作用其实相当于第一步中的执行代码,都是为了生成源文件ASSIIDOC

  1. 导出 html、pdf、xml 格式

这个步骤同通过代码导出文档中的第4步一样,这里 不再赘述。

解决pdf文档乱码空白问题

如果导出成功,但是pdf文档出现乱码或者文字空白的情况,解决办法如下:

  1. 打开asciidoctorj-pdf jar包
maven仓库中的asciidoctorj
  • 作者:六月的北回归线
  • 原文链接:https://blog.csdn.net/weixin_43726137/article/details/122713063
    更新时间:2022-09-06 11:18:17