OFD 元数据、资源与自定义数据
本节介绍 OFDDoc 上的文档元数据、嵌入式资源与自定义键值数据的读取与设置。元数据与自定义数据用于文档属性与业务扩展;资源(字体、图像、多媒体等)供 图元与图层、注释与动作 等章节引用。取得 OFDDoc 的方式请参阅 OFD 文档与页面。
任务场景
- 读取或修改文档元数据字段(标题、作者等)及关键词列表。
- 将外部图像、字体、通用资源嵌入文档,取得
resource_id供图元或动作引用。 - 提取或导出文档内的多媒体等资源文件。
- 维护 Custom Data 扩展键值对(
AddCustomData、GetCustomDataName/GetCustomDataValue)。
API 概览
| 功能 | C++ API(foxit::ofd::OFDDoc) | 核心参数 / 描述 |
|---|---|---|
| 元数据读写 | GetMetadata、SetMetadata | 参数为 WString 键值对;按字符串键读写 OFD 文档信息(如 Title、Author、Creator、Subject 等) |
| 关键词 | GetKeywordCount、InsertKeyword、RemoveKeyword | InsertKeyword(keyword, index),index = -1 追加到末尾 |
| 自定义数据 | GetCustomDataCount、GetCustomDataName、GetCustomDataValue | 按索引访问键名与值 |
| 添加自定义数据 | AddCustomData、InsertCustomData、RemoveCustomData | 键值对为 String;AddCustomData 追加条目 |
| 通用资源 | AddResourceFromFile | 指定文件路径与 format 字符串,返回 uint32 资源 ID |
| 图像资源 | AddImageResourceFromFile、AddImageResourceFromBuffer | 返回资源 ID,供 OFDImageObject::SetImage 等使用 |
| 字体资源 | AddFontResourceFromName、EmbedFont | 按字体族/名称添加资源,或内嵌已有字体 |
| 资源类型查询 | GetResourceTypeByID | 返回 ResourceType(ColorSpace、Font、Multimedia 等) |
| 多媒体资源 | GetMultiMediaFileByID、ExportMultiMediaByID、GetMultiMediaBufferByID 等 | 按资源 ID 读取或导出音视频 |
读取与设置元数据
元数据通过 GetMetadata / SetMetadata 按关键字读写。C++ 侧建议使用 WString 重载,以正确支持中文标题、作者等字段。关键词列表使用 InsertKeyword / RemoveKeyword 维护。
c++
#include "ofd/fs_ofdpackage.h"
#include "ofd/fs_ofddoc.h"
using namespace foxit;
using namespace foxit::ofd;
void ConfigureMetadata(OFDDoc& doc) {
if (doc.IsEmpty()) {
return;
}
// 使用 WString 读写元数据(支持中文)
doc.SetMetadata(L"Title", L"示例文档");
doc.SetMetadata(L"Author", L"Foxit");
WString title = doc.GetMetadata(L"Title");
WString author = doc.GetMetadata(L"Author");
// 关键词:index = -1 表示追加到末尾
doc.InsertKeyword(L"OFD", -1);
doc.InsertKeyword(L"SDK", 0);
int keyword_count = doc.GetKeywordCount();
if (keyword_count > 0) {
doc.RemoveKeyword(keyword_count - 1);
}
}
1
java
import com.foxit.sdk.ofd.OFDDoc;
public class OFDMetadataExample {
public static void configureMetadata(OFDDoc doc) throws Exception {
if (doc.isEmpty()) {
return;
}
doc.setMetadata("Title", "示例文档");
doc.setMetadata("Author", "Foxit");
String title = doc.getMetadata("Title");
String author = doc.getMetadata("Author");
doc.insertKeyword("OFD", -1);
doc.insertKeyword("SDK", 0);
int keywordCount = doc.getKeywordCount();
if (keywordCount > 0) {
doc.removeKeyword(keywordCount - 1);
}
}
}
1
修改元数据后须调用 OFDPackage::Save 或 SaveAs 写回文件。
管理自定义数据
当标准元数据无法满足业务需求时,可使用 Custom Data 维护私有键值对(如业务 ID、审批状态)。通过 AddCustomData 追加条目,按索引读取 GetCustomDataName / GetCustomDataValue;InsertCustomData 可在指定位置插入,RemoveCustomData 删除条目。
c++
#include "ofd/fs_ofddoc.h"
using namespace foxit;
using namespace foxit::ofd;
void ManageCustomData(OFDDoc& doc) {
if (doc.IsEmpty()) {
return;
}
doc.AddCustomData("BusinessId", "INV-2024-001");
doc.AddCustomData("ApprovalStatus", "Approved");
int count = doc.GetCustomDataCount();
for (int i = 0; i < count; ++i) {
WString name = doc.GetCustomDataName(i);
WString value = doc.GetCustomDataValue(i);
}
// 在索引 0 处插入新条目
doc.InsertCustomData("Department", "Finance", 0);
doc.RemoveCustomData(doc.GetCustomDataCount() - 1);
}
1
java
import com.foxit.sdk.ofd.OFDDoc;
public class OFDCustomDataExample {
public static void manageCustomData(OFDDoc doc) throws Exception {
if (doc.isEmpty()) {
return;
}
doc.addCustomData("BusinessId", "INV-2024-001");
doc.addCustomData("ApprovalStatus", "Approved");
int count = doc.getCustomDataCount();
for (int i = 0; i < count; i++) {
String name = doc.getCustomDataName(i);
String value = doc.getCustomDataValue(i);
}
doc.insertCustomData("Department", "Finance", 0);
doc.removeCustomData(doc.getCustomDataCount() - 1);
}
}
1
嵌入与提取资源
资源 ID(uint32)是文档内资源的唯一标识,可用于 OFDImageObject::SetImage、SoundAction::SetResourceID 等接口。添加资源后建议通过 GetResourceTypeByID 确认类型;无效 ID 通常导致后续操作失败。
添加图像与字体资源
c++
#include "ofd/fs_ofddoc.h"
using namespace foxit;
using namespace foxit::ofd;
bool AddImageAndFontResource(OFDDoc& doc, const wchar_t* image_path) {
if (doc.IsEmpty()) {
return false;
}
// 从文件添加图像资源,返回资源 ID
uint32 image_res_id = doc.AddImageResourceFromFile(WString(image_path));
if (image_res_id == 0) {
return false;
}
ResourceType image_type = doc.GetResourceTypeByID(image_res_id);
// 图像资源可能归类为 CompositeGraphicUnit 等,绑定图元前建议校验类型
(void)image_type;
// 添加字体资源
uint32 font_res_id = doc.AddFontResourceFromName("SimSun", "SimSun");
doc.EmbedFont("SimSun");
return font_res_id != 0;
}
1
java
import com.foxit.sdk.ofd.OFDDoc;
public class OFDResourceExample {
public static boolean addImageAndFontResource(OFDDoc doc, String imagePath)
throws Exception {
if (doc.isEmpty()) {
return false;
}
int imageResId = doc.addImageResourceFromFile(imagePath);
if (imageResId == 0) {
return false;
}
int imageType = doc.getResourceTypeByID(imageResId);
int fontResId = doc.addFontResourceFromName("SimSun", "SimSun");
doc.embedFont("SimSun");
return fontResId != 0;
}
}
1
将返回的 image_res_id 用于图元示例请参阅 图元与图层 中「创建与编辑图元」一节。
导出多媒体资源
c++
#include "ofd/fs_ofddoc.h"
using namespace foxit;
using namespace foxit::ofd;
void ExportDocumentResources(OFDDoc& doc, uint32 media_res_id,
const char* output_media) {
if (doc.IsEmpty()) {
return;
}
// 导出多媒体资源到文件
doc.ExportMultiMediaByID(media_res_id, output_media);
WString media_format = doc.GetMultiMediaFormatByID(media_res_id);
}
1
java
import com.foxit.sdk.ofd.OFDDoc;
public class OFDResourceExportExample {
public static void exportDocumentResources(OFDDoc doc, int mediaResId,
String outputMedia) throws Exception {
if (doc.isEmpty()) {
return;
}
doc.exportMultiMediaByID(mediaResId, outputMedia);
String mediaFormat = doc.getMultiMediaFormatByID(mediaResId);
}
}
1
注意事项
- 字符编码:C++ 元数据读写(
GetMetadata/SetMetadata)及中文文件路径建议使用WString重载,避免乱码;自定义数据键值使用String。 - 资源 ID:
AddImageResourceFromFile等返回的uint32ID 为文档内唯一标识;ID 为0通常表示添加失败,绑定图元前应校验。 - 资源 vs 自定义数据:
- Resource:渲染依赖的底层数据(字体、图像流、多媒体等),通过资源 ID 引用。
- Custom Data:简单键值对,非文件流。
- 资源读取方式:优先使用
ExportMultiMediaByID导出到文件;需要内存访问时可调用GetMultiMediaFileByID、GetMultiMediaBufferByID等,须在OFDDoc有效期间使用。 - 包体积与优化:大量嵌入资源会增加文件体积,可结合 OFD 优化 与
OFDPackage::EnableOptimizeResource。 - 持久化:所有修改均为内存操作,须通过
OFDPackage::Save/SaveAs写回,请参阅 OFD 文件包。