简体中文 繁體中文 English 日本語 Deutsch 한국 사람 بالعربية TÜRKÇE português คนไทย Français

站内搜索

搜索

活动公告

11-02 12:46
10-23 09:32
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,将及时处理!
10-23 09:31
10-23 09:28
通知:签到时间调整为每日4:00(东八区)
10-23 09:26

XSL-FO技术指南轻松创建PDF书签提升文档阅读体验详解实现步骤与常见问题解决方案助你快速掌握这一实用技能让文档更专业

3万

主题

424

科技点

3万

积分

大区版主

木柜子打湿

积分
31917

三倍冰淇淋无人之境【一阶】财Doro小樱(小丑装)立华奏以外的星空【二阶】⑨的冰沙

发表于 2025-9-24 12:40:00 | 显示全部楼层 |阅读模式 [标记阅至此楼]

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

XSL-FO(XSL Formatting Objects)是一种用于格式化XML数据的W3C标准,它专门设计用于将XML内容转换为高质量的打印文档,特别是PDF文件。在处理长文档时,PDF书签是一项极其重要的功能,它能显著提升文档的导航性和用户体验。本文将详细介绍如何使用XSL-FO技术创建PDF书签,帮助你快速掌握这一实用技能,让你的文档更加专业。

1. XSL-FO基础概述

1.1 什么是XSL-FO

XSL-FO是XSL(Extensible Stylesheet Language)的一部分,专门用于描述XML文档的视觉呈现。它将内容和表现分离,使开发者能够专注于数据的结构和内容,而将格式化交给XSL-FO处理器处理。

XSL-FO文档的基本结构如下:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
  3.   <fo:layout-master-set>
  4.     <!-- 定义页面布局 -->
  5.   </fo:layout-master-set>
  6.   <fo:page-sequence>
  7.     <!-- 页面内容 -->
  8.   </fo:page-sequence>
  9. </fo:root>
复制代码

1.2 XSL-FO处理器

要将XSL-FO转换为PDF,需要使用XSL-FO处理器。常用的处理器包括:

• Apache FOP(Formatting Objects Processor):开源且广泛使用的XSL-FO处理器
• RenderX XEP:商业XSL-FO处理器,提供高级功能
• Antenna House Formatter:商业处理器,支持复杂布局

本文将以Apache FOP为例进行讲解,因为它免费且功能强大。

2. PDF书签的重要性

PDF书签(也称为大纲)是PDF文档中的导航元素,它们显示在PDF阅读器的左侧面板中,允许用户快速跳转到文档的特定部分。书签的主要优势包括:

1. 提升导航效率:用户可以快速定位到文档的任何部分
2. 增强文档结构:书签反映了文档的层次结构,使内容组织更加清晰
3. 改善用户体验:专业文档通常包含完整的书签结构,这已成为行业标准
4. 提高文档可用性:特别是对于长文档和参考手册,书签是必不可少的

3. 使用XSL-FO创建PDF书签的基本步骤

3.1 设置XSL-FO文档结构

首先,我们需要创建一个基本的XSL-FO文档结构,并添加书签所需的命名空间:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
  3.          xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
  4.   
  5.   <fo:layout-master-set>
  6.     <!-- 页面布局定义 -->
  7.     <fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm">
  8.       <fo:region-body margin="2cm"/>
  9.       <fo:region-before extent="3cm"/>
  10.       <fo:region-after extent="1.5cm"/>
  11.     </fo:simple-page-master>
  12.   </fo:layout-master-set>
  13.   
  14.   <fo:page-sequence master-reference="A4">
  15.     <!-- 页面内容 -->
  16.   </fo:page-sequence>
  17.   
  18. </fo:root>
复制代码

注意,我们添加了xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"命名空间,这是Apache FOP的扩展命名空间,用于创建书签。

3.2 创建基本书签

