Swagger UI 导出文档

生成静态 HTML 文档

使用 Swagger2markup

Swagger2markup 是一个能将 Swagger JSON 或 YAML 文件转换为 AsciiDoc 或 Markdown 文档的工具。结合 AsciiDoctor,可以将文档转换为 HTML 或 PDF 格式。

添加 Maven 依赖:

实例

<dependencies>
    <dependency>
        <groupId>io.github.swagger2markup</groupId>
        <artifactId>swagger2markup</artifactId>
        <version>1.3.3</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.asciidoctor</groupId>
            <artifactId>asciidoctor-maven-plugin</artifactId>
            <version>2.2.2</version>
            <dependencies>
                <dependency>
                    <groupId>org.asciidoctor</groupId>
                    <artifactId>asciidoctorj-pdf</artifactId>
                    <version>1.6.2</version>
                </dependency>
            </dependencies>
            <configuration>
                <sourceDirectory>target/asciidoc</sourceDirectory>
                <outputDirectory>target/generated-docs</outputDirectory>
                <backend>html5</backend> <!-- 或者 'pdf' -->
                <attributes>
                    <toc>left</toc>
                    <toclevels>3</toclevels>
                </attributes>
            </configuration>
        </plugin>
    </plugins>
</build>

创建测试类生成文档:

实例

import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.net.URL;
import java.nio.file.Paths;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class SwaggerDocumentationTest {

    @Test
    public void generateAsciiDoc() throws Exception {
        // 设置输出目录
        final String outputDir = "target/asciidoc";
       
        // Swagger2Markup 配置
        Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.ASCIIDOC)
                .withOutputLanguage(java.util.Locale.CHINA)
                .withGeneratedExamples()
                .withPathsGroupedBy(io.github.swagger2markup.GroupBy.TAGS)
                .build();

        // 从 OpenAPI JSON 文件生成 AsciiDoc 文件
        Swagger2MarkupConverter.from(new URL("http://localhost:8080/v3/api-docs"))
                .withConfig(config)
                .build()
                .toFolder(Paths.get(outputDir));
    }
}

运行测试并生成文档:

# 生成 AsciiDoc
mvn test

# 将 AsciiDoc 转换为 HTML
mvn asciidoctor:process-asciidoc

# 生成的文档位于 target/generated-docs 目录

生成 PDF 文档

使用 Asciidoctor-PDF

基于前面生成的 AsciiDoc 文件,可以使用 Asciidoctor-PDF 生成 PDF 文档:

1. 修改 Maven 配置:

实例

<plugin>
    <groupId>org.asciidoctor</groupId>
    <artifactId>asciidoctor-maven-plugin</artifactId>
    <version>2.2.2</version>
    <dependencies>
        <dependency>
            <groupId>org.asciidoctor</groupId>
            <artifactId>asciidoctorj-pdf</artifactId>
            <version>1.6.2</version>
        </dependency>
    </dependencies>
    <configuration>
        <sourceDirectory>target/asciidoc</sourceDirectory>
        <outputDirectory>target/generated-docs</outputDirectory>
        <backend>pdf</backend>
        <attributes>
            <toc>left</toc>
            <toclevels>3</toclevels>
            <icons>font</icons>
            <source-highlighter>coderay</source-highlighter>
            <pagenums>true</pagenums>
            <pdf-stylesdir>${project.basedir}/src/main/resources/theme</pdf-stylesdir>
            <pdf-style>custom</pdf-style>
            <pdf-fontsdir>${project.basedir}/src/main/resources/fonts</pdf-fontsdir>
        </attributes>
    </configuration>
</plugin>

自定义 PDF 样式 src/main/resources/theme/custom-theme.yml:

实例

font:
  catalog:
    # 中文字体配置
    Noto Sans SC:
      normal: NotoSansSC-Regular.ttf
      bold: NotoSansSC-Bold.ttf
      italic: NotoSansSC-Regular.ttf
      bold_italic: NotoSansSC-Bold.ttf
    # 英文字体配置
    Roboto:
      normal: Roboto-Regular.ttf
      bold: Roboto-Bold.ttf
      italic: Roboto-Italic.ttf
      bold_italic: Roboto-BoldItalic.ttf
  fallbacks:
    - Noto Sans SC
    - Roboto

page:
  layout: portrait
  margin: [0.75in, 1in, 0.75in, 1in]
  size: A4

base:
  font_color: #333333
  font_family: Noto Sans SC
  font_size: 10
  line_height_length: 17
  line_height: $base_line_height_length / $base_font_size

title_page:
  align: center
  logo:
    image: image:logo.png[pdfwidth=60%]
  title:
    top: 40%
    font_size: 24
    font_color: #262626
  subtitle:
    font_size: 18
    font_style: bold_italic
    font_color: #666666
  authors:
    font_size: 14
    font_color: #181818
  revision:
    font_size: 12
    font_color: #181818

header:
  height: 0.75in
  line_height: 1
  border_color: #dddddd
  border_width: 0.25
  font_size: 10
  background_color: #f5f5f5
  padding: [4, 4, 4, 4]
  vertical_align: middle

footer:
  height: 0.75in
  line_height: 1
  border_color: #dddddd
  border_width: 0.25
  font_size: 10
  padding: [4, 4, 4, 4]
  vertical_align: middle

heading:
  font_color: #262626
  font_family: Roboto
  h1_font_size: 18
  h2_font_size: 16
  h3_font_size: 14
  h4_font_size: 12
  h5_font_size: 10
  h6_font_size: 10
  line_height: 1.2
  margin_bottom: $base_line_height_length

