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}