在XSL-FO中,书签是通过fox:bookmark和fox:bookmark-title元素创建的。以下是一个简单示例:
  1. <fo:page-sequence master-reference="A4">
  2.   <!-- 书签定义 -->
  3.   <fo:bookmark-tree>
  4.     <fox:bookmark internal-destination="intro">
  5.       <fox:bookmark-title>介绍</fox:bookmark-title>
  6.     </fox:bookmark>
  7.     <fox:bookmark internal-destination="chapter1">
  8.       <fox:bookmark-title>第一章</fox:bookmark-title>
  9.     </fox:bookmark>
  10.     <fox:bookmark internal-destination="chapter2">
  11.       <fox:bookmark-title>第二章</fox:bookmark-title>
  12.     </fox:bookmark>
  13.   </fo:bookmark-tree>
  14.   
  15.   <!-- 页面内容 -->
  16.   <fo:flow flow-name="xsl-region-body">
  17.     <fo:block id="intro" font-size="18pt" font-weight="bold" space-after="1cm">
  18.       介绍
  19.     </fo:block>
  20.     <fo:block>
  21.       这是介绍部分的内容...
  22.     </fo:block>
  23.    
  24.     <fo:block id="chapter1" font-size="18pt" font-weight="bold" space-before="2cm" space-after="1cm">
  25.       第一章
  26.     </fo:block>
  27.     <fo:block>
  28.       这是第一章的内容...
  29.     </fo:block>
  30.    
  31.     <fo:block id="chapter2" font-size="18pt" font-weight="bold" space-before="2cm" space-after="1cm">
  32.       第二章
  33.     </fo:block>
  34.     <fo:block>
  35.       这是第二章的内容...
  36.     </fo:block>
  37.   </fo:flow>
  38. </fo:page-sequence>
复制代码

在这个示例中:

• fo:bookmark-tree是书签树的容器
• fox:bookmark定义一个书签项,internal-destination属性指向文档中的一个ID
• fox:bookmark-title定义书签的显示文本
• 每个书签对应的内容块都有一个id属性,与书签的internal-destination相匹配

3.3 创建嵌套书签

对于复杂的文档结构,通常需要创建嵌套的书签层次。以下是一个包含嵌套书签的示例:
  1. <fo:bookmark-tree>
  2.   <fox:bookmark internal-destination="intro">
  3.     <fox:bookmark-title>介绍</fox:bookmark-title>
  4.   </fox:bookmark>
  5.   
  6.   <fox:bookmark internal-destination="chapter1">
  7.     <fox:bookmark-title>第一章 基础概念</fox:bookmark-title>
  8.     <!-- 嵌套书签 -->
  9.     <fox:bookmark internal-destination="section1-1">
  10.       <fox:bookmark-title>1.1 概述</fox:bookmark-title>
  11.     </fox:bookmark>
  12.     <fox:bookmark internal-destination="section1-2">
  13.       <fox:bookmark-title>1.2 基本原理</fox:bookmark-title>
  14.     </fox:bookmark>
  15.   </fox:bookmark>
  16.   
  17.   <fox:bookmark internal-destination="chapter2">
  18.     <fox:bookmark-title>第二章 高级应用</fox:bookmark-title>
  19.     <!-- 嵌套书签 -->
  20.     <fox:bookmark internal-destination="section2-1">
  21.       <fox:bookmark-title>2.1 复杂场景</fox:bookmark-title>
  22.       <!-- 更深层嵌套 -->
  23.       <fox:bookmark internal-destination="subsection2-1-1">
  24.         <fox:bookmark-title>2.1.1 实例分析</fox:bookmark-title>
  25.       </fox:bookmark>
  26.     </fox:bookmark>
  27.     <fox:bookmark internal-destination="section2-2">
  28.       <fox:bookmark-title>2.2 最佳实践</fox:bookmark-title>
  29.     </fox:bookmark>
  30.   </fox:bookmark>
  31. </fo:bookmark-tree>
复制代码