link:
  font_color: #1565C0

code:
  font_family: Courier
  font_size: 9
  background_color: #f5f5f5
  border_color: #dddddd
  border_radius: 4

生成 PDF 文档:

mvn asciidoctor:process-asciidoc@pdf

使用工具直接导出

使用 wkhtmltopdf 工具

1. 安装 wkhtmltopdf:

# Ubuntu/Debian
sudo apt-get install wkhtmltopdf

# CentOS/RHEL
sudo yum install wkhtmltopdf

# macOS
brew install wkhtmltopdf

2. 创建导出脚本 export-docs.sh:

#

实例

!/bin/bash

# 设置变量
SWAGGER_URL="http://localhost:8080/swagger-ui/index.html"
OUTPUT_DIR="./api-docs"
FILENAME="api-documentation.pdf"
HTML_FILENAME="api-documentation.html"

# 创建输出目录
mkdir -p $OUTPUT_DIR

# 使用 curl 下载 HTML 文档
echo "正在下载 Swagger UI HTML..."
curl -s $SWAGGER_URL > $OUTPUT_DIR/$HTML_FILENAME

# 使用 wkhtmltopdf 生成 PDF
echo "正在生成 PDF 文档..."
wkhtmltopdf \
  --enable-javascript \
  --javascript-delay 5000 \
  --no-stop-slow-scripts \
  --page-size A4 \
  --title "API 文档" \
  --margin-top 20 \
  --margin-right 20 \
  --margin-bottom 20 \
  --margin-left 20 \
  --header-line \
  --header-center "API 文档中心" \
  --footer-line \
  --footer-center "页码 [page] / [topage]" \
  --footer-right "生成日期: $(date +%Y-%m-%d)" \
  $OUTPUT_DIR/$HTML_FILENAME $OUTPUT_DIR/$FILENAME

echo "文档已生成:"
echo "HTML: $OUTPUT_DIR/$HTML_FILENAME"
echo "PDF: $OUTPUT_DIR/$FILENAME"

3. 运行脚本:

chmod +x export-docs.sh
./export-docs.sh

使用 Puppeteer 导出 PDF

对于 Node.js 环境,可以使用 Puppeteer 导出 PDF。

1. 创建导出脚本 export-pdf.js:

实例

const puppeteer = require('puppeteer');
const path = require('path');
const fs = require('fs');

(async () => {
  // 创建输出目录
  const outputDir = path.join(__dirname, 'api-docs');
  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir);
  }

  // 启动浏览器
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
 
  // 访问 Swagger UI 页面
  await page.goto('http://localhost:8080/swagger-ui/index.html', {
    waitUntil: 'networkidle0',
    timeout: 60000
  });

  // 等待 Swagger UI 加载完成
  await page.waitForSelector('.swagger-ui .information-container', { timeout: 10000 });
 
  // 展开所有 API 节点
  await page.evaluate(() => {
    document.querySelectorAll('.opblock').forEach(el => {
      if (!el.classList.contains('is-open')) {
        el.querySelector('.opblock-summary').click();
      }
    });
  });

  // 等待展开动画完成
  await page.waitForTimeout(2000);
 
  // 添加自定义页眉页脚样式
  await page.addStyleTag({
    content: `
      @page {
        margin: 20mm 15mm;
      }
      .page-header {
        width: 100%;
        text-align: center;
        font-size: 16px;
        color: #333;
        padding: 10px 0;
        border-bottom: 1px solid #ddd;
      }
      .page-footer {
        width: 100%;
        text-align: center;
        font-size: 12px;
        color: #666;
        padding: 10px 0;
        border-top: 1px solid #ddd;
      }
    `
  });

  // 生成 PDF
  await page.pdf({
    path: path.join(outputDir, 'api-documentation.pdf'),
    format: 'A4',
    printBackground: true,
    displayHeaderFooter: true,
    headerTemplate: `<div class="page-header">API 文档中心</div>`,
    footerTemplate: `<div class="page-footer">
                       <span>页码 <span class="pageNumber"></span> / <span class="totalPages"></span></span>
                       <span style="margin-left: 20px;">生成日期: ${new Date().toLocaleDateString()}</span>
                     </div>`,
    margin: {
      top: '40px',
      bottom: '40px',
      left: '20px',
      right: '20px'
    }
  });

  // 生成 HTML
  const htmlContent = await page.content();
  fs.writeFileSync(path.join(outputDir, 'api-documentation.html'), htmlContent);

  // 关闭浏览器
  await browser.close();
 
  console.log('文档已生成在目录:', outputDir);
})();

2. 安装依赖并运行:

npm install puppeteer
node export-pdf.js

总结

Swagger UI 是一个强大的 API 文档工具,通过正确配置和使用,可以大大提高 API 的可用性和开发效率。

通过以上内容我们了解了 Swagger UI 的基本概念、集成方法、文档编写、自定义配置、文档发布、样式定制以及文档导出等内容。

记住以下关键点:

  1. 选择适合项目技术栈的 Swagger 集成方式
  2. 精心设计和编写 API 文档注解或注释
  3. 根据需要自定义 Swagger UI 界面和样式
  4. 添加品牌标识使文档更具专业性
  5. 选择合适的文档发布和导出方式
  6. 遵循最佳实践,确保文档的准确性和安全性

通过合理使用 Swagger UI,您可以为您的 API 提供专业、交互式的文档,让您的 API 更易于理解和使用。