三、站点 转化 为PDF文档(将 HTML 转化为 PDF)

149 阅读2分钟

背景

文档中心需要将现有 web 内容转化为 PDF 文档 供用户下载。 如:

  1. docs.rongcloud.cn/android-iml…
  2. docs.rongcloud.cn/ios-imlib
  3. docs.rongcloud.cn/harmonyOS-i…

一个模块下有很多页面,需要将这些页面合并到一个PDF文件中输出。

技术方案

输出目录树

  1. 收集目录产出 目录树文件。

处理文档将内容输出到一个HTML文件中

  1. 按目录树收集 HTML 文件。
  2. 按目录树处理 文档内的 H1 - H5 的内容。
  3. 处理 HTML 输出到 output.html中, 删除头尾部分。

将 HTML 转化为 PDF

  1. 将合并后的 HTML 转化为 PDF 文档。
  2. 为 PDF 添加封面
  3. 为 PDF 添加目录
  4. 为 PDF 添加页码

将 HTML 转化为 PDF

到这里通过

  1. juejin.cn/spost/74500…
  2. juejin.cn/spost/74500…

生成了一个很大HTML文档了。

需要将HTML 输出为PDF。

主要命令

wkhtmltopdf(){
  /usr/local/bin/wkhtmltopdf \
    --user-style-sheet /opt/rcloud/docs/main.css \
    --print-media-type \
    --page-offset 0 \
    --margin-bottom 20mm --footer-spacing 8 --footer-font-size 9 --footer-center '- [page] -' \
    cover /opt/com.rcloud/cn.rongcloud.docs/cover$1.html \
    toc --xsl-style-sheet  /opt/rcloud/docs/contents.xsl \
    http://docs.rongcloud.cn/pdf$1.html /opt/rcloud/docs/dist/pdf$1.pdf
}

命令解说

参考文档 wkhtmltopdf.org/usage/wkhtm…

--user-style-shee
--user-style-sheet /opt/rcloud/docs/main.css

用于干预 HTML 中的原有样式。

--print-media-type

使用打印样式

--page-offset
--page-offset 0

设置页面起始是第几页,当前设置为0页

--margin-bottom

页面边距

--footer-center
 --footer-center '- [page] -'

设置页码

cover xxxx.html

设置一个封面页

toc
toc --xsl-style-sheet  /opt/rcloud/docs/contents.xsl

设置目录格式

contents.xsl 文件

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:outline="http://wkhtmltopdf.org/outline"
  xmlns="http://www.w3.org/1999/xhtml">
  <xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    indent="yes" />
  <xsl:template match="outline:outline">
    <html>
      <head>
        <title>目录</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <style>
          * {
            padding: 0;
            margin: 0;
          }
          body {
            padding: 4%;
          }
          h1 {
            color: #000!important;
            margin: 2% 0%;
            padding:2% 0;
            font-size: 30px;
          }
          div {border-bottom: 1px dashed rgb(200,200,200);  padding: 5px 0;}
          span {float: right;}
          li {list-style: none; color: #000000;}
          ul {
            font-size: 35px;
            color: #000000;
          }
          ul ul {font-size: 80%; }
          ul {padding-left: 0em;}
          ul ul {padding-left: 2em; padding-right: 0;}
          a {text-decoration:none; color: #000000;}

        </style>
      </head>
      <body>
        <h1 style="font-size:45px; text-align: center">目录</h1>
        <ul><xsl:apply-templates select="outline:item/outline:item"/></ul>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="outline:item">
    <li>
      <xsl:if test="@title!='目录'">
        <xsl:if test="@title!=''">
          <div>
            <xsl:choose>
              <xsl:when test="contains(@title,' 异常')">
              <a style="color: #FF8B07!important;">
                <xsl:if test="@link">
                  <xsl:attribute name="href"><xsl:value-of select="@link"/></xsl:attribute>
                </xsl:if>
                <xsl:if test="@backLink">
                  <xsl:attribute name="name"><xsl:value-of select="@backLink"/></xsl:attribute>
                </xsl:if>
                <xsl:value-of select="@title" />
              </a>
              </xsl:when>
                <xsl:otherwise>
                  <a>
                    <xsl:if test="@link">
                      <xsl:attribute name="href"><xsl:value-of select="@link"/></xsl:attribute>
                    </xsl:if>
                    <xsl:if test="@backLink">
                      <xsl:attribute name="name"><xsl:value-of select="@backLink"/></xsl:attribute>
                    </xsl:if>
                    <xsl:value-of select="@title" />
                  </a>
                </xsl:otherwise>
            </xsl:choose>
            <span><xsl:value-of select="@page" /></span>
          </div>
        </xsl:if>
      </xsl:if>
      <ul>
        <xsl:comment>added to prevent self-closing tags in QtXmlPatterns</xsl:comment>
        <xsl:apply-templates select="outline:item"/>
      </ul>
    </li>
  </xsl:template>
</xsl:stylesheet>