对应的文档内容结构如下:
  1. <fo:flow flow-name="xsl-region-body">
  2.   <fo:block id="intro" font-size="18pt" font-weight="bold" space-after="1cm">
  3.     介绍
  4.   </fo:block>
  5.   
  6.   <fo:block id="chapter1" font-size="18pt" font-weight="bold" space-before="2cm" space-after="1cm">
  7.     第一章 基础概念
  8.   </fo:block>
  9.   
  10.   <fo:block id="section1-1" font-size="16pt" font-weight="bold" space-before="1cm" space-after="0.5cm">
  11.     1.1 概述
  12.   </fo:block>
  13.   
  14.   <fo:block id="section1-2" font-size="16pt" font-weight="bold" space-before="1cm" space-after="0.5cm">
  15.     1.2 基本原理
  16.   </fo:block>
  17.   
  18.   <fo:block id="chapter2" font-size="18pt" font-weight="bold" space-before="2cm" space-after="1cm">
  19.     第二章 高级应用
  20.   </fo:block>
  21.   
  22.   <fo:block id="section2-1" font-size="16pt" font-weight="bold" space-before="1cm" space-after="0.5cm">
  23.     2.1 复杂场景
  24.   </fo:block>
  25.   
  26.   <fo:block id="subsection2-1-1" font-size="14pt" font-weight="bold" space-before="1cm" space-after="0.5cm">
  27.     2.1.1 实例分析
  28.   </fo:block>
  29.   
  30.   <fo:block id="section2-2" font-size="16pt" font-weight="bold" space-before="1cm" space-after="0.5cm">
  31.     2.2 最佳实践
  32.   </fo:block>
  33. </fo:flow>
复制代码

3.4 使用XSLT自动生成书签

在实际应用中,我们通常使用XSLT转换来自动生成XSL-FO文档,包括书签。以下是一个XSLT样式表的示例,它从XML源文档生成带有书签的XSL-FO:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <xsl:stylesheet version="1.1"
  3.     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  4.     xmlns:fo="http://www.w3.org/1999/XSL/Format"
  5.     xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"
  6.     exclude-result-prefixes="fox">
  7.    
  8.   <xsl:template match="/">
  9.     <fo:root>
  10.       <fo:layout-master-set>
  11.         <fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm">
  12.           <fo:region-body margin="2cm"/>
  13.           <fo:region-before extent="3cm"/>
  14.           <fo:region-after extent="1.5cm"/>
  15.         </fo:simple-page-master>
  16.       </fo:layout-master-set>
  17.       
  18.       <fo:page-sequence master-reference="A4">
  19.         <!-- 自动生成书签 -->
  20.         <fo:bookmark-tree>
  21.           <xsl:apply-templates select="document/chapter" mode="bookmark"/>
  22.         </fo:bookmark-tree>
  23.         
  24.         <!-- 生成内容 -->
  25.         <fo:flow flow-name="xsl-region-body">
  26.           <xsl:apply-templates select="document/intro"/>
  27.           <xsl:apply-templates select="document/chapter"/>
  28.         </fo:flow>
  29.       </fo:page-sequence>
  30.     </fo:root>
  31.   </xsl:template>
  32.   
  33.   <!-- 书签生成模板 -->
  34.   <xsl:template match="chapter" mode="bookmark">
  35.     <fox:bookmark internal-destination="{generate-id()}">
  36.       <fox:bookmark-title>
  37.         <xsl:value-of select="title"/>
  38.       </fox:bookmark-title>
  39.       <!-- 为每个节生成子书签 -->
  40.       <xsl:apply-templates select="section" mode="bookmark"/>
  41.     </fox:bookmark>
  42.   </xsl:template>
  43.   
  44.   <xsl:template match="section" mode="bookmark">
  45.     <fox:bookmark internal-destination="{generate-id()}">
  46.       <fox:bookmark-title>
  47.         <xsl:value-of select="title"/>
  48.       </fox:bookmark-title>
  49.       <!-- 为每个子节生成子书签 -->
  50.       <xsl:apply-templates select="subsection" mode="bookmark"/>
  51.     </fox:bookmark>
  52.   </xsl:template>
  53.   
  54.   <xsl:template match="subsection" mode="bookmark">
  55.     <fox:bookmark internal-destination="{generate-id()}">
  56.       <fox:bookmark-title>
  57.         <xsl:value-of select="title"/>
  58.       </fox:bookmark-title>
  59.     </fox:bookmark>
  60.   </xsl:template>
  61.   
  62.   <!-- 内容生成模板 -->
  63.   <xsl:template match="intro">
  64.     <fo:block id="{generate-id()}" font-size="18pt" font-weight="bold" space-after="1cm">
  65.       <xsl:value-of select="title"/>
  66.     </fo:block>
  67.     <fo:block>
  68.       <xsl:apply-templates select="para"/>
  69.     </fo:block>
  70.   </xsl:template>
  71.   
  72.   <xsl:template match="chapter">
  73.     <fo:block id="{generate-id()}" font-size="18pt" font-weight="bold" space-before="2cm" space-after="1cm" break-before="page">
  74.       <xsl:value-of select="title"/>
  75.     </fo:block>
  76.     <xsl:apply-templates select="section"/>
  77.   </xsl:template>
  78.   
  79.   <xsl:template match="section">
  80.     <fo:block id="{generate-id()}" font-size="16pt" font-weight="bold" space-before="1cm" space-after="0.5cm">
  81.       <xsl:value-of select="title"/>
  82.     </fo:block>
  83.     <fo:block>
  84.       <xsl:apply-templates select="para"/>
  85.     </fo:block>
  86.     <xsl:apply-templates select="subsection"/>
  87.   </xsl:template>
  88.   
  89.   <xsl:template match="subsection">
  90.     <fo:block id="{generate-id()}" font-size="14pt" font-weight="bold" space-before="1cm" space-after="0.5cm">
  91.       <xsl:value-of select="title"/>
  92.     </fo:block>
  93.     <fo:block>
  94.       <xsl:apply-templates select="para"/>
  95.     </fo:block>
  96.   </xsl:template>
  97.   
  98.   <xsl:template match="para">
  99.     <fo:block space-after="0.5cm">
  100.       <xsl:apply-templates/>
  101.     </fo:block>
  102.   </xsl:template>
  103. </xsl:stylesheet>
