Spire.Presentation 11.5.1 现已正式发布。该版本优化了从 PowerPoint 到 PDF 的转换功能。同时,一些在加载 PPT 文档、转换形状到 SVG 以及获取图片时出现的问题也得以成功修复。更多详情如下。
问题修复:
https://www.e-iceblue.cn/Downloads/Spire-Presentation-NET.html
Spire.PDF 12.5.1 现已正式发布。该版本在数字签名中新增支持 SHA-2 和 SHA-256 算法,同时修复了一些问题,例如打印 PDF 时内容丢失的问题。更多详情如下。
新功能:
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile(inputFile);
X509Certificate2 cert = new X509Certificate2(inputFile_pfx, "e-iceblue");
IPdfSignatureFormatter formatter = new PdfPKCS7Formatter(cert, false);
PdfMDPSignatureMaker pdfMDPSignatureMaker = new PdfMDPSignatureMaker(pdf, formatter);
PdfSignature signature = pdfMDPSignatureMaker.Signature;
signature.Name = "e-iceblue";
signature.ContactInfo = "028-81705109";
signature.Location = "chengdu";
signature.Reason = " this document";
PdfSignatureAppearance appearance = new PdfSignatureAppearance(signature);
appearance.NameLabel = "Signer: ";
appearance.ContactInfoLabel = "ContactInfo: ";
appearance.LocationLabel = "Loaction: ";
appearance.ReasonLabel = "Reason: ";
pdfMDPSignatureMaker.MakeSignature("signName", pdf.Pages[0], 100, 100, 250, 200, appearance);
foreach (HashAlgorithmType hashAlgorithmType in Enum.GetValues(typeof(HashAlgorithmType)))
{
if (string.Equals(hashAlgorithmType.ToString(), "SM3", StringComparison.OrdinalIgnoreCase))
{
continue;
}
//default value of HashAlgorithm is SHA256
formatter.Properties.HashAlgorithm = hashAlgorithmType;
try
{
pdf.SaveToFile( "out.pdf", FileFormat.PDF);
}
catch (Exception ex)
{
Console.WriteLine($"error:{ex.Message}");
}
}
pdf.Dispose();
问题修复:

在涉及网页内容和文档处理的工作中,掌握使用 Python 解析 HTML 的能力是各个领域开发者的一项必备技能。HTML 解析指的是从 HTML 文档中提取有价值的信息、操作内容,以及高效处理网页数据的过程。无论你是在做网页抓取、数据提取、内容分析,还是文档处理,熟练掌握 Python 的 HTML 解析技术,都能显著提升开发效率与处理能力。
本文将介绍如何使用 Spire.Doc for Python 高效解析 HTML。你将学习如何从 HTML 字符串、本地 HTML 文件以及网页 URL 中读取并处理 HTML 内容,并在项目中实施 HTML 解析的最佳实践。
HTML(HyperText Markup Language,超文本标记语言)是网页内容展示的基础,用于构建和呈现网站内容。通过解析 HTML,你可以:
虽然像 BeautifulSoup 这样的库在轻量级解析方面表现出色,但当需要将 HTML 解析与文档创建或转换集成时,Spire.Doc for Python 则更胜一筹。它提供了一个健壮的框架,能以结构化的文档对象模型(DOM)来解析和交互 HTML 内容。
在开始解析 HTML 之前,需要先安装 Spire.Doc for Python。该库可以通过 PyPI 获得,安装非常直接:
pip install Spire.Doc
执行后将自动安装最新版 Spire.Doc 及其依赖项。安装完成后,即可开始解析 HTML。
Spire.Doc 的核心机制,是将 HTML 基于标签的结构转换为层级化文档模型。该模型由多个对象组成,用于表示章节、段落及其他元素,从而还原 HTML 原始结构。
下面通过实际示例来演示其工作方式。
如果你已经拥有 HTML 字符串(例如 API 返回结果或用户输入),可以直接从字符串解析 HTML。这种方式非常适合测试场景或处理较短的静态 HTML 内容。
from spire.doc import *
from spire.doc.common import *
# 定义 HTML 字符串内容
html_string = """
<html>
<head>
<title>示例页面</title>
</head>
<body>
<h1>欢迎</h1>
<p>这是一个<strong>HTML解析</strong>的演示。</p>
<ul>
<li>功能一:读取字符串</li>
<li>功能二:读取文件</li>
<li>功能三:读取URL</li>
</ul>
</body>
</html>
"""
# 初始化一个新的 Document 对象
doc = Document()
# 向文档中添加节和段落
section = doc.AddSection()
paragraph = section.AddParagraph()
# 从字符串加载 HTML 内容
paragraph.AppendHTML(html_string)
print("解析后的 HTML 文本:")
print("-----------------------------")
# 从解析后的 HTML 中提取文本内容
parsed_text = doc.GetText()
# 打印结果
print(parsed_text)
# 关闭文档
doc.Close()
工作原理:
<h1> 变成 "标题 1" 样式,<ul> 变成列表)。输出结果:

Spire.Doc 还支持通过 SaveToFile() 方法,将解析后的 HTML 转换为 TXT、Word 等格式。
对于本地 HTML 文件,Spire.Doc 可通过一个方法直接加载并解析。这非常适合处理离线 HTML 内容,例如下载的网页或静态报告。
from spire.doc import *
from spire.doc.common import *
# 定义本地 HTML 文件的路径
html_file_path = "example.html"
# 创建一个 Document 实例
doc = Document()
# 加载并解析 HTML 文件
doc.LoadFromFile(html_file_path, FileFormat.Html)
# 分析文档结构
print(f"文档包含 {doc.Sections.Count} 个节")
print("-"*40)
# 处理每个节
for section_idx in range(doc.Sections.Count):
section = doc.Sections.get_Item(section_idx)
print(f"第 {section_idx + 1} 节")
print(f"本节有 {section.Body.Paragraphs.Count} 个段落")
print("-"*40)
# 遍历当前节中的段落
for para_idx in range(section.Paragraphs.Count):
para = section.Paragraphs.get_Item(para_idx)
# 获取段落样式名称和文本内容
style_name = para.StyleName
para_text = para.Text
# 如果有内容,打印段落信息
if para_text.strip():
print(f"[{style_name}] {para_text}\n")
# 节之间增加间距
print()
# 关闭文档
doc.Close()
主要功能:
输出结果:

在将 HTML 文件加载到 Document 对象后,还可以进一步提取 HTML 中的表格、超链接等元素。
要直接从实时网页解析 HTML,首先使用 requests 获取网页 HTML 内容,再将内容传递给 Spire.Doc 进行解析。这是网页抓取和实时数据提取的核心。
通过 pip 安装 Requests 库:
pip install requests
解析网页的 Python 代码:
from spire.doc import *
from spire.doc.common import *
import requests
# 从 URL 获取 HTML 内容
def fetch_html_from_url(url):
"""从 URL 获取 HTML 并处理错误(例如 404、网络问题)"""
# 用 User-Agent 模拟浏览器(避免被网站拦截)
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}
try:
response = requests.get(url, headers=headers)
response.raise_for_status() # 对 HTTP 错误抛出异常
return response.text # 返回原始 HTML 内容
except requests.exceptions.RequestException as e:
raise Exception(f"获取 HTML 时出错: {str(e)}")
# 指定目标 URL
url = "https://www.e-iceblue.cn/Introduce/Spire-Doc-Python.html"
print(f"正在从以下 URL 获取 HTML: {url}")
# 获取 HTML 内容
html_content = fetch_html_from_url(url)
# 创建文档并将 HTML 内容插入其中
doc = Document()
section = doc.AddSection()
paragraph = section.AddParagraph()
paragraph.AppendHTML(html_content)
# 提取并显示摘要信息
print("\n解析后的内容摘要:")
print(f"节数: {doc.Sections.Count}")
print("-------------------------------------------")
# 提取并显示标题
print("找到的标题:")
for para_idx in range(section.Paragraphs.Count):
para = section.Paragraphs.get_Item(para_idx)
if isinstance(para, Paragraph) and para.StyleName.startswith("Heading"):
print(f"- {para.Text.strip()}")
# 关闭文档
doc.Close()
步骤说明:
输出结果:

为了更高效地使用 Spire.Doc 解析 HTML,建议遵循以下实践:
import os
html_file = "data.html"
if os.path.exists(html_file):
doc.LoadFromFile(html_file, FileFormat.Html)
else:
print(f"错误: 文件 '{html_file}' 未找到。")
try:
doc.LoadFromFile("sample.html", FileFormat.Html)
except Exception as e:
print(f"加载 HTML 时出错: {e}")
优化大文件解析:对于大型 HTML 文件,考虑分块加载内容或禁用非必要的解析功能,以提高性能。
清洗提取的数据:使用 Python 字符串方法(如 strip()、replace())清理空格和无用字符。
保持库版本更新:定期使用 pip install --upgrade Spire.Doc 更新 Spire.Doc,以获得改进的解析逻辑与 Bug 修复。
Python 让 HTML 解析变得简单高效。无论是 HTML 字符串、本地文件还是在线网页,结合 Requests(负责获取 HTML)与 Spire.Doc(负责结构化解析),都可以轻松完成网页抓取与内容提取等复杂任务。通过本文中的示例与最佳实践,你可以快速将无结构的 HTML 转换为可操作、有组织的数据。
如果你想进一步体验 Spire.Doc for Python 的完整功能,你可以在此处申请 30 天试用授权。

现代 Web 应用程序越来越多地需要在浏览器中直接查看和编辑 Word、Excel 和 PowerPoint 文件。相比将用户跳转到新页面或外部应用,许多开发者更倾向于将 Office 编辑器直接嵌入网页,使其成为现有界面的一部分,从而提供更加流畅的在线文档处理体验。
然而,从零开始构建一个功能完善的在线文档编辑器并不容易,通常需要处理文档渲染、格式兼容性、编辑交互以及响应式 UI 集成等复杂问题。借助 Spire.OfficeJS,开发者可以使用 JavaScript 快速将基于浏览器的 Office 编辑器集成到 HTML 页面中,而无需在客户端设备上安装 Microsoft Office 等文档处理工具。
本文将演示如何在 HTML 中嵌入文档编辑器,包括页面布局设计、编辑器初始化以及动态文档加载,并提供完整的实用示例。
目录
将文档编辑器作为页面布局的一部分嵌入,可以实现无缝工作流程并提升用户体验。常见应用场景包括:
用户可以直接在当前 Web 界面中处理文档,而无需在单独的应用程序或专用页面中打开文档。
有两种常见的集成方式:
| 方式 | 描述 |
|---|---|
| 全屏编辑器 | 整个页面专用于文档编辑 |
| 嵌入式编辑器 | 编辑器作为更大 UI 的一部分集成 |
本教程重点介绍嵌入式方法,即文档编辑器与侧边栏、文件列表、导航菜单和其他应用程序组件协同工作。
在集成编辑器之前,请确保具备以下条件:
下载并解压 Spire.OfficeJS 包 并将其解压到本地目录。
初始化字体
cd Spire.OfficeJS.Windows_11.5.7
run_genallfonts.bat
部署前需要先执行“run_genallfonts.bat”初始化字体,执行后web文件夹下会多出fontsweb文件夹包含基础字体。如果需要新增其它字体,请参阅:如何在 Spire.OfficeJS 前端编辑器中添加自定义字体

启动 Spire.OfficeJS 后端服务
run_servers.bat
这将在 http://localhost:3000 上启动编辑器服务
启动示例服务器(提供示例文档)
示例服务器运行在 http://localhost:3000,示例文档位于 /public/samples/
如需了解如何在 JavaScript 应用程序中安装和部署 Spire.OfficeJS,请参阅:如何在 JavaScript 中部署 Spire.OfficeJS
注意: 以下代码示例使用 localhost 地址进行本地开发和测试。在生产环境中,请将其替换为实际的服务器 URL 或域名。
第一步是设计一个布局,使编辑器仅占据页面的一部分。以下是带有侧边栏和编辑器区域的常见结构:
<!DOCTYPE html>
<html>
<head>
<title>文档编辑器集成</title>
<style>
.app-container {
display: flex;
height: 100vh;
}
.sidebar {
width: 250px;
border-right: 1px solid #ddd;
padding: 10px;
background: #f5f5f5;
}
.editor-container {
flex: 1;
position: relative;
}
</style>
</head>
<body>
<div class="app-container">
<div class="sidebar">
<h3>文档列表</h3>
<ul>
<li onclick="openDocument('http://localhost:3000/public/samples/sample.docx', 'docx')">示例文档.docx</li>
<li onclick="openDocument('http://localhost:3000/public/samples/sample.xlsx', 'xlsx')">示例电子表格.xlsx</li>
<li onclick="openDocument('http://localhost:3000/public/samples/sample.pptx', 'pptx')">示例演示文稿.pptx</li>
</ul>
</div>
<div class="editor-container" id="editor"></div>
</div>
</body>
</html>
一个简单的嵌入式文档管理界面在打开文档前可能如下所示:

