为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用Python Mammoth将DOCX转换为HTML?

标签:
Html5 Python

https://img1.sycdn.imooc.com/58c78869096f2b0706560406.jpg

我们在实际的项目开发的过程中,有时候不得不将文件从一种格式转换为另一种格式。

DOCX(由 Microsoft Word 使用)是一种非常常见的文件格式,被很多人使用。有时候,我们希望将 Word 文档转换为 HTML。

这可以通过 Mammoth 包轻松实现。它是一个用于将 DOCX 文件转换为 HTML 的简单、高效、快速的库。在本文中,我们将学习如何在 Python 中使用 Mammoth 将 DOCX 转换为 HTML。

安装 Mammoth

首先,在安装之前准备好并激活你的虚拟环境:

python3 -m venv myenv
. myenv/bin/activate

然后,使用pip安装 Mammoth:

pip3 install mammoth

本教程使用的 Mammoth 版本是 1.4.15。在测试的时候,请确保它是.docx 文件!

以上环境准备好后,现在让我们开始提取文本并将其转换成 HTML。

提取 DOCX 文件的原始文本

在转换为 HTML 时保留格式是 Mammoth 的最佳功能之一。这里我们只需要几行代码转换成你需要 DOCX 文件的文本。

使用 extract_raw_text()方法来获取它:

import mammoth

with open(input_filename, "rb") as docx_file:
    result = mammoth.extract_raw_text(docx_file)
    text = result.value # The raw text
    with open('output.txt', 'w') as text_file:
        text_file.write(text)

注意,此方法不会返回有效的 HTML 文档。它只返回页面上的文本,因此我们使用.txt 扩展来保存它。如果你确实需要保持布局或格式,你需要提取 HTML 内容。

将 Docx 转换为 HTML 并自定义样式映射

默认情况下,Mammoth 将文档转换为 HTML,但它不会提供有效的 HTML 页面。虽然网页浏览器可以显示内容,但它缺少一个<html>标签来封装文档,以及一个<body>标签来包含文档。

假设使用的是带有模板的网络框架。可能会定义一个模板来显示 Word 文档,并将 Mammoth 的输出加载到模板主体内。

Mammoth 不仅在如何使用其输出方面具有灵活性,而且在如何创建输出方面也具有很大的灵活性。特别是在我们想要样式化我们生成的 HTML 时,我们有很多选项。我们通过将每个 DOCX 格式规则匹配到相应的 CSS 规则来映射样式。

要查看你的 DOCX 文件有哪些样式,你有两个选择:

  1. 使用 MS Word 打开您的 docx 文件,并检查样式工具栏。

  2. 通过用解压管理器打开你的 DOCX 文件来研究 XML 文件,然后导航到/word/styles.xml并找到你的样式。

第二个选项适用于无法使用 MS Word 或无法解释和显示样式的替代文字处理程序的用户。

Mammoth 已经默认涵盖了某些最常用的样式映射。例如,Heading1在 docx 样式中映射到 HTML 元素的<h1>bold被映射到 HTML 元素的<strong>,等等。

我们还可以在映射时使用 Mammoth 来自定义文档的样式。例如,如果您想将 DOCX 文件中的所有bold出现次数更改为 HTML 中的斜体,可以这样子实现:

import mammoth

custom_styles = "b => i"

with open(input_filename, "rb") as docx_file:
    result = mammoth.convert_to_html(docx_file, style_map = custom_styles)
    text = result.value
    with open('output.html', 'w') as html_file:
        html_file.write(text)

通过 custom_styles 变量,左边的样式来自 DOCX 文件,而右边的是相应的 CSS。

假设我们想完全省略粗体出现的次数,我们可以将映射目标留空:

custom_styles = "b => "

有时我们转换的文档会有很多样式需要保留。这个时候再这样实现就会变得不切实际,要为每一个我们要映射的样式都创建一个变量。

不过有解法,我们可以使用docstrings一次映射我们想要的任意多个样式:

custom_styles = """ b => del
                    u => em
                    p[style-name='Heading 1'] => i"""

你可能已经注意到,最后的映射与其他的有点不同。在映射样式时,我们可以使用方括号[]并在其中添加条件,这样只有部分元素会以这种方式进行样式设置。

在我们的示例中,p[style-name='Heading 1']选择具有样式名称的段落Heading 1。我们也可以使用p[style-name^='Heading']来选择具有以Heading开头的样式名称的每个段落。

样式映射还允许我们将样式映射到自定义 CSS 类。通过这样做,我们可以随心所欲地修改 HTML 的样式。让我们举一个例子,我们在文档字符串中定义基本的自定义 CSS:

custom_css ="""
    <style>
    .red{
        color: red;
    }
    .underline{
        text-decoration: underline;
    }
    .ul.li{
        list-style-type: circle;
    }
    table, th, td {
    border: 1px solid black;
    }
    </style>
    """

现在我们可以更新我们的映射,以引用我们在<style>块中定义的 CSS 类:

custom_styles = """ b => b.red
                    u => em.red
                    p[style-name='Heading 1'] => h1.red.underline"""

并将 CSS 和 HTML 合并在一起:

edited_html = custom_css + html

这个时候如果 DOCX 文件包含任何这些元素,就能看到我们设置的样式结果。

通过以上方法我们已经知道如何映射样式,那就让我们使用一个更著名的 CSS 框架(以及相关的 JS)来让我们的 HTML 看起来更好,并练习一个更有可能的现实场景。

