Skip to main content

easyofd_core/model/
ofd_metadata.rs

1//! OFD 文档元数据。
2//!
3//! 对应 Java: org.ofdrw.core.basicStructure.ofd.docInfo.CT_DocInfo
4
5use chrono::NaiveDateTime;
6
7use crate::model::bookmarks::Bookmarks;
8use crate::model::custom_datas::CustomDatas;
9use crate::model::permissions::Permissions;
10use crate::model::template_page::TemplatePage;
11
12/// OFD 文档元数据(OFD.xml 层级)。
13///
14/// 对应 Java: ofdrw CT_DocInfo。
15// 多个布尔标志反映 GB/T 33190-2016 中同名元素的存在性(ofdrw 对不同场景
16// 会省略这些元素),聚合为一个结构体便于 roundtrip 保真。
17#[allow(clippy::struct_excessive_bools)]
18#[derive(Debug, Clone)]
19pub struct OfdMetadata {
20    /// 文档版本(默认: "1.0")。
21    pub version: String,
22    /// 文档标识符(ofd:DocID)。
23    pub doc_id: Option<String>,
24    /// 文档标题。
25    pub title: Option<String>,
26    /// 文档作者(ofd:Author)。
27    pub author: Option<String>,
28    /// 创建应用程序名称(ofd:Creator)。
29    pub creator: Option<String>,
30    /// 创建应用程序版本(ofd:CreatorVersion)。
31    pub creator_version: Option<String>,
32    /// 创建日期(ofd:CreationDate)。
33    pub creation_date: Option<NaiveDateTime>,
34    /// 创建日期原始文本(ofd:CreationDate),roundtrip 保真用。
35    ///
36    /// 保留 OFD 文件中 `<ofd:CreationDate>` 的原始字符串(如 `"2020-01-25"`),
37    /// writer 优先使用此值原样输出,避免强加日期格式(如追加 `T00:00:00`)。
38    pub creation_date_raw: Option<String>,
39    /// 最后修改日期(ofd:ModDate)。
40    pub mod_date: Option<NaiveDateTime>,
41    /// 最后修改日期原始文本(ofd:ModDate),roundtrip 保真用。
42    ///
43    /// 保留 OFD 文件中 `<ofd:ModDate>` 的原始字符串,writer 优先使用此值原样输出。
44    pub mod_date_raw: Option<String>,
45    /// 最大单元标识符(ofd:MaxUnitID),默认 0。
46    pub max_unit_id: u32,
47    /// 书签集合(ofd:Bookmarks)。
48    pub bookmarks: Option<Bookmarks>,
49    /// 大纲集合(ofd:Outlines,即 GB/T 33190-2016 的书签大纲)。
50    pub outlines: Option<Bookmarks>,
51    /// 自定义数据集合(ofd:CustomDatas)。
52    pub custom_datas: Option<CustomDatas>,
53    /// 文档用途(ofd:DocUsage),如 "Normal"。
54    pub doc_usage: Option<String>,
55    /// 文档关键词(ofd:Keywords)。
56    pub keywords: Option<String>,
57    /// 文档主题(ofd:Subject),对应 ofdrw CT_DocInfo.Subject。
58    pub subject: Option<String>,
59    /// 应用区域(ofd:ApplicationBox),格式 "x y w h"。
60    pub application_box: Option<String>,
61    /// 内容区域(ofd:ContentBox),格式 "x y w h"。
62    pub content_box: Option<String>,
63    /// 裁剪区域(ofd:ClipBox),格式 "x y w h"。
64    pub clip_box: Option<String>,
65    /// 出血区域(ofd:BleedBox),格式 "x y w h"。
66    pub bleed_box: Option<String>,
67    /// 裁切区域(ofd:TrimBox),格式 "x y w h"。
68    pub trim_box: Option<String>,
69    /// 签名容器路径(ofd:Signatures),位于 OFD.xml 的 DocBody 中,如 "/Doc_0/Signs/Signatures.xml"。
70    pub signatures_path: Option<String>,
71    /// 模板页引用(ofd:TemplatePage),位于 Document.xml 的 CommonData 中。
72    pub template_pages: Vec<TemplatePage>,
73    /// 注释容器路径(ofd:Annotations),位于 Document.xml 中,如 "Annots/Annotations.xml"。
74    pub annotations_path: Option<String>,
75    /// 附件容器路径(ofd:Attachments),位于 Document.xml 中,如 "Attachs/Attachments.xml"。
76    pub attachments_path: Option<String>,
77    /// 自定义标签容器路径(ofd:CustomTags),位于 Document.xml 中,如 "Tags/CustomTags.xml"。
78    pub custom_tags_path: Option<String>,
79    /// 原始 Document.xml 是否声明了 ofd:PageArea(ofdrw 未显式设置页面大小时省略该元素)。
80    pub page_area_present: bool,
81    /// 文档目录(ZIP 中的目录前缀,如 "Doc_0")。
82    pub doc_dir: String,
83    /// Document XML 文件名(位于 `doc_dir` 下,通常为 "Document.xml",
84    /// 非标准文件可能是 "Document_0.xml")。
85    pub document_file: String,
86    /// DocumentRes 引用(CommonData 中 `<ofd:DocumentRes>` 的文本,如
87    /// "DocumentRes.xml" 或非标准的 "DocumentRes_0.xml")。
88    pub document_res: Option<String>,
89    /// CommonData 是否声明了 ofd:DocumentRes 元素(ofdrw 样本可能把
90    /// PublicRes 引用错误指向 DocumentRes.xml 而无 DocumentRes 元素)。
91    pub document_res_element_present: bool,
92    /// 源文档是否包含 PublicRes.xml(ofdrw 在无字体资源时不写出该文件,
93    /// 但 Document.xml 中的引用仍保留)。
94    pub public_res_present: bool,
95    /// Document.xml 的 CommonData 是否声明了 ofd:PublicRes 引用。
96    pub public_res_element_present: bool,
97    /// 文档权限(ofd:Permissions),如存在。
98    pub permissions: Option<Permissions>,
99}
100
101impl Default for OfdMetadata {
102    fn default() -> Self {
103        Self {
104            version: "1.0".to_string(),
105            doc_id: None,
106            title: None,
107            author: None,
108            creator: None,
109            creator_version: None,
110            creation_date: None,
111            creation_date_raw: None,
112            mod_date: None,
113            mod_date_raw: None,
114            max_unit_id: 0,
115            bookmarks: None,
116            outlines: None,
117            custom_datas: None,
118            doc_usage: None,
119            keywords: None,
120            subject: None,
121            application_box: None,
122            content_box: None,
123            clip_box: None,
124            bleed_box: None,
125            trim_box: None,
126            signatures_path: None,
127            template_pages: Vec::new(),
128            annotations_path: None,
129            attachments_path: None,
130            custom_tags_path: None,
131            page_area_present: true,
132            doc_dir: "Doc_0".to_string(),
133            document_file: "Document.xml".to_string(),
134            document_res: None,
135            document_res_element_present: true,
136            public_res_present: true,
137            public_res_element_present: true,
138            permissions: None,
139        }
140    }
141}