使用 Python 将演示文稿导出为带外部链接图像的 HTML
概述
默认情况下,Aspose.Slides 将演示文稿导出为一个自包含的 HTML 文件。图像和其他资源直接写入 HTML,通常以 Base64 数据的形式存在。这在需要单个便携文件时很方便,但并不总是网站、CMS 或服务器端转换流水线的最佳格式。
当您想要:
- 减小 HTML 文档的大小;
- 在浏览器或 CDN 中单独缓存图像;
- 在导出后检查、替换、压缩或后处理生成的图像;
- 使输出结构更接近 Web 应用程序的预期
时,请使用外部链接的图像。
对于通用的 HTML 转换工作流,请参阅Convert PowerPoint Presentations to HTML。本文聚焦于导出过程中的图像链接部分。
链接图像导出工作原理
在 .NET 和 Java 中,ILinkEmbedController 表示导出器用于决定资源是嵌入还是链接的回调接口。在通过 .NET 的 Python 中,Python 类目前不能直接实现此 .NET 回调接口,因此实际工作流如下:
- 使用HtmlOptions将演示文稿导出为 HTML;
- 使用SlideImageFormat结合SVGOptions,使幻灯片在 HTML 中以 SVG 形式呈现;
- 将 HTML 中
data:URL 的 Base64 图像数据移动到独立的文件; - 将原始的
data:URL 替换为相对链接,如assets/resource-1.jpg。
文件系统路径和浏览器 URL 是不同的概念。例如,下面示例将图像文件写入磁盘上的 html-output/assets,而 HTML 中包含的相对 URL 如 assets/resource-1.jpg。浏览器会相对于包含链接的 HTML 文件解析这些 URL。
使用链接图像导出HTML
以下 Python 示例创建输出目录,将 HTML 文件保存到该目录,在 assets 子目录中存储提取的图像,并将 Base64 图像 URL 重写为相对链接。示例在 Aspose.Slides 提供安全文件扩展名时,提取常见的 Base64 图像格式。未识别的 Data URL 将保持嵌入状态。
import base64
import os
import re
import aspose.slides as slides
import aspose.slides.export as slides_export
EXTENSIONS_BY_CONTENT_TYPE = {
"image/jpeg": ".jpg",
"image/png": ".png",
"image/gif": ".gif",
"image/bmp": ".bmp",
"image/svg+xml": ".svg",
"image/tiff": ".tiff",
"image/x-emf": ".emf",
"image/x-wmf": ".wmf",
}
DATA_URI_PATTERN = re.compile(
r"data:(?P<content_type>[-\w.+]+/[-\w.+]+);base64,(?P<data>[A-Za-z0-9+/=\r\n]+)"
)
def export_presentation_to_html_with_linked_images(
input_file_path,
output_directory,
asset_directory_name="assets",
):
asset_directory = os.path.join(output_directory, asset_directory_name)
os.makedirs(output_directory, exist_ok=True)
os.makedirs(asset_directory, exist_ok=True)
html_options = slides_export.HtmlOptions()
html_options.html_formatter = slides_export.HtmlFormatter.create_document_formatter("", False)
html_options.slide_image_format = slides_export.SlideImageFormat.svg(
slides_export.SVGOptions()
)
html_file_path = os.path.join(output_directory, "presentation.html")
with slides.Presentation(input_file_path) as presentation:
presentation.save(html_file_path, slides_export.SaveFormat.HTML, html_options)
externalize_base64_images(html_file_path, asset_directory, asset_directory_name)
def externalize_base64_images(html_file_path, asset_directory, asset_directory_name):
with open(html_file_path, "r", encoding="utf-8-sig") as html_file:
html_content = html_file.read()
saved_resource_names = {}
resource_index = 1
def replace_data_uri(match):
nonlocal resource_index
data_uri = match.group(0)
if data_uri in saved_resource_names:
return saved_resource_names[data_uri]
content_type = match.group("content_type").lower()
extension = EXTENSIONS_BY_CONTENT_TYPE.get(content_type)
if extension is None:
return data_uri
encoded_data = match.group("data")
image_data = base64.b64decode(encoded_data)
if len(image_data) == 0:
return data_uri
file_name = f"resource-{resource_index}{extension}"
resource_index += 1
file_path = os.path.join(asset_directory, file_name)
with open(file_path, "wb") as image_file:
image_file.write(image_data)
linked_url = f"{asset_directory_name}/{file_name}"
saved_resource_names[data_uri] = linked_url
return linked_url
updated_html_content = DATA_URI_PATTERN.sub(replace_data_uri, html_content)
with open(html_file_path, "w", encoding="utf-8", newline="\n") as html_file:
html_file.write(updated_html_content)
input_file_path = "presentation.pptx"
output_directory = "html-output"
export_presentation_to_html_with_linked_images(input_file_path, output_directory)
导出后,输出文件夹可能具有以下结构:
html-output/
presentation.html
assets/
resource-1.jpg
resource-2.png
具体的文件取决于演示文稿的内容和导出选项。例如,光栅图像通常导出为 JPEG 或 PNG。Aspose.Slides 可能会选择与源演示文稿不同的图像编解码器,以获得更小或更合适的文件。具有透明度的图像会导出为 PNG。
选择部署用的URL
示例使用相对 URL 前缀:assets/。如果 presentation.html 位于 html-output/presentation.html,浏览器会加载 html-output/assets/resource-1.jpg。
在文件部署到其他位置时,可使用不同的资产目录名称或重写生成的链接:
- 当资产目录与 HTML 文件位于同一目录时使用
assets/; - 当资产目录位于 HTML 文件的上一级目录时使用
../assets/; - 当文件上传至 CDN 或静态文件服务器时使用
https://cdn.example.com/presentations/job-123/assets/。
在服务器应用程序中,为每个转换任务使用唯一的输出目录或对象存储前缀,以避免覆盖其他导出的文件。
何时使用嵌入而非链接
当输出必须是单个文件时(例如电子邮件附件、离线预览或需要在不带资产文件夹的情况下移动的文档),嵌入的 Base64 HTML 仍然有用。HTML 将由 Web 应用服务、存储在 CMS 中、通过构建流水线优化或由浏览器独立缓存时,链接图像是更合适的选择。
常见问题
我可以只外部化图像而保持其他资源嵌入吗?
可以。示例仅提取 image/* 类型的 Base64 数据 URL,这些类型列在 EXTENSIONS_BY_CONTENT_TYPE 中。其他数据 URL 将保持嵌入。
为什么导出图像的扩展名与源演示文稿不同?
Aspose.Slides 可能在 HTML 导出过程中重新编码光栅图像,以优化文件大小或浏览器兼容性。例如,源文件中的图像可能会根据渲染结果被写入为 JPEG 或 PNG。
移动 HTML 文件后相对 URL 还能工作吗?
相对 URL 只在保持相同的相对文件夹结构时有效。如果 HTML 引用了 assets/resource-1.png,则 assets 文件夹必须与 HTML 文件位于同一目录,除非您生成了不同的 URL 前缀。
服务器应用程序应该复用同一输出文件夹吗?
不应该。为每个转换任务使用唯一的输出目录或存储前缀。这样可以避免文件名冲突,并防止一次导出覆盖另一项导出生成的资源。