复制代码

对应的XML源文档示例:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <document>
  3.   <intro>
  4.     <title>介绍</title>
  5.     <para>这是介绍部分的内容...</para>
  6.   </intro>
  7.   
  8.   <chapter>
  9.     <title>第一章 基础概念</title>
  10.     <section>
  11.       <title>1.1 概述</title>
  12.       <para>这是1.1节的内容...</para>
  13.     </section>
  14.     <section>
  15.       <title>1.2 基本原理</title>
  16.       <para>这是1.2节的内容...</para>
  17.     </section>
  18.   </chapter>
  19.   
  20.   <chapter>
  21.     <title>第二章 高级应用</title>
  22.     <section>
  23.       <title>2.1 复杂场景</title>
  24.       <para>这是2.1节的内容...</para>
  25.       <subsection>
  26.         <title>2.1.1 实例分析</title>
  27.         <para>这是2.1.1子节的内容...</para>
  28.       </subsection>
  29.     </section>
  30.     <section>
  31.       <title>2.2 最佳实践</title>
  32.       <para>这是2.2节的内容...</para>
  33.     </section>
  34.   </chapter>
  35. </document>
复制代码

4. 高级书签功能

4.1 设置书签初始状态

你可以设置书签的初始展开或折叠状态,使用starting-state属性:
  1. <fox:bookmark internal-destination="chapter1" starting-state="hide">
  2.   <fox:bookmark-title>第一章</fox:bookmark-title>
  3.   <!-- 子书签 -->
  4. </fox:bookmark>
复制代码

starting-state可以设置为:

• “show”:默认展开
• “hide”:默认折叠

4.2 为书签添加颜色

使用fox:bookmark-color可以为书签添加颜色,增强视觉效果:
  1. <fox:bookmark internal-destination="chapter1">
  2.   <fox:bookmark-title>第一章</fox:bookmark-title>
  3.   <fox:bookmark-color>#FF0000</fox:bookmark-color>
  4.   <!-- 子书签 -->
  5. </fox:bookmark>