使用 Bootstrap(或其他任何前端框架)映射样式

就像我们之前处理custom_css一样,我们需要确保 CSS 与 HTML 一起加载。我们需要将 Bootstrap 文件 URI 或 CDN 添加到我们的 HTML 中:

bootstrap_css = '<link rel="nofollow" href="https://mybj123.com/links?url=aHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9ib290c3RyYXBANS4wLjAtYmV0YTIvZGlzdC9jc3MvYm9vdHN0cmFwLm1pbi5jc3M=" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">'
bootstrap_js = '<script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>'

这里我稍微调整我们的 custom_styles,以匹配我们的新 CSS 类:

custom_styles = """ b => b.mark
                    u => u.initialism
                    p[style-name='Heading 1'] => h1.card
                    table => table.table.table-hover
                    """

在第一行,我们将粗体 DOCX 样式映射到具有类的 HTML 元素,该类是 HTML 标签的 Bootstrap 类,用于突出显示文本的一部分。bmark<mark>

在第二行,我们为 HTML 元素添加了类,稍微减小了字体大小,并将文本转换为大写。initialismu

在第三行,我们选择所有具有样式名称的段落,并将其转换为具有 Bootstrap 类的 HTML 元素,该类为元素设置多个样式属性,例如背景颜色、位置和边框。Heading 1h1card

在最后一行,我们将 docx 文件中的所有表格转换为 HTML 元素,并使用 Bootstrap 的类来给它一个新的外观,同时我们通过添加 Bootstrap 类使其在悬停时高亮显示。tabletabletable-hover

和之前一样,我们使用点符号将多个类映射到同一个 HTML 元素,即使这些样式来自另一个来源。

最后,将 Bootstrap CDNs 添加到我们的 HTML 中:

edited_html = bootstrap_css + html + bootstrap_js

现在可以分享我们的 HTML,以下是完整的代码以供参考:

import mammoth

input_filename = "file-sample_100kB.docx"

custom_styles = """ b => b.mark
                    u => u.initialism
                    p[style-name='Heading 1'] => h1.card
                    table => table.table.table-hover
                    """


bootstrap_css = '<link rel="nofollow" href="https://mybj123.com/links?url=aHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9ib290c3RyYXBANS4wLjAtYmV0YTIvZGlzdC9jc3MvYm9vdHN0cmFwLm1pbi5jc3M=" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">'
bootstrap_js = '<script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>'


with open(input_filename, "rb") as docx_file:
    result = mammoth.convert_to_html(docx_file, style_map = custom_styles)
    html = result.value 

edited_html = bootstrap_css + html + bootstrap_js

output_filename = "output.html"
with open(output_filename, "w") as f: 
    f.writelines(edited_html)

此外,需要注意的一点是,在实际情况下,你可能不会像我们在这里所做的那样直接将 Bootstrap CSS 添加到 HTML 内容中。相反,你会将 HTML 内容加载或注入到一个特殊的 HTML 页面中,该页面已经包含了必要的 CSS 和 JS 捆绑包。

Mammoth 还允许我们修改我们正在转换的内容。

处理我们不想分享的图片

假设我们希望跳过 DOCX 文件中的图像不进行转换。convert_to_html()方法接受一个convert_image参数,这是一个图像处理函数。它返回一个应该转换并添加到 HTML 文档中的图像列表。

当然,如果我们覆盖它并返回一个空列表,它们将从转换后的页面中省略:

def ignore_image(image):
    return []

现在,让我们将该函数作为参数传递到convert_to_html()方法中:

with open(input_filename, "rb") as docx_file:
    result = mammoth.convert_to_html(docx_file, style_map = custom_styles, convert_image=ignore_image)
    html = result.value
    with open('output.html', 'w') as html_file:
        html_file.write(text)

就是这样! Mammoth 在生成 HTML 文件时将忽略所有图像。

到目前为止,我们一直在用 Python 编程方式使用 Mammoth。Mammoth 也是一个命令行工具,因此我们有了另一个将 DOCX 转换为 HTML 的接口。让我们在下一节中看看它的工作情况。

使用命令行工具将 DOCX 转换为 HTML

使用 Mammoth 的 CLI 进行文件转换通常如下所示:

mammoth path/to/input_filename.docx path/to/output.html

如果你想将图像从 HTML 中分离出来,可以指定一个输出文件夹:

mammoth file-sample_100kB.docx --output-dir=imgs

我们也可以像在 Python 中那样添加自定义样式。首先需要创建一个自定义样式文件:

touch my-custom-styles

然后,我们将在其中添加自定义样式,语法与之前相同:

b => b.red
u => em.red
p[style-name='Heading 1'] => h1.red.underline

现在我们可以生成带有自定义样式的 HTML 文件:

mammoth file-sample_100kB.docx output.html --style-map=my-custom-styles

大功告成!您的文档已按定义的自定义样式进行转换。https://mybj123.com/28792.html

结语

文件类型转换在处理网页技术时是一种常见需求。将 DOCX 文件转换为易于操作的 HTML 格式,使我们能够根据需要重建数据。使用 Mammoth,我们学会了如何从 docx 中提取文本并将其转换为 HTML。

在转换为 HTML 时,我们可以使用我们创建的 CSS 规则或常见的 UI 框架提供的规则来样式化输出。我们还可以省略不需要在 HTML 中可用的数据。


点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消