flex: 1 填充剩余空间这种结构反映了真实世界的应用程序布局,而非简单的演示页面。
加载 Spire.OfficeJS 脚本并在指定容器内初始化编辑器:
<script src="http://localhost:3000/web/editors/spireapi/SpireCloudEditor.js"></script>
<script>
function initEditor() {
const config = {
user: {
id: 'user1',
name: '演示用户'
},
fileAttrs: {
sourceUrl: "http://localhost:3000/public/samples/sample.docx",
fileInfo: {
ext: "docx",
name: "示例文档.docx"
}
},
editorAttrs: {
editorType: "document",
editorMode: "edit",
editorWidth: "100%",
editorHeight: "100%",
platform: "desktop",
viewLanguage: "zh",
canEdit: true,
canDownload: true,
canForcesave: true,
useWebAssemblyDoc: true,
useWebAssemblyExcel: true,
useWebAssemblyPpt: true,
useWebAssemblyPdf: true,
serverless: {
useServerless: true,
baseUrl: "http://localhost:3000",
coAuthorUrl: "http://localhost:8000" //协同编辑服务
},
embedded: {
saveUrl: "",
toolbarDocked: 'top'
},
events: {
onDocumentReady: function() {
console.log('文档已就绪');
},
onError: function(event) {
console.error('编辑器错误:', event);
},
onSave: function(data) {
console.log('文档已保存', data);
if (data && data.data && data.data.length >= 2) {
downloadFile(data.data[1], data.data[0]);
}
}
}
}
};
new SpireCloudEditor.OpenApi("editor", config);
}
function downloadFile(file, fileName) {
const a = document.createElement('a');
const url = URL.createObjectURL(file);
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
initEditor();
</script>
初始化后,嵌入式 Office 编辑器将直接加载到目标容器中:

为帮助快速入门,可以下载本文中使用的完整可运行 HTML 示例:
注意:在打开示例编辑器之前,请先启动 Spire.OfficeJS 服务。以上下载演示示例使用 window.location.hostname 动态检测当前主机,因此应通过 HTTP 服务器打开。如需直接在浏览器中预览文件,请将其替换为固定的主机地址。
编辑器在 ID 为 "editor" 的指定容器元素内渲染,使其能够作为 UI 组件运行,而不是接管整个页面。
在实际应用中,用户需要动态打开不同的文件。可以通过使用新配置重新初始化编辑器来实现:
let editorInstance = null;
function openDocument(sourceUrl, ext) {
const fileName = sourceUrl.split('/').pop();
if (editorInstance) {
editorInstance.destroy();
}
const container = document.getElementById("editor");
container.innerHTML = "";
const config = {
user: {
id: 'user1',
name: '演示用户'
},
fileAttrs: {
sourceUrl: sourceUrl,
fileInfo: {
ext: ext,
name: fileName
}
},
editorAttrs: {
editorType: getEditorType(ext),
editorMode: "edit",
editorWidth: "100%",
editorHeight: "100%",
platform: "desktop",
viewLanguage: "zh",
canEdit: true,
canDownload: true,
canForcesave: true,
useWebAssemblyDoc: true,
useWebAssemblyExcel: true,
useWebAssemblyPpt: true,
useWebAssemblyPdf: true,
serverless: {
useServerless: true,
baseUrl: "http://localhost:3000",
coAuthorUrl:"http://localhost:8000" //协同编辑服务地址
},
embedded: {
saveUrl: "",
toolbarDocked: 'top'
},
events: {
onSave: function(data) {
if (data && data.data && data.data.length >= 2) {
downloadFile(data.data[1], data.data[0]);
}
}
}
}
};
editorInstance = new SpireCloudEditor.OpenApi("editor", config);
}
function getEditorType(ext) {
const extLower = ext.toLowerCase();
switch (extLower) {
case 'docx':
case 'doc':
case 'rtf':
case 'txt':
case 'odt':
return 'document';
case 'xlsx':
case 'xls':
case 'csv':
case 'ods':
return 'spreadsheet';
case 'pptx':
case 'ppt':
case 'odp':
return 'presentation';
default:
return 'document';
}
}
openDocument,传入文件 URL 和扩展名此模式对于构建交互式文档管理系统至关重要。
在动态切换文档时,正确的清理可以避免 UI 问题:
错误处理和加载状态
始终使用 try-catch 进行错误处理,并考虑添加加载指示器:
let editorInstance = null;
async function openDocument(sourceUrl, ext) {
try {
if (editorInstance) {
editorInstance.destroy();
}
const container = document.getElementById("editor");
container.innerHTML = "";
const config = { /* ... 配置 ... */ };
editorInstance = new SpireCloudEditor.OpenApi("editor", config);
} catch (error) {
console.error('加载文档失败:', error);
}
}
关键点:
可以使用 editorAttrs 中的配置选项微调编辑器的行为。
将编辑器设置为仅查看模式:
editorAttrs: {
editorMode: "view",
isReadOnly: true
}
限制特定操作:
editorAttrs: {
canEdit: false,
canDownload: false,
canComment: true,
canPrint: true
}
通过设置界面语言支持国际化:
editorAttrs: {
viewLanguage: "en"
}
支持的语言包括英语("en")和中文("zh")。
在无服务器模式下,保存通过 onSave 事件回调处理:
editorAttrs: {
embedded: {
saveUrl: "", // 在无服务器模式下保持为空
toolbarDocked: 'top'
},
events: {
onSave: function(data) {
console.log('文档已保存', data);
if (data && data.data && data.data.length >= 2) {
// data.data[0] = 文件名, data.data[1] = 文件 blob
downloadFile(data.data[1], data.data[0]);
}
}
}
}
function downloadFile(file, fileName) {
const a = document.createElement('a');
const url = URL.createObjectURL(file);
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
当用户点击保存时,文档将自动下载到本地计算机。
为支持 HTTP 和 HTTPS 环境,使用动态协议检测:
const currentHost = window.location.hostname;
const currentProtocol = window.location.protocol;
const baseUrl = `${currentProtocol}//${currentHost}:3000`;
const exampleBaseUrl = `${currentProtocol}//${currentHost}:3000`;
const coAuthorUrl = `${currentProtocol}//${currentHost}:8000`;
这可以防止在页面通过 HTTPS 提供服务时出现混合内容错误。
用户可以上传本地文档进行编辑:
<input type="file" id="fileInput" accept=".docx,.xlsx,.pptx,.doc,.xls,.ppt"
onchange="handleFileUpload(event)">
async function handleFileUpload(event) {
const file = event.target.files[0];
const fileName = file.name;
const ext = fileName.split('.').pop().toLowerCase();
const fileData = await new Promise((resolve) => {
const reader = new FileReader();
reader.onload = (e) => resolve(e.target.result);
reader.readAsArrayBuffer(file);
});
const config = {
user: {
id: 'user1',
name: '演示用户'
},
fileAttrs: {
sourceUrl: 'upload://' + fileName,
fileInfo: { ext, name: fileName }
},
editorAttrs: {
editorType: getEditorType(ext),
serverless: {
useServerless: true,
baseUrl: baseUrl,
coAuthorUrl: coAuthorUrl, //协同编辑服务
fileData: fileData // 直接传递文件数据
}
}
};
editorInstance = new SpireCloudEditor.OpenApi("editor", config);
}
在大多数实际场景中,在线文档编辑器并非整个应用程序,而是作为大型业务系统中的一个模块运行。
典型的集成模式包括:
由于基于浏览器的 Office 编辑器挂载到标准 DOM 容器中,它可以与以下内容无缝共存:
这种模块化架构允许开发者构建丰富的以文档为中心的应用程序,而不会影响现有的 UI 模式或用户工作流。
虽然示例使用纯 JavaScript,但相同的概念也适用于现代框架。关键原则保持不变:在组件挂载后初始化编辑器,并将其渲染到 DOM 容器中。
useEffect(() => {
new SpireCloudEditor.OpenApi("editor-container", config);
}, []);
mounted() {
new SpireCloudEditor.OpenApi("editor-container", config);
}
ngAfterViewInit(): void {
new SpireCloudEditor.OpenApi("editor-container", config);
}
有关完整的框架特定设置和部署说明,请参阅专门的集成指南:
以下是开发者遇到的常见问题及其解决方案:
http://localhost:3000/web/editors/spireapi/SpireCloudEditor.jsfile:// 协议打开 HTML 文件python -m http.server 8080 或 npx http-server -p 8080)并通过 http://localhost:8080/your-file.html 访问sourceUrl 可通过 HTTP 公开访问。将占位符 URL(如 https://example.com/)替换为真实可访问的文档 URLeditorAttrs 中缺少 serverless 配置serverless 和 useWebAssembly* 设置editorInstance.destroy()editorWidth 和 editorHeight 设置为 "100%",并确保容器具有定义的尺寸本文演示了如何使用 Spire.OfficeJS 将基于 Web 的 Office 文档编辑器嵌入现有 HTML 页面。通过将编辑器视为模块化组件,开发者可以将文档编辑功能直接集成到 Web 应用程序中,而无需将用户重定向到单独的页面。
这种方法能够构建丰富的文档管理界面,使编辑器与导航、文件列表和其他 UI 组件共存。通过适当的配置,嵌入式编辑器提供与全屏解决方案相同的功能强大的特性,同时保持无缝的用户体验。
Spire.OfficeJS 支持多种文档格式,包括 Word(DOCX)、Excel(XLSX)和 PowerPoint(PPTX),使其成为基于 Web 的文档处理需求的全面解决方案。
如果希望在真实项目环境中测试 Spire.OfficeJS,可以在此处申请免费临时许可证:申请临时许可证
可以通过在特定的 HTML 容器元素内初始化 SpireCloudEditor.OpenApi,并配置文档源和编辑器设置来嵌入文档编辑器。
不需要。Spire.OfficeJS 使用 WebAssembly 进行浏览器端文档处理,同时依赖后端服务提供编辑器界面和相关资源。客户端计算机上无需安装 Microsoft Office。
可以。编辑器可以集成到任何 JavaScript 框架中,通过在组件生命周期(如 React 中的 useEffect 或 Vue 中的 mounted)将其挂载到 DOM 元素来实现。
Spire.OfficeJS 支持 Word 文档(DOCX、DOC)、Excel 电子表格(XLSX、XLS)和 PowerPoint 演示文稿(PPTX、PPT),以及 PDF 查看。
在无服务器模式下,在 editorAttrs.events 中配置 onSave 事件回调。当用户保存时,回调接收文件数据,可以自动下载或进一步处理。
我们很高兴地宣布发布 Spire.XLS for Python 16.5.0。本次更新主要解决了数据透视表单元格中文本换行无效的问题。详情请参见以下变更内容。
问题修复:
我们很高兴地宣布,Spire.Office 11.4.0 正式发布。在此版本中,Spire.Doc 支持将图表保存为模板,以及通过 CompareOptions 进行多维度文档对比。Spire.XLS提升了 PDF 与 SVG 转换的稳定性。Spire.Presentation新增支持将 PPTX 保存为视频。Spire.PDF优化了 PDF 合并功能的内存占用,以及增强了 PDF 到 PDF/A 和图片的转换功能。此外,本版本还修复了大量已知问题。
本次发布集成了以下组件的最新版本:Spire.Doc、Spire.PDF、Spire.XLS、Spire.Presentation、Spire.Barcode、Spire.DocViewer、Spire.PDFViewer、Spire.Email、Spire.Spreadsheet 和 Spire.OfficeViewer。
https://www.e-iceblue.cn/Downloads/Spire-Office-NET.html
调整:
ToPdfParameterList.IsAtlast-->ToPdfParameterList.IsAtLeast
新功能:
Document doc = new Document();
doc.LoadFromFile(inputFile);
int count = 1;
foreach (Section sec in doc.Sections)
{
foreach (Spire.Doc.Documents.Paragraph paragraph in sec.Paragraphs)
{
foreach (DocumentObject obj in paragraph.ChildObjects)
{
if (obj is ShapeObject shape)
{
Chart chart = shape.Chart;
if (chart == null)
continue;
string fileName = Path.Combine(outputPath, $"{count}.crtx");
chart.SaveAsTemplate(fileName);
count++;
}
}
}
}
string genName = "Testing For Set Producer";
Document doc = new Document();
doc.LoadFromFile(filename);
ToPdfParameterList toPdf = new ToPdfParameterList();
toPdf.GeneratorName = genName;
doc.SaveToFile("result.pdf", toPdf);
Document doc = new Document();
doc.LoadFromFile(inputFile);
StringBuilder sb = new StringBuilder();
int number = 1;
foreach (Section sec in doc.Sections)
{
foreach (Paragraph paragraph in sec.Paragraphs)
{
for (int i = 0; i < paragraph.ChildObjects.Count; i++)
{
DocumentObject obj = paragraph.ChildObjects[i];
if (obj is ShapeObject)
{
ShapeObject shape = obj as ShapeObject;
Chart chart = shape.Chart;
sb.Append("\r\n\r\n第" + number + "页:\r\n" + "获取所有X轴数据:");
for (int x = 0; x < chart.XValues.Count; x++)
{
ChartValue xVal = chart.XValues[x];
// 获取所有X轴数据值
sb.Append(xVal.StringValue + " ");
}
//获取第一个系列
ChartSeries series = chart.Series[0];
sb.Append("\r\n获取Y轴数据:");
foreach (ChartValue yVal in series.YValues)
{
// 获取第一个系列所有的Y轴数据值
sb.Append(yVal.Value + " ");
}
}
}
}
number++;
}
Document doc = new Document();
foreach (ChartDataLabelPosition position in Enum.GetValues(typeof(ChartDataLabelPosition)))
{
Section section = doc.AddSection();
section.AddParagraph().AppendText(position.ToString());
Spire.Doc.Documents.Paragraph newPara = section.AddParagraph();
ShapeObject shape = newPara.AppendChart(ChartType.Pie, 500, 300);
Chart chart = shape.Chart;
chart.Series[0].HasDataLabels = true;
chart.Series[0].DataLabels.ShowCategoryName = true;
chart.Series[0].DataLabels.ShowValue = true;
// 设置Position
chart.Series[0].DataLabels.Position = position;
ShapeObject shape2 = newPara.AppendChart(ChartType.Bubble, 500, 300);
Chart chart2 = shape2.Chart;
chart2.Series[0].HasDataLabels = true;
chart2.Series[0].DataLabels.ShowCategoryName = true;
chart2.Series[0].DataLabels.ShowValue = true;
chart2.Series[0].DataLabels.Position = position;
}
doc.SaveToFile(outputFile, FileFormat.Docx);
doc.Dispose();
Document doc1 = new Document();
doc1.LoadFromFile(inputFile_1);
Document doc2 = new Document();
doc2.LoadFromFile(inputFile_2);
CompareOptions options = new CompareOptions();
options.CompareMoves = false;
options.IgnoreCaseChanges = false;
options.IgnoreComments = true;
options.IgnoreFields = true;
options.IgnoreFootnotes = true;
options.IgnoreTables = true;
options.IgnoreTextboxes = true;
doc1.Compare(doc2, "user", new DateTime(), options);
doc1.SaveToFile(outputFile, FileFormat.Docx2013);
问题修复:
调整:
问题修复:
新功能:
注意:使用此功能需要指定 ffmpeg 路径。
Presentation ppt = new Presentation();
ppt.LoadFromFile(inputFile);
SaveToVideoOption saveOption = new SaveToVideoOption(ffmpegDir);
ppt.SaveToVideoOption=saveOption;// 默认每张幻灯片5秒
ppt.SaveToFile(outputFile_mp4, FileFormat.MP4);
ppt.SaveToFile(outputFile_wmv, FileFormat.WMV);
ppt.Dispose();
问题修复:
优化:
问题修复:
Spire.Office for Java 11.4.0 已正式发布。在该版本中,Spire.Doc for Java 支持将图表保存为模板,以及获取图表 X 轴和 Y 轴的数据值;Spire.PDF for Java支优化了合并 PDF 文档时对内存的消耗。除此之外,一些在转换和操作 Word、Excel、PDF和 PPT 文档时出现的问题也已成功被修复。更多新功能及问题修复详情如下。
https://www.e-iceblue.cn/Downloads/Spire-Office-JAVA.html
新功能:
Document doc = new Document();
doc.loadFromFile(inputFile);
int count = 1;
for (Section sec : (Iterable extends Section>) doc.getSections()) {
for (Paragraph paragraph : (Iterable extends Paragraph>) sec.getParagraphs()) {
for (int i = 0; i < paragraph.getChildObjects().getCount(); i++) {
DocumentObject obj = paragraph.getChildObjects().get(i);
if (obj instanceof ShapeObject) {
ShapeObject shape = (ShapeObject) obj;
Chart chart = shape.getChart();
String fileName = outputFile + count + ".crtx";
chart.saveAsTemplate(fileName);
count++;
}
}
}
}
Document doc = new Document();
doc.loadFromFile(inputFile);
StringBuilder sb = new StringBuilder();
int number =1;
for (Section sec : (Iterable extends Section>) doc.getSections()) {
for (Paragraph paragraph : (Iterable extends Paragraph>) sec.getParagraphs()) {
for (int i = 0; i < paragraph.getChildObjects().getCount(); i++) {
DocumentObject obj = paragraph.getChildObjects().get(i);
if (obj instanceof ShapeObject) {
ShapeObject shape = (ShapeObject) obj;
Chart chart = shape.getChart();
sb.append("\r\n\r\n第" +number + "页:\r\n" + "获取所有X轴数据:");
for(int x = 0; x < chart.getXValues().getCount(); x++){
// 打印所有X轴数据值
ChartValue xVal = chart.getXValues().get(x);
sb.append( xVal.getStringValue() + " ");
}
ChartSeries series = chart.getSeries().get(0);
sb.append("\r\n获取Y轴数据:");
// 打印第一个系列所有的Y轴数据值
for(ChartValue yVal : (Iterable<ChartValue>)series.getYValues()){
sb.append(yVal.getValue() + " ");
}
}
}
}
number ++;
}
Document doc = new Document();
for (ChartDataLabelPosition position : ChartDataLabelPosition.values()) {
Section section = doc.addSection();
section.addParagraph().appendText(position.name());
Paragraph newPara = section.addParagraph();
ShapeObject shape = newPara.appendChart(ChartType.Pie, 500, 300);
Chart chart = shape.getChart();
chart.getSeries().get(0).hasDataLabels(true);
chart.getSeries().get(0).getDataLabels().setShowCategoryName(true);
chart.getSeries().get(0).getDataLabels().setShowValue(true);
chart.getSeries().get(0).getDataLabels().setPosition(position);
ShapeObject shape2 = newPara.appendChart(ChartType.Bubble, 500, 300);
Chart chart2 = shape2.getChart();
chart2.getSeries().get(0).hasDataLabels(true);
chart2.getSeries().get(0).getDataLabels().setShowCategoryName(true);
chart2.getSeries().get(0).getDataLabels().setShowValue(true);
chart2.getSeries().get(0).getDataLabels().setPosition(position);
}
doc.saveToFile(outputFile, FileFormat.Docx);
问题修复:
问题修复:
优化:
问题修复:
问题修复:
问题修复:
Spire.Doc for Java 14.4.9 现已正式发布。该版本支持将图表保存为模板,并新增 XValues 属性支持获取图表 X 轴的数据值,以及 YValues 属性支持获取指定系列 Y 轴的数据值。此外,还支持读取和设置图表数据标签的位置。同时,一些在转换 Word 到 PDF,HTML 到 Word 以及 Markdown 到 Word 时出现的问题也得以成功修复。更多详情如下。
新功能:
Document doc = new Document();
doc.loadFromFile(inputFile);
int count = 1;
for (Section sec : (Iterable extends Section>) doc.getSections()) {
for (Paragraph paragraph : (Iterable extends Paragraph>) sec.getParagraphs()) {
for (int i = 0; i < paragraph.getChildObjects().getCount(); i++) {
DocumentObject obj = paragraph.getChildObjects().get(i);
if (obj instanceof ShapeObject) {
ShapeObject shape = (ShapeObject) obj;
Chart chart = shape.getChart();
String fileName = outputFile + count + ".crtx";
chart.saveAsTemplate(fileName);
count++;
}
}
}
}
Document doc = new Document();
doc.loadFromFile(inputFile);
StringBuilder sb = new StringBuilder();
int number =1;
for (Section sec : (Iterable extends Section>) doc.getSections()) {
for (Paragraph paragraph : (Iterable extends Paragraph>) sec.getParagraphs()) {
for (int i = 0; i < paragraph.getChildObjects().getCount(); i++) {
DocumentObject obj = paragraph.getChildObjects().get(i);
if (obj instanceof ShapeObject) {
ShapeObject shape = (ShapeObject) obj;
Chart chart = shape.getChart();
sb.append("\r\n\r\n第" +number + "页:\r\n" + "获取所有X轴数据:");
for(int x = 0; x < chart.getXValues().getCount(); x++){
// 打印所有X轴数据值
ChartValue xVal = chart.getXValues().get(x);
sb.append( xVal.getStringValue() + " ");
}
ChartSeries series = chart.getSeries().get(0);
sb.append("\r\n获取Y轴数据:");
// 打印第一个系列所有的Y轴数据值
for(ChartValue yVal : (Iterable<ChartValue>)series.getYValues()){
sb.append(yVal.getValue() + " ");
}
}
}
}
number ++;
}
Document doc = new Document();
for (ChartDataLabelPosition position : ChartDataLabelPosition.values()) {
Section section = doc.addSection();
section.addParagraph().appendText(position.name());
Paragraph newPara = section.addParagraph();
ShapeObject shape = newPara.appendChart(ChartType.Pie, 500, 300);
Chart chart = shape.getChart();
chart.getSeries().get(0).hasDataLabels(true);
chart.getSeries().get(0).getDataLabels().setShowCategoryName(true);
chart.getSeries().get(0).getDataLabels().setShowValue(true);
chart.getSeries().get(0).getDataLabels().setPosition(position);
ShapeObject shape2 = newPara.appendChart(ChartType.Bubble, 500, 300);
Chart chart2 = shape2.getChart();
chart2.getSeries().get(0).hasDataLabels(true);
chart2.getSeries().get(0).getDataLabels().setShowCategoryName(true);
chart2.getSeries().get(0).getDataLabels().setShowValue(true);
chart2.getSeries().get(0).getDataLabels().setPosition(position);
}
doc.saveToFile(outputFile, FileFormat.Docx);
问题修复:

PowerPoint 演示文稿广泛用于培训材料、产品演示、在线课程和业务报告。然而,共享原始 PPT 或 PPTX 文件可能存在问题——接收者可能未安装 PowerPoint,动画可能无法正确播放,批量处理时手动导出效率低下。
将 PowerPoint 转换为 MP4 或 WMV 等视频格式可以解决这些挑战,创建通用可播放的内容,同时保留格式和动画。借助 e-iceblue 的 Spire.Presentation,开发人员可以在无需安装 Microsoft PowerPoint 的情况下以编程方式自动执行 PowerPoint 到视频的转换。
本文演示如何使用 Spire.Presentation for .NET 在 C# 中将 PowerPoint 演示文稿转换为 MP4 和 WMV 视频,包括帧率、幻灯片持续时间和过渡效果保留的配置选项。
目录
开发人员经常需要将 PowerPoint 演示文稿转换为视频,作为更大业务流程的一部分。与在 Microsoft PowerPoint 中手动导出文件相比,编程转换提供了更高的灵活性和可扩展性。
常见场景包括:
当需要可重复的工作流、服务器端处理或与现有文档自动化系统集成时,编程转换特别有用。
在将 PowerPoint 演示文稿转换为视频之前,需要准备两个组件:
Spire 处理演示文稿渲染,而 FFmpeg 生成最终的视频输出。两者对于成功转换都是必需的。
从 NuGet 安装库:
Install-Package Spire.Presentation
也可以下载 Spire.Presentation for .NET 包并手动安装。
此包允许 C# 应用程序打开 PowerPoint 演示文稿、访问幻灯片并以编程方式导出它们。
Spire.Presentation 依赖 FFmpeg 将渲染的幻灯片帧组合成可播放的视频文件。如果未安装 FFmpeg 或路径配置不正确,导出过程将失败。
按照以下步骤安装 FFmpeg:
下载 FFmpeg essentials 构建版本
将压缩包解压到本地计算机
定位 bin 文件夹路径
示例:
D:\tools\ffmpeg\bin
稍后配置 SaveToVideoOption 时将使用此路径。
使用以下命令安装 FFmpeg:
sudo yum install epel-release
sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm
sudo yum install ffmpeg ffmpeg-devel
安装完成后,可以运行以下命令定位 FFmpeg 路径:
which ffmpeg
注意:较旧的 FFmpeg 版本可能不完全支持某些幻灯片过渡效果。
配置环境后,只需几行代码即可将 PowerPoint 演示文稿转换为 MP4。
基本工作流程包括:
以下示例将 PPTX 文件转换为 MP4 视频:
using Spire.Presentation;
namespace PowerPointToVideo
{
class Program
{
static void Main(string[] args)
{
string inputFile = "ProductDemo.pptx";
string outputFile = "ProductDemo.mp4";
Presentation presentation = new Presentation();
presentation.LoadFromFile(inputFile);
presentation.SaveToVideoOption = new SaveToVideoOption(
@"D:\tools\ffmpeg\bin"
);
presentation.SaveToVideoOption.Fps = 30;
presentation.SaveToVideoOption.DurationForEachSlide = 2;
presentation.SaveToFile(outputFile, FileFormat.MP4);
presentation.Dispose();
}
}
}
运行代码后:
以下是示例 PowerPoint 演示文稿及其转换后的视频输出。
输入:PowerPoint 演示文稿

输出:转换后的 MP4 视频
点击上面的预览图观看 PowerPoint 幻灯片转换后的视频,视频保留幻灯片过渡效果和动画。
此示例使用了几个关键的 API 方法:
这个基本工作流程足以满足大多数标准 PowerPoint 到视频转换任务。如果需要其他格式或自定义选项,请继续查看下面的高级场景。
如果需要静态共享格式,还可以在 C# 中将 PowerPoint 演示文稿转换为图像(JPG/PNG),以便更轻松地分发和网页显示。
基本示例适用于大多数场景,但某些应用程序可能需要不同的输出格式、自定义播放设置或批量转换工作流。
虽然 MP4 是最广泛使用的视频格式,但一些传统企业系统和基于 Windows 的环境可能仍然需要 WMV 输出。
要将 PowerPoint 文件导出为 WMV,只需更改输出文件扩展名:
using Spire.Presentation;
Presentation presentation = new Presentation();
presentation.LoadFromFile("TrainingSlides.pptx");
presentation.SaveToVideoOption = new SaveToVideoOption(
@"D:\tools\ffmpeg\bin"
);
presentation.SaveToFile("TrainingVideo.wmv", FileFormat.WMV);
presentation.Dispose();
如果演示文稿包含复杂动画或需要特定播放时序,可以调整帧率和幻灯片持续时间设置。
using Spire.Presentation;
Presentation presentation = new Presentation();
presentation.LoadFromFile("MarketingPitch.pptx");
presentation.SaveToVideoOption = new SaveToVideoOption(
@"D:\tools\ffmpeg\bin"
);
// 更高的帧率以获得更流畅的播放
presentation.SaveToVideoOption.Fps = 60;
// 每张幻灯片更长的显示时间
presentation.SaveToVideoOption.DurationForEachSlide = 10;
presentation.SaveToFile("MarketingPitch_HD.mp4", FileFormat.MP4);
presentation.Dispose();
视频设置参考
| 设置 | 默认值 | 最大值 | 用途 |
|---|---|---|---|
| Fps | 30 | 60 | 控制播放流畅度 |
| DurationForEachSlide | 5 秒 | 5 分钟 | 控制幻灯片显示时长 |
较高的值可能会增加处理时间和临时存储使用量。
批量转换对于需要自动处理多个演示文稿的 LMS 平台、企业报告系统和文档自动化工作流非常有用。
using Spire.Presentation;
using System.IO;
string ffmpegPath = @"D:\tools\ffmpeg\bin";
string inputFolder = @"C:\Presentations\";
string outputFolder = @"C:\Videos\";
string[] pptxFiles = Directory.GetFiles(inputFolder, "*.pptx");
foreach (string inputFile in pptxFiles)
{
string fileName = Path.GetFileNameWithoutExtension(inputFile);
string outputFile = Path.Combine(outputFolder, fileName + ".mp4");
Presentation presentation = new Presentation();
presentation.LoadFromFile(inputFile);
presentation.SaveToVideoOption = new SaveToVideoOption(ffmpegPath);
presentation.SaveToVideoOption.Fps = 30;
presentation.SaveToVideoOption.DurationForEachSlide = 3;
presentation.SaveToFile(outputFile, FileFormat.MP4);
presentation.Dispose();
}
这种方法有助于自动化大规模 PowerPoint 到视频转换工作流,无需在 Microsoft PowerPoint 中进行手动导出。
可以在转换前在 C# 中编辑 PowerPoint 演示文稿,以确保生成的视频具有更好的布局和动画效果。
在 PowerPoint 到视频转换期间,Spire.Presentation 保留关键视觉效果,以确保输出视频与原始演示文稿体验紧密匹配。
PowerPoint 幻灯片过渡在视频生成期间被渲染,以保持幻灯片之间的平滑视觉流动。
支持以下过渡效果:
这些过渡效果在帧渲染期间应用,以模拟最终视频中自然的幻灯片进度。
动画在视频生成期间被处理和渲染,以模拟 PowerPoint 播放行为。
进入动画:
退出动画:
动画序列作为单个播放单元处理,以确保在最终视频中一致渲染。
PowerPoint 幻灯片内的嵌入媒体包含在导出的视频中,使其适用于包含多媒体内容的演示文稿。
幻灯片时序和动画时长在转换期间被自动解释,以确保最终视频输出中的准确播放。
转换过程可以在 Windows 和 Linux 环境中运行,使其适用于服务器端自动化和企业工作流。
有关支持功能的更多信息,请参阅 Spire.Presentation for .NET API 文档。
将 PowerPoint 演示文稿转换为视频时,有一些常见问题可能影响输出质量或运行时执行。了解这些问题有助于确保生产环境中的转换过程更加顺畅。
视频导出过程依赖 FFmpeg 编码最终的 MP4 或 WMV 文件。
确保 FFmpeg 路径配置正确,并指向包含 FFmpeg 可执行文件的 bin 目录。
在 Windows 上,通常如下所示:
D:\tools\ffmpeg\bin
如果 FFmpeg 路径不正确或不可访问,视频导出过程将在运行时失败。
PowerPoint 到视频转换涉及将幻灯片渲染为中间帧,然后将它们编码为最终视频文件。
因此,磁盘使用量可能会显著增加,具体取决于:
对于高质量或长时间演示文稿,临时磁盘使用量可能变得很大。建议在处理大型批量转换之前确保有足够的可用磁盘空间。
大多数常见的 PowerPoint 过渡效果在转换期间得到支持。但是,某些复杂或高级过渡效果可能无法与 Microsoft PowerPoint 中完全相同地渲染。
在这种情况下,最终视频仍将保留幻灯片流程,但视觉效果可能与原始演示文稿相比显得简化。
建议在生产工作流中使用之前测试包含高级过渡效果的演示文稿。
PowerPoint 演示文稿依赖系统安装的字体。如果执行转换的环境中缺少所需字体,最终视频中的布局或文本外观可能会发生变化。
为确保一致渲染:
这对于多语言演示文稿或服务器端转换场景尤为重要。
本文演示了如何使用 Spire.Presentation 在 C# 中将 PowerPoint 演示文稿转换为 MP4 和 WMV 视频。通过利用 Spire API,开发人员可以自动生成视频,并具有可定制的帧率、幻灯片持续时间和过渡效果保留功能。
除了视频转换,Spire.Presentation 还可用于幻灯片编辑、媒体提取和演示文稿生成等任务,使其在更广泛的文档自动化工作流中非常有用。
如果想不受限制地评估完整功能,可以申请临时许可证。
可以。Spire.Presentation 独立执行转换,不需要安装 Microsoft PowerPoint。
是的,许多常见的幻灯片过渡效果和进入/退出动画在转换期间被保留。
目前,MP4 和 WMV 格式支持视频导出。
是的。Spire.Presentation 支持服务器环境,并广泛用于自动化文档处理工作流。
视频生成会创建临时图像帧。一个包含 5 张幻灯片、60 FPS 和 5 分钟时长的演示文稿可能需要大约 25GB 的临时存储空间。

目录:
PowerPoint 演示文稿在商业汇报和技术文档中被广泛使用。在一些行业中,尤其是政府和企业系统,文档分发通常要求使用 OFD 格式,而不是标准的 Office 文件格式。由于 PowerPoint 文件可能包含复杂的排版结构以及交互元素,因此并不总是适合用于统一规范的文档分发。
在本教程中,你将学习如何使用 C++ 将 PowerPoint 转换为 OFD 格式。内容将通过简单的代码示例,讲解如何将整个 .ppt/.pptx 文件进行转换、导出单个幻灯片,以及如何对多个文件进行批量转换。
在进行转换之前,先了解 PowerPoint 与 OFD 格式之间的主要差异是很有必要的。两种格式分别面向不同的使用目的和应用场景,因此在某些组织中,文档在分发前需要进行格式转换。理解这些差异有助于更清楚地认识到,为什么在企业或政府的文档工作流程中,经常需要将 PowerPoint 转换为 OFD 格式。
**PowerPoint 文件(PPT/PPTX)**主要用于交互式演示文稿,支持动画、幻灯片切换、嵌入媒体以及可编辑的页面元素。
相比之下,OFD 是一种固定版式的文档格式(类似 PDF),其核心特点是能够在不同系统中保持文档的原始视觉布局不变。因此,OFD 常用于正式文件的分发以及长期数字存档。
与 PowerPoint 不同,OFD 更强调“版式固定”和“内容不可随意改变”,因此在很多场景中,它也被用于类似将 PowerPoint 转换为 PDF 的需求,以确保文档在不同环境中保持一致的显示效果。
PowerPoint 属于 Microsoft Office 生态系统,通常需要兼容的演示软件才能进行查看或编辑。
OFD 则是一种用于电子文档交换的国家标准开放格式,它允许组织在不同软件环境下共享和存储文档,并始终保持一致的排版效果。
在许多企业及政府的业务流程中,文档需要遵循统一的标准格式,以满足相关的监管要求。OFD 支持数字签名、固定版式渲染以及安全的文档交换等功能,因此非常适合用于符合合规要求的文档分发与管理。
理解 PowerPoint 与 OFD 之间的差异,是确保文档在分发过程中保持正确格式的第一步。OFD 的固定版式和标准化特性,使其非常适合用于正式文件分发以及长期归档使用。
在 C++ 中进行转换时,Spire.Presentation for C++ 提供了一种简单且可靠的解决方案。它允许开发者加载、编辑并将 PowerPoint 文件导出为 OFD,同时尽可能保留原有的布局与内容。此外,它还支持其他操作,例如编辑幻灯片、提取图片,以及将 PowerPoint 文件转换为图片等多种格式。
接下来将介绍如何使用 Spire.Presentation for C++ 将 PowerPoint 转换为 OFD 格式。
在 Visual Studio 中使用示例代码之前,请确保已将相关库添加到你的 C++ 项目中。你可以选择以下两种方式之一进行安装:
如果你需要更详细的集成教程,可以参考:Spire.Presentation for C++ 中文教程
示例代码:
#include "Spire.Presentation.o.h";
using namespace Spire::Presentation;
using namespace std;
int main()
{
// 指定输入和输出文件路径
std::wstring inputFile = L"powerpoint-sample.pptx";
std::wstring outputFile = L"output\\PowerPointToOFD.ofd";
// 创建 Presentation 对象
intrusive_ptr<Presentation> presentation = new Presentation();
// 从磁盘加载 PowerPoint 文件
presentation->LoadFromFile(inputFile.c_str());
// 将文件保存为 OFD 格式
presentation->SaveToFile(outputFile.c_str(), FileFormat::OFD);
// 释放资源
presentation->Dispose();
}
结果展示:

注意: 如果你希望去除转换后的 OFD 文件中的评估提示信息,或获得 Spire.Presentation for C++ 的全部功能权限,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。申请授权。
在实际开发场景中,开发者通常需要一次性处理多个 PowerPoint 文件,而不是逐个进行转换。例如,在文档管理系统中,可能需要将一个文件夹中的 PPT 文件批量转换为 OFD 格式,以便进行统一归档或标准化分发。
通过使用 C++ 工具库,可以轻松遍历目录中的文件,逐个加载 PowerPoint 文档,并自动将其导出为 OFD 格式。这种方式在处理大量演示文稿时,可以显著提升效率。
示例代码:
#include "Spire.Presentation.o.h"
#include <filesystem>
using namespace Spire::Presentation;
using namespace std;
namespace fs = std::filesystem;
int main()
{
// 指定输入和输出文件夹路径
wstring inputFolder = L"InputPPT";
wstring outputFolder = L"batchoutputOFD";
for (auto& file : fs::directory_iterator(inputFolder))
{
// 判断文件扩展名是否为 .pptx
if (file.path().extension() == L".pptx")
{
intrusive_ptr<Presentation> presentation = new Presentation();
// 加载 PowerPoint 文件
presentation->LoadFromFile(file.path().wstring().c_str());
// 生成输出 OFD 文件路径
wstring outputFile = outputFolder + L"\\" + file.path().stem().wstring() + L".ofd";
// 转换为 OFD 格式
presentation->SaveToFile(outputFile.c_str(), FileFormat::OFD);
presentation->Dispose();
}
}
return 0;
}
结果展示:

在某些场景中,开发者可能只需要导出部分指定的幻灯片,而不是转换整个演示文稿。例如,在报表系统中,可能只需要将 PowerPoint 中的几页关键内容生成 OFD 文档。
通过使用 Spire.Presentation,可以新建一个演示文稿对象,从原始 PowerPoint 文件中复制所需的幻灯片,然后将这些内容导出为 OFD 格式。
注意:在 Spire.Presentation 中,幻灯片索引从 0 开始,因此 索引 4 表示演示文稿中的第 5 张幻灯片
示例代码:
#include "Spire.Presentation.o.h"
using namespace Spire::Presentation;
using namespace std;
int main()
{
// 指定输入和输出路径
wstring inputFile = L"Input.pptx";
wstring outputFile = L"SingleSlide.ofd";
// 加载源演示文稿
intrusive_ptr<Presentation> presentation = new Presentation();
presentation->LoadFromFile(inputFile.c_str());
// 创建一个新的演示文稿
intrusive_ptr<Presentation> newPresentation = new Presentation();
// 获取指定幻灯片(例如:第5张幻灯片,索引从0开始)
intrusive_ptr<ISlide> slide = presentation->GetSlides()->GetItem(4);
// 将该幻灯片添加到新演示文稿中
newPresentation->GetSlides()->Append(slide);
// 将幻灯片保存为 OFD 格式
newPresentation->SaveToFile(outputFile.c_str(), FileFormat::OFD);
// 释放资源
presentation->Dispose();
newPresentation->Dispose();
return 0;
}
结果展示:

不可以。Microsoft PowerPoint 本身不支持将演示文稿直接导出为 OFD 格式。开发者通常需要借助文档处理库或第三方工具,通过程序方式完成该转换。
虽然 PDF 应用非常广泛,但在一些政府及行业平台中,OFD 是被指定使用的格式,因为它是国家标准的电子文档格式,更适合用于安全存储和长期归档。
不需要。Spire.Presentation for C++ 是一个独立运行的库,不依赖于本地安装的 Microsoft PowerPoint。
可以。通过遍历目录中的多个文件,并对每个文件应用相同的转换逻辑,就可以在 C++ 中轻松实现批量转换功能。
本教程介绍了如何在 C++ 中实现 PowerPoint 到 OFD 的转换。通过简单的代码,开发者可以加载 PPT 或 PPTX 文件,并将其导出为 OFD,同时尽可能保留原有的排版布局。
此外,本文还讲解了多种使用场景,包括转换整个演示文稿、导出单个幻灯片以及批量进行 PPT 到 OFD 的转换。这些方法可以方便地集成到自动化流程或企业系统中,提升文档处理效率。你可以通过下载相关 C++ 开发库来尝试这些示例,并在自己的项目中实现 PowerPoint 到 OFD 的转换功能。