复制代码

4.3 设置外部链接书签

书签不仅可以链接到文档内部,还可以链接到外部资源:
  1. <fox:bookmark external-destination="url('https://www.example.com')">
  2.   <fox:bookmark-title>访问示例网站</fox:bookmark-title>
  3. </fox:bookmark>
复制代码

5. 使用Apache FOP生成带书签的PDF

5.1 安装和配置Apache FOP

1. 从Apache FOP官网下载最新版本:https://xmlgraphics.apache.org/fop/download.html
2. 解压下载的文件
3. 设置环境变量FOP_HOME指向FOP安装目录
4. 将FOP的bin目录添加到PATH环境变量

5.2 使用命令行生成PDF

假设我们有一个XSL-FO文件document.fo,可以使用以下命令生成PDF:
  1. fop -fo document.fo -pdf document.pdf
复制代码

如果使用XSLT转换,可以直接从XML和XSL生成PDF:
  1. fop -xml document.xml -xsl stylesheet.xsl -pdf document.pdf
复制代码

5.3 使用Java API生成PDF

在Java应用程序中使用Apache FOP生成PDF的示例代码:
  1. import org.apache.fop.apps.*;
  2. import javax.xml.transform.*;
  3. import javax.xml.transform.sax.SAXResult;
  4. import javax.xml.transform.stream.StreamSource;
  5. import java.io.*;
  6. public class PDFGenerator {
  7.     public static void main(String[] args) {
  8.         try {
  9.             // 配置FOP
  10.             FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
  11.             
  12.             // 设置输出流
  13.             OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("document.pdf")));
  14.             
  15.             try {
  16.                 // 构造FOP实例
  17.                 Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);
  18.                
  19.                 // 设置XSLT
  20.                 TransformerFactory factory = TransformerFactory.newInstance();
  21.                 Transformer transformer = factory.newTransformer(new StreamSource(new File("stylesheet.xsl")));
  22.                
  23.                 // 设置源和结果
  24.                 Source src = new StreamSource(new File("document.xml"));
  25.                 Result res = new SAXResult(fop.getDefaultHandler());
  26.                
  27.                 // 转换
  28.                 transformer.transform(src, res);
  29.             } finally {
  30.                 out.close();
  31.             }
  32.             
  33.             System.out.println("PDF生成成功!");
  34.         } catch (Exception e) {
  35.             e.printStackTrace(System.err);
  36.         }
  37.     }
  38. }
复制代码

6. 常见问题及解决方案

6.1 书签不显示

问题:生成的PDF中没有书签显示。

可能原因及解决方案:

1. 缺少FOP扩展命名空间:确保在XSL-FO根元素中包含xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"命名空间。
2. 书签定义位置错误:fo:bookmark-tree应该放在fo:page-sequence内部,而不是外部。
3. ID不匹配:检查fox:bookmark的internal-destination属性是否与目标元素的id属性完全匹配。
4. 使用错误的处理器:不是所有XSL-FO处理器都支持FOP的书签扩展。确保使用Apache FOP或兼容的处理器。

6.2 书签顺序错误

问题:书签的顺序与文档中的内容顺序不一致。

解决方案:

• 确保fo:bookmark-tree中书签的顺序与文档中内容的顺序一致
• 如果使用XSLT生成书签,检查XSLT模板的应用顺序
• 考虑使用xsl:sort对书签进行排序:
  1. <xsl:template match="chapter" mode="bookmark">
  2.   <xsl:for-each select=".">
  3.     <xsl:sort select="@order" data-type="number"/>
  4.     <fox:bookmark internal-destination="{generate-id()}">
  5.       <fox:bookmark-title>
  6.         <xsl:value-of select="title"/>
  7.       </fox:bookmark-title>
  8.     </fox:bookmark>
  9.   </xsl:for-each>
  10. </xsl:template>
复制代码

6.3 嵌套书签不工作

问题:嵌套的书签没有正确显示层次结构。

解决方案:

• 确保子书签元素是父书签元素的直接子元素
• 检查XSLT模板是否正确递归应用:
  1. <xsl:template match="chapter" mode="bookmark">
  2.   <fox:bookmark internal-destination="{generate-id()}">
  3.     <fox:bookmark-title>
  4.       <xsl:value-of select="title"/>
  5.     </fox:bookmark-title>
  6.     <!-- 确保这里正确应用了子元素的模板 -->
  7.     <xsl:apply-templates select="section" mode="bookmark"/>
  8.   </fox:bookmark>
  9. </xsl:template>
复制代码

6.4 书签文本显示异常

问题:书签中的文本显示不正确,包含乱码或特殊字符。

解决方案:

• 确保XML和XSL文件使用正确的编码(通常是UTF-8)
• 在XML和XSL文件的开头指定编码:
  1. <?xml version="1.0" encoding="UTF-8"?>
复制代码

• 在XSLT中使用xsl:output指定输出编码:
  1. <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
复制代码

6.5 书签链接到错误位置

问题:点击书签后,跳转到错误的位置。

解决方案:

• 确保每个目标元素有唯一的ID
• 检查ID是否包含特殊字符,某些特殊字符可能导致链接问题
• 考虑使用generate-id()函数生成唯一ID,避免手动输入错误:
  1. <fo:block id="{generate-id()}">
  2.   <xsl:value-of select="title"/>
  3. </fo:block>
复制代码

6.6 性能问题

问题:处理大型文档时,生成带书签的PDF速度很慢。

解决方案:

• 优化XSLT样式表,减少不必要的模板匹配和处理
• 考虑分页处理大型文档
• 增加Java虚拟机内存:
  1. fop -Xmx2g -fo document.fo -pdf document.pdf
复制代码

7. 最佳实践

7.1 设计一致的书签结构

• 保持书签层次结构与文档结构一致
• 使用一致的命名约定
• 限制书签深度,通常不超过3-4层,以保持导航的简洁性

7.2 使用有意义的书签标题

• 确保书签标题简洁明了
• 包含章节编号,便于用户定位
• 避免过长的书签标题,考虑在必要时使用缩写

7.3 自动化书签生成

• 使用XSLT自动生成书签,而不是手动创建
• 将书签生成逻辑与内容生成逻辑分离
• 使用模板匹配和递归处理复杂的文档结构

7.4 测试和验证

• 在不同的PDF阅读器中测试书签功能
• 验证所有书签链接是否正确
• 检查书签在不同缩放级别下的显示效果

8. 完整示例

以下是一个完整的示例,展示如何从XML源文档生成带有完整书签结构的PDF文档。

