
OFD (Open Fixed-layout Document) 是电子公文出版版式内容的国家标准,在国内广泛应用于电子发票、政府采购和官方文档存档等。对于 C++ 开发者而言,快速转换 PDF 为 OFD 文件是一项常见的开发需求。
本教程将演示如何使用 Spire.PDF for C++ 库来自动化处理这个任务,主要从三个角度进行介绍,包括:转换单个 PDF 文档为 OFD、提取 PDF 页面转换以及批量转换多个文件。通过这些示例,你可以用 C++ 代码轻松在应用程序中集成 PDF 转 OFD 的功能。
在 C++ 中将单个 PDF 转换为 OFD
将整个 PDF 文件转换为 OFD 是最常见,也是最基础的操作。在 Spire.PDF for C++ 的帮助下,该任务仅需三个核心步骤就能轻松完成:初始化文档、加载 PDF 源文件、导出为 OFD。下面为具体的步骤介绍:
核心步骤:
- 创建 PdfDocument 实例。
- 使用 PdfDocument->LoadFromFile() 方法加载 PDF。
- 使用 PdfDocument->SaveToFile(filename, FileFormat::OFD) 方法将 PDF 保存为 OFD 格式。
代码示例:
#include "Spire.Pdf.o.h"
using namespace Spire::Pdf;
int main()
{
// 创建 PdfDocument 实例
PdfDocument* pdf = new PdfDocument();
// 加载 PDF 源文件
pdf->LoadFromFile(L"/input/示例文档.pdf");
// 将 PDF 保存为 OFD 文档
pdf->SaveToFile(L"/output/转OFD.ofd", FileFormat::OFD);
// 释放资源
pdf->Close();
delete pdf;
return 0;
}
下面是 PDF 源文档与转换后的 OFD 文档对比图:

除了 OFD 转换,Spire.PDF 还支持将 PDF 转换为 Word 或 Excel,帮助你在不同办公需求间快速切换。
通过 C++ 转换特定 PDF 页面为 OFD
在实际应用时,你可能只需要转换 PDF 的一部分,例如只提取发票页或报告的特定章节。这不仅能减小文件体积,还能确保输出的 OFD 仅包含业务相关数据,无需对结果文档再进行编辑。
核心步骤:
- 初始化两个 PdfDocument 实例,并使用 PdfDocument->LoadFromFile() 方法加载 PDF 源文档。
- 遍历指定的 PDF 页面。
- 在新文档中创建页面,并使用 CreateTemplate()->Draw() 方法将源页面内容绘制到新页面上。
- 使用 PdfDocument->SaveToFile(filename, FileFormat::OFD) 方法将新的 PDF 文档保存为 OFD。
代码示例(提取第 2 至第 3 页):
#include "Spire.Pdf.o.h"
#include <iostream>
using namespace Spire::Pdf;
int main()
{
// 创建 PdfDocument 实例并加载 PDF
intrusive_ptr<PdfDocument> oldPdf = new PdfDocument();
oldPdf->LoadFromFile(L"/input/示例文档.pdf");
// 创建新的 PdfDocument 对象用于存放提取的页面
intrusive_ptr<PdfDocument> newPdf = new PdfDocument();
// 获取源文件总页数
int pageCount = oldPdf->GetPages()->GetCount();
std::cout << "总页数: " << pageCount << std::endl;
// 提取第 2 页到第 3 页
if (pageCount >= 3)
{
for (int i = 1; i <= 2; i++)
{
// 在目标文档中创建相同尺寸的新页面
intrusive_ptr<PdfMargins> margins = new PdfMargins(0);
intrusive_ptr<PdfPageBase> newPage = newPdf->GetPages()->Add(oldPdf->GetPages()->GetItem(i)->GetSize(), margins);
// 基于源页面创建模板,并将其绘制到新页面上
oldPdf->GetPages()->GetItem(i)->CreateTemplate()->Draw(newPage, new PointF(0, 0));
}
// 将提取后的结果保存为 OFD
newPdf->SaveToFile(L"E:/Administrator/Python1/output/页面转OFD.ofd", FileFormat::OFD);
std::cout << "指定范围页面已成功转换并保存为 OFD。" << std::endl;
}
// 关闭文档
newPdf->Close();
oldPdf->Close();
return 0;
}

推荐阅读:在 C++ 中将图像转换为 OFD(PNG、JPG、BMP)
批量转换多个 PDF 文件为 OFD
在处理大规模历史档案或云存储同步时,手动逐个转换 PDF 文件效率低下。对于多文件的业务流,例如迁移历史存档或同步云端目录等来说,实现多个 PDF 文档的批量自动化转换是一项核心需求。
通过利用 Spire.PDF 库,我们可以构建一套实用的解决方案,自动检测并转换目标文件夹下的所有 PDF 文件,从而节省人力成本。
核心步骤:
- 定义输入和输出目录路径。
- 创建 PdfDocument 类的对象。
- 遍历文件夹中的所有 PDF 文件。
- 通过 PdfDocument->SaveToFile(filename, FileFormat::OFD) 方法,将每一个 PDF 文件转换为 OFD。
代码示例:
#include "Spire.Pdf.o.h"
#include <iostream>
#include <filesystem>
#include <string>
namespace fs = std::filesystem;
using namespace Spire::Pdf;
int main()
{
// 定义输入和输出目录
std::string inputDir = "/input/pdf/";
std::string outputDir = "/output/pdftoofd/";
// 创建 PdfDocument 实例
intrusive_ptr<PdfDocument> pdf = new PdfDocument();
// 遍历输入目录
for (const auto& entry : fs::directory_iterator(inputDir))
{
// 仅处理 .pdf 文件
if (entry.path().extension() == ".pdf")
{
// 获取当前文件路径
std::wstring inputPath = entry.path().wstring();
// 构造输出文件名
std::wstring outputFileName = entry.path().stem().wstring() + L".ofd";
std::wstring outputPath = fs::path(outputDir).wstring() + outputFileName;
// 加载并转换
pdf->LoadFromFile(inputPath.c_str());
pdf->SaveToFile(outputPath.c_str(), FileFormat::OFD);
std::wcout << L"转换完成: " << outputFileName << std::endl;
}
}
pdf->Close();
std::cout << "批量转换任务已全部完成。" << std::endl;
return 0;
}

在掌握了批量转换技术后,你还可以通过学习如何在 C++ 中将多个 PDF 文件合并为一个 PDF,来进一步优化文档处理流程。
常见问题解答
Q: OFD 格式是否能完美还原 PDF 的所有元素?
A: 是的,通过 Spire.PDF 进行的转换能够很好地保留文本、矢量图形和图像。其内部绘图逻辑能做到将 PDF 的布局和视觉完整性准确映射到 OFD 标准中。
Q: 转换过程如何处理 PDF 中的高分辨率图片?
A: 转换引擎会保留原始 PDF 图像的 DPI 和压缩设置。即使是批量处理,输出的 OFD 文件也能在保持高质量渲染的同时避免文件体积异常变大。
Q: PDF 表单或交互式元素能否转换?
A: OFD 主要是一种用于查看和打印的固定布局格式。在转换过程中,交互式表单字段一般会被扁平化为可视化图层,以确保数据在 OFD 文档中清晰可见,其交互性在 OFD 中将不再被激活。
结语
Spire.PDF for C++ 为处理 OFD 转换提供了灵活且强大的 API。无论是简单的格式转换,还是复杂的页面提取与批量自动化流,该库都能确保稳定且完整的输出。
如果你对 Spire.PDF 库感兴趣,欢迎该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。申请 30 天免费临时授权,在无限制的环境下深度体验该库的所有功能!







