65.9K
CodeProject 正在变化。 阅读更多。
Home

XHTML2RTF:基于 XSL 的 HTML 到 RTF 转换工具

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (41投票s)

2004 年 5 月 18 日

11分钟阅读

viewsIcon

375614

downloadIcon

13628

本文介绍了一个转换工具,该工具以 HTML 文档为输入,并生成用于打印的 Microsoft Word 文档。

概述

本文介绍了一个转换工具,该工具以 HTML 文档为输入,并生成用于打印的 Microsoft Word 文档。

这一切都始于我必须处理一个拥有数百台计算机的新信息系统。我们决定采用一个 100% 基于 Web 的应用程序。直到我们需要从应用程序打印正式文档时,一切都很顺利……

尽管正在进行标准化工作(W3C 的 XHTML-PRINT 和 IEEE 的 Print Working Group),并且有一些优秀的 HTML 打印工具(Bersoft 的 HTML PrintMeadCo 的 ScriptX),但没有一个似乎能满足我的需求。我想 保留我的基于 Web 的应用程序,并 重用生成的 HTML 来馈送打印机……

您是否尝试过 打印 HTML 文档?您是否尝试过为打印 格式化 您的 HTML 文档,包括特定的字体、大小、页眉、页脚和页边距?

如果您尝试过,那么您就知道 HTML 不适合打印——但您可以找到其他格式并使用新工具将 HTML 文档 转换 为 Microsoft Word 格式,这是一种适合打印的格式……本文就是关于这个的。

目录

特点

XHTML2RTF 转换工具

引言

XHTML2RTF 转换工具使用 XSL 样式表将 XHTML 文档转换为 RTF 文档,适合在 Word(或 Word Viewer)中预览和打印。

XHTML = HTML + XML

可扩展超文本标记语言 (XHTML) 是一系列当前和未来的文档类型及模块,它们复制、子集并扩展了 HTML,已重新设计为 XML。XHTML 系列文档类型 全部基于 XML,并最终设计为与基于 XML 的用户代理协同工作。XHTML 是 HTML 的后继者,并且已开发了一系列 XHTML 规范

XHTML2RTF 转换工具以 XHTML 文档作为输入。因此,您必须 调整您的应用程序才能使用此工具。

XSL

XSL 是 eXtensible Stylesheet Language 的缩写。它是一系列用于定义 XML 文档转换和表示 的建议。它包含三个部分:

  1. 用于转换 XML 文档的编程语言:XSL Transformations (XSLT)。
  2. XSLT 用于访问或引用 XML 文档部分的表达式语言:XML Path Language (XPath)。该语言提供模式匹配(xsl:template match)、条件语句(xsl:when test)、循环(for-each)等……
  3. 用于指定格式语义的 XML 词汇表:类似于 W3C 的级联样式表 (CSS),该词汇表提供了增强的演示功能。

有关 XSL 的更多信息,请参阅 XSL 参考页面

XHTML2RTF 转换工具使用 XSL 将 XHTML 文档(XML 文档)转换为 RTF 文档。这是该工具的核心——其他一切只是构建应用程序的粘合剂。一切都包含在 XSL 样式表中。

Microsoft XML SDK 3.0

Microsoft 提供了一个 XML SDK 用于处理 XML 和 XSL 文档。它通常随操作系统一起安装,但您可以下载并安装最新的 SDK。有关 MSXML SDK 的更多信息,请参阅 参考部分

XHTML2RTF 转换工具使用 XML SDK 对象和方法来处理 XHTML 并将其转换为 RTF。XML SDK API 可用于 Web 应用程序以及 批处理应用程序,XHTML2RTF 转换工具也是如此。

Microsoft Rich Text Format (RTF)

Microsoft 创建了一种 Word 文档的交换格式:Rich Text Format (RTF)。与原生的 Word 格式不同,它是已记录的;此外,RTF 已经存在一段时间了(因此您可以使用旧版的 Word 97 查看 RTF 文档)。还有一个免费的 RTF 查看器(Word 97/2000 Viewer),甚至 WordPad(随大多数 Windows 版本安装)也可以打开、查看和编辑 RTF 文档。

XHTML2RTF

XHTML 到 RTF 转换器包含一个 XSL 样式表,用于解析 XHTML 标签并生成其 RTF 等价物。

用法

从 HTML 到 XHTML

如果您想使用 XHTML2RTF 转换工具,您必须调整您的应用程序以生成 XHTML 文档

  • 在文档开头包含 XML 声明。
    <?xml version="1.0" encoding="iso-8859-1" ?>
  • <html> 标签中包含 XHTML 命名空间声明(默认)和 XHTML2RTF 命名空间声明。
    <html 
       xmlns="http://www.w3.org/1999/xhtml" 
       xmlns:xhtml2rtf=
         "http://www.lutecia.info/download/xmlns/xhtml2rtf">
    ...
    </html>
  • 对标签名称和属性名称都使用小写。
    • <P></P> 变为 <p></p>
    • <A HREF="...">...</a> 变为 <a href="...">...</a>
    • 等等...
  • 为所有标签添加结束符(XHTML 比 HTML 更严格)。
    • <link rel="stylesheet" href="..."> 变为 <link rel="stylesheet" href="..." />
    • <hr> 变为 <hr />
    • <br> 变为 <br />
  • 引用所有属性值。
    • <table class=noprint> 变为 <table class="noprint">
    • <a href=mypage.asp> 变为 <a href="mypage.asp">
  • 对非 ASCII 和/或特殊字符使用 编码字符
    • & 变为 &
    • é 变为 &#233;
    • è 变为 &#232; 等……
  • 用其代码替换 HTML 字符实体(XML 只识别很少的 字符实体引用 - 请改用字符代码)。
    • &nbsp; 变为 &#160;
    • è 变为 &#232;
    • é 变为 &#233;
    • ê 变为 &#234; 等……
  • 不要对标签使用直接样式(而是使用类和外部 CSS 样式表)。
    • <div style='background:#c0c0c0; font-size: 125%; padding:1.0pt 10.0pt 1.0pt 10.0pt;'>
      变为 <div class="mydivstyle">

这样,您就可以为您的类自定义 RTF 输出(在 XSL 样式表中解析 HTML 样式声明太困难了)。

HTML 和 RTF 中的空格

在 HTML 中,空格不重要——大多数浏览器在渲染文档时会忽略它们。另一方面,Microsoft Word(和 RTF)将空格渲染为可见字符。构建 HTML 文档时要小心:不要生成空格,否则它们将显示在您的 Word 文档中。

HTML 和 RTF 中的页眉和页脚

RTF 文档中的默认页眉包含 HTML <title>(来自 <head> 部分)。您可以通过设置 header-font-size-defaultheader-distance-from-edgeheader-indentation-left 参数来更改页眉(请参阅下面的 参数)。您还可以通过在 HTML 文档中使用类“rtf_header”和“rtf_header_first”来创建自己的页眉。

  • rtf_header_first 定义文档第一页页眉的完整 HTML 内容。
  • rtf_header 定义文档其他所有页面页眉的完整 HTML 内容。

RTF 文档中的默认页脚包含页码和文档日期(当前日期和时间;即打印日期和时间)。您可以通过设置 footer-font-size-defaultfooter-distance-from-edgeuse-default-footer 参数来更改页脚(请参阅下面的 参数)。

分页符

要在 RTF 文档中强制分页,可以使用 CSS 样式“page-break-before”或“page-break-after”,值为“always”。

This is on page 1
<p style="page-break-before:always"/>
This is on page 2

请注意,这些 CSS 样式的其他值(left、right、auto 等)不受支持(仅支持“always”)。

XSL 样式表参数

XSL 样式表 xhtml2rtf.xsl 提供了一组参数,以便您可以更改样式表的默认行为。

  • page-start-number:起始页码(默认:1)。
  • page-setup-paper-width:纸张宽度(以 TWIPS 为单位)(默认:11907 TWIPS = 21 cm,即 A4 格式)。
  • page-setup-paper-height:纸张高度(以 TWIPS 为单位)(默认:16840 TWIPS = 29.7 cm,即 A4 格式)。
  • page-setup-margin-top:上边距(以 TWIPS 为单位)(默认:1440 TWIPS = 1 英寸 = 2.54 cm)。
  • page-setup-margin-bottom:下边距(以 TWIPS 为单位)(默认:1440 TWIPS = 1 英寸 = 2.54 cm)。
  • page-setup-margin-left:左边距(以 TWIPS 为单位)(默认:1134 TWIPS = 2 cm)。
  • page-setup-margin-right:右边距(以 TWIPS 为单位)(默认:1134 TWIPS = 2 cm)。
  • font-size-default:默认字体大小(以 TWIPS 为单位)(默认:20 TWIPS = 10 pt)。
  • font-name-default:默认字体名称(默认:'Times New Roman')。
  • font-name-fixed:固定宽度文本(如 PRECODE)的默认字体名称(默认:'Courier New')。
  • font-name-barcode:条形码字体名称(默认:'3 of 9 Barcode')。
  • header-font-size-default:页眉默认字体大小(以 TWIPS 为单位)(默认:14 TWIPS = 7 pt)。
  • header-distance-from-edge:页眉与页面顶部之间的默认距离(以 TWIPS 为单位)(默认:720 TWIPS = 1.27 cm)。
  • header-indentation-left:页眉左缩进(以 TWIPS 为单位)(默认:0)。
  • footer-font-size-default:页脚默认字体大小(以 TWIPS 为单位)(默认:14 TWIPS = 7 pt)。
  • footer-distance-from-edge:页脚与页面底部之间的默认距离(以 TWIPS 为单位)(默认:720 TWIPS = 1.27 cm)。
  • use-default-footer:布尔标志:1 表示使用默认页脚(页码和日期),0 表示无页脚(默认:1)。
  • document-protected:布尔标志:1 表示受保护(不可修改),0 表示未受保护(默认:1)。
  • normalize-space:布尔标志:1 表示空格被规范化和修剪,0 表示不规范化也不修剪(默认:0)。
  • my-normalize-space:布尔标志:1 表示空格被规范化(不修剪),0 表示不规范化(默认:1)。