8.1 XML源文档 (manual.xml)
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <manual>
  3.   <title>产品使用手册</title>
  4.   
  5.   <front>
  6.     <chapter>
  7.       <title>前言</title>
  8.       <section>
  9.         <title>关于本手册</title>
  10.         <para>本手册提供了产品的详细使用说明...</para>
  11.       </section>
  12.       <section>
  13.         <title>适用范围</title>
  14.         <para>本手册适用于产品的所有版本...</para>
  15.       </section>
  16.     </chapter>
  17.   </front>
  18.   
  19.   <body>
  20.     <chapter id="ch1">
  21.       <title>第一章 产品概述</title>
  22.       <section id="ch1-sec1">
  23.         <title>1.1 产品简介</title>
  24.         <para>我们的产品是一款创新的解决方案...</para>
  25.       </section>
  26.       <section id="ch1-sec2">
  27.         <title>1.2 主要功能</title>
  28.         <para>产品提供以下主要功能...</para>
  29.       </section>
  30.       <section id="ch1-sec3">
  31.         <title>1.3 系统要求</title>
  32.         <para>使用本产品需要满足以下系统要求...</para>
  33.       </section>
  34.     </chapter>
  35.    
  36.     <chapter id="ch2">
  37.       <title>第二章 安装与配置</title>
  38.       <section id="ch2-sec1">
  39.         <title>2.1 安装步骤</title>
  40.         <subsection id="ch2-sec1-sub1">
  41.           <title>2.1.1 Windows系统安装</title>
  42.           <para>在Windows系统上安装产品的步骤...</para>
  43.         </subsection>
  44.         <subsection id="ch2-sec1-sub2">
  45.           <title>2.1.2 Linux系统安装</title>
  46.           <para>在Linux系统上安装产品的步骤...</para>
  47.         </subsection>
  48.       </section>
  49.       <section id="ch2-sec2">
  50.         <title>2.2 基本配置</title>
  51.         <para>安装完成后,需要进行基本配置...</para>
  52.       </section>
  53.     </chapter>
  54.    
  55.     <chapter id="ch3">
  56.       <title>第三章 使用指南</title>
  57.       <section id="ch3-sec1">
  58.         <title>3.1 基本操作</title>
  59.         <para>产品的基本操作包括...</para>
  60.       </section>
  61.       <section id="ch3-sec2">
  62.         <title>3.2 高级功能</title>
  63.         <subsection id="ch3-sec2-sub1">
  64.           <title>3.2.1 数据导入导出</title>
  65.           <para>产品的数据导入导出功能...</para>
  66.         </subsection>
  67.         <subsection id="ch3-sec2-sub2">
  68.           <title>3.2.2 自动化处理</title>
  69.           <para>产品的自动化处理功能...</para>
  70.         </subsection>
  71.       </section>
  72.     </chapter>
  73.   </body>
  74.   
  75.   <appendix>
  76.     <chapter>
  77.       <title>附录</title>
  78.       <section>
  79.         <title>常见问题解答</title>
  80.         <para>以下是用户常见的问题及解答...</para>
  81.       </section>
  82.       <section>
  83.         <title>技术支持</title>
  84.         <para>如需技术支持,请联系...</para>
  85.       </section>
  86.     </chapter>
  87.   </appendix>
  88. </manual>
复制代码

8.2 XSLT样式表 (manual2fo.xsl)
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <xsl:stylesheet version="1.1"
  3.     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  4.     xmlns:fo="http://www.w3.org/1999/XSL/Format"
  5.     xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"
  6.     exclude-result-prefixes="fox">
  7.    
  8.   <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  9.   
  10.   <xsl:template match="/">
  11.     <fo:root>
  12.       <fo:layout-master-set>
  13.         <fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm">
  14.           <fo:region-body margin="2cm"/>
  15.           <fo:region-before extent="3cm"/>
  16.           <fo:region-after extent="1.5cm"/>
  17.         </fo:simple-page-master>
  18.       </fo:layout-master-set>
  19.       
  20.       <fo:page-sequence master-reference="A4">
  21.         <!-- 书签树 -->
  22.         <fo:bookmark-tree>
  23.           <!-- 前言部分书签 -->
  24.           <xsl:apply-templates select="manual/front/chapter" mode="bookmark"/>
  25.          
  26.           <!-- 正文部分书签 -->
  27.           <xsl:apply-templates select="manual/body/chapter" mode="bookmark"/>
  28.          
  29.           <!-- 附录部分书签 -->
  30.           <xsl:apply-templates select="manual/appendix/chapter" mode="bookmark"/>
  31.         </fo:bookmark-tree>
  32.         
  33.         <!-- 文档内容 -->
  34.         <fo:flow flow-name="xsl-region-body">
  35.           <!-- 标题页 -->
  36.           <fo:block text-align="center" space-after="2cm">
  37.             <fo:block font-size="24pt" font-weight="bold" space-after="1cm">
  38.               <xsl:value-of select="manual/title"/>
  39.             </fo:block>
  40.             <fo:block font-size="12pt">
  41.               版本 1.0
  42.             </fo:block>
  43.             <fo:block font-size="12pt">
  44.               <xsl:value-of select="format-date(current-date(), '[Y]-[M]-[D]')"/>
  45.             </fo:block>
  46.           </fo:block>
  47.          
  48.           <!-- 前言部分内容 -->
  49.           <xsl:apply-templates select="manual/front/chapter"/>
  50.          
  51.           <!-- 正文部分内容 -->
  52.           <xsl:apply-templates select="manual/body/chapter"/>
  53.          
  54.           <!-- 附录部分内容 -->
  55.           <xsl:apply-templates select="manual/appendix/chapter"/>
  56.         </fo:flow>
  57.       </fo:page-sequence>
  58.     </fo:root>
  59.   </xsl:template>
  60.   
  61.   <!-- 书签生成模板 -->
  62.   <xsl:template match="chapter" mode="bookmark">
  63.     <fox:bookmark internal-destination="{@id}">
  64.       <fox:bookmark-title>
  65.         <xsl:value-of select="title"/>
  66.       </fox:bookmark-title>
  67.       <xsl:apply-templates select="section" mode="bookmark"/>
  68.     </fox:bookmark>
  69.   </xsl:template>
  70.   
  71.   <xsl:template match="section" mode="bookmark">
  72.     <fox:bookmark internal-destination="{@id}">
  73.       <fox:bookmark-title>
  74.         <xsl:value-of select="title"/>
  75.       </fox:bookmark-title>
  76.       <xsl:apply-templates select="subsection" mode="bookmark"/>
  77.     </fox:bookmark>
  78.   </xsl:template>
  79.   
  80.   <xsl:template match="subsection" mode="bookmark">
  81.     <fox:bookmark internal-destination="{@id}">
  82.       <fox:bookmark-title>
  83.         <xsl:value-of select="title"/>
  84.       </fox:bookmark-title>
  85.     </fox:bookmark>
  86.   </xsl:template>
  87.   
  88.   <!-- 内容生成模板 -->
  89.   <xsl:template match="chapter">
  90.     <fo:block id="{@id}" font-size="18pt" font-weight="bold" space-before="2cm" space-after="1cm" break-before="page">
  91.       <xsl:value-of select="title"/>
  92.     </fo:block>
  93.     <xsl:apply-templates select="section"/>
  94.   </xsl:template>
  95.   
  96.   <xsl:template match="section">
  97.     <fo:block id="{@id}" font-size="16pt" font-weight="bold" space-before="1cm" space-after="0.5cm">
  98.       <xsl:value-of select="title"/>
  99.     </fo:block>
  100.     <fo:block>
  101.       <xsl:apply-templates select="para"/>
  102.     </fo:block>
  103.     <xsl:apply-templates select="subsection"/>
  104.   </xsl:template>
  105.   
  106.   <xsl:template match="subsection">
  107.     <fo:block id="{@id}" font-size="14pt" font-weight="bold" space-before="1cm" space-after="0.5cm">
  108.       <xsl:value-of select="title"/>
  109.     </fo:block>
  110.     <fo:block>
  111.       <xsl:apply-templates select="para"/>
  112.     </fo:block>
  113.   </xsl:template>
  114.   
  115.   <xsl:template match="para">
  116.     <fo:block space-after="0.5cm" text-align="justify">
  117.       <xsl:apply-templates/>
  118.     </fo:block>
  119.   </xsl:template>
  120. </xsl:stylesheet>
复制代码

8.3 生成PDF的命令

使用Apache FOP生成PDF的命令:
  1. fop -xml manual.xml -xsl manual2fo.xsl -pdf manual.pdf
复制代码

9. 结论

XSL-FO技术为创建专业PDF文档提供了强大的功能,特别是通过书签增强文档导航性。本文详细介绍了如何使用XSL-FO创建PDF书签,包括基本概念、实现步骤、高级功能和常见问题解决方案。

通过掌握这些技术,你可以创建具有专业书签结构的PDF文档,显著提升用户体验。无论是技术手册、产品文档还是学术报告,良好的书签结构都能使文档更加专业和易用。

随着实践的深入,你将能够更加灵活地运用XSL-FO技术,创建出更加复杂和精美的PDF文档,满足各种专业需求。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

频道订阅

频道订阅

加入社群

加入社群

联系我们|TG频道|RSS

Powered by Pixtech

© 2025 Pixtech Team.