批处理模式 (WSH)

我编写了一个批处理程序(XHTML2RTF.BAT),它依赖于 Windows Script Host (WSH) 来调用 XML DOM SDK 并将 HTML 文件转换为其 RTF 等价物(输出到 stdout)。

要从批处理中使用此组件:使用 HTML 文件名作为参数调用程序 XHTML2RTF.BAT。RTF 文件生成在 stdout 中,因此您应该使用“>”运算符重定向输出。然后您可以使用 Microsoft Word(或 Wordpad)打开生成的 RTF 文件。

C:\> XHTML2RTF.BAT Readme.htm > Readme.rtf
C:\> START WINWORD Readme.rtf

要将参数传递给 XHTML2RTF 程序,请使用 -p 标志,后跟参数名称和值。

例如

C:\> XHTML2RTF.BAT -p page-start-number=5 -p document-protected=0 
              -p font-name-default='Arial' Readme.htm > Readme.rtf
C:\> START WINWORD Readme.rtf

基于 Web (ASP)

我编写了一个简单的 ASP 库,用于从 ASP 页面调用该组件,从而从实时动态内容(例如 SQL 数据库请求的结果)生成 RTF 文档。

要从网页中使用此组件,您必须在页面中包含 XHTML2RTF.inc 文件,并调用函数 XHTMLString2RTF(),传递 XHTML 文档(作为字符串)。

  <!--#include file="XHTML2RTF.inc"-->
  var strXHTML = " \
  <html xmlns=\"http://www.w3.org/1999/xhtml\" 
        xmlns:xhtml2rtf=
            \"http://www.lutecia.info/download/xmlns/xhtml2rtf\"> \
    <head> \
      <title>Hello, World! from string</title> \
    </head> \
    <body> \
      <h1>Hello, World!</h1> \
    </body> \
  </html> \
  ";
  XHTMLString2RTF(strXHTML);

注意:实际的生产系统使用 SQL 请求,生成 XML 输出,通过第一个 XSL 样式表将其转换为 XHTML,然后将其转换为 RTF 文档。上面的示例只是一个演示示例。请不要在生产系统中使用字符串生成 HTML ;-)

原始 RTF 输出

XHTML2RTF 转换工具提供直接的 RTF 输出,无需在 XHTML 中进行渲染。该工具处理一个特殊标签(<xhtml2rtf:raw>)以直接发送 RTF。例如,此代码将在 RTF 输出中发送一个 TAB 字符:<xhtml2rtf:raw class="rtf">\tab </xhtml2rtf:raw>。此代码不会在您的 Web 浏览器中渲染,因为类“rtf”在 CSS 样式表中定义为“display:none”。

原始输出有很多用途——特别是,您可以解决转换工具当前限制(如 TODO 部分中所列)的大部分问题。例如,即使转换工具尚不支持图像,您也可以发送图像的 RTF 代码。

<xhtml2rtf:raw class="rtf">
 {\*\shppict{\pict\picw3043\pich3043\picwgoal1725\pichgoal1725\pngblip
  89504e470d0a1a0a0000000d49484452000000730000007308020000002421
  aab1000000017352474200aece1ce90000000467414d410000b18f0bfc61050000
  ...
 }}
</xhtml2rtf:raw>

要找出适用于此图像的 RTF 代码,我只需使用 Word 编辑一个带有图片的文档,然后将其保存为 RTF 格式。我将结果文件以文本形式打开,并将 RTF 代码复制/粘贴到 XHTML 输出中,放在 <xhtml2rtf:raw> 标签内。

RTF 特定字段

转换工具提供了一些 RTF 特定字段。

页码

您可以通过 <xhtml2rtf:page_number> 在 RTF 文档中显示当前页码。

PAGE <xhtml2rtf:page_number/>
总页数

您可以通过 <xhtml2rtf:total_number_of_pages> 在 RTF 文档中显示总页数。

PAGE <xhtml2rtf:page_number/> / <xhtml2rtf:total_number_of_pages/>

示例

  1. Hello, World!(HTML 和 RTF
  2. 自定义页眉,两页(HTML 和 RTF
  3. 无页脚(HTML 和 RTF
  4. 表格(HTML 和 RTF
  5. 您正在阅读的 Readme 文件(RTF 格式

实现

  • XHTML 到 RTF 转换器包含一个 XSL 样式表,用于解析 XHTML 标签并生成其 RTF 等价物。

待办事项列表

参考文献

致谢

非常感谢 2can 为我的原始源代码添加的表格支持。

© . All rights reserved.