12个版本
0.2.8 | 2023年11月7日 |
---|---|
0.2.7 | 2023年8月16日 |
0.2.6 | 2022年5月17日 |
0.2.5 | 2022年4月6日 |
0.1.2 | 2020年12月10日 |
#1606 在 解析器实现
66 每月下载量
用于 xlsx2csv
360KB
3K SLoC
OOXML - Rust中的Office OpenXML解析器
该项目最初是一个以Office Open XML为目标的私人项目,对Office Open XML的了解有限,使用时请谨慎!
Office Open XML,是由Microsoft开发的一种基于XML并以ZIP格式压缩的电子文件规范,支持文件、表格、备忘录、幻灯片等文件格式。
Office Open XML(非正式称为OOXML或Microsoft Open XML (MOX))是由Microsoft开发的一种压缩的XML文件格式,用于表示电子表格、图表、演示文稿和文字处理文档。该格式最初由Ecma(作为ECMA-376)以及后来的ISO和IEC(作为ISO/IEC 29500)标准化。
OOXML,正如其命名,试图成为一个纯Rust实现的Office Open XML解析器 - 在Rust中高效地读取和写入ooxml组件。但截至目前,仅支持xlsx解析。
简单来说;
examples/xlsx.rs
中的示例代码
use ooxml::document::SpreadsheetDocument;
fn main() {
let xlsx =
SpreadsheetDocument::open("examples/simple-spreadsheet/data-image-demo.xlsx").unwrap();
let workbook = xlsx.get_workbook();
//println!("{:?}", xlsx);
let _sheet_names = workbook.worksheet_names();
for (sheet_idx, sheet) in workbook.worksheets().iter().enumerate() {
println!("worksheet {}", sheet_idx);
println!("worksheet dimension: {:?}", sheet.dimenstion());
println!("---------DATA---------");
for rows in sheet.rows() {
// get cell values
let cols: Vec<_> = rows
.into_iter()
.map(|cell| cell.value().unwrap_or_default())
.collect();
println!("{}", itertools::join(&cols, ","));
}
}
}
运行 cargo run --example xlsx
worksheet 0
worksheet dimension: Some((1, 1))
---------DATA---------
----------------------
worksheet 1
worksheet dimension: Some((4, 4))
---------DATA---------
name,age,birthday,last edited
bob,17,1983/12/12,2020/10/11 19:59
tom,18,1982/12/12,2020/10/11 19:59
cury,20,1980-12-12,2020-10-11 19:59
----------------------
库设计
主要思想来自DotNet OpenXML SDK。
- 实现任何OOXML格式(docx/xlsx/pptx...)的OpenXML包约定,包括
- 包的读取和写入
- 内容类型解析
- 关系通用类型
- 实现共享OpenXML部分
- 内容类型
- 核心属性
- 应用程序属性
- 文件属性
- 嵌入式包
- 图片
- 主题
- 样式
- 实现Excel/SpreadsheetML规范
- 计算链
- 图表工作表
- 注释
- 连接
- 自定义属性
- 客户XML映射
- 对话框工作表
- 绘图
- 外部工作簿引用
- 元数据
- 数据透视表
- 数据透视表缓存定义
- 数据透视表缓存记录
- 查询表
- 共享字符串表
- 共享工作簿修订记录
- 共享工作簿用户数据
- 单个单元格表定义
- 表定义
- 易变依赖
- 工作簿
- 工作表
- 其他 OpenXML 格式(docx, pptx)
代码库树结构如下。
src
├── document
│ ├── mod.rs
│ ├── presentation
│ │ └── mod.rs
│ ├── spreadsheet
│ │ ├── cell.rs
│ │ ├── chart.rs
│ │ ├── document_type.rs
│ │ ├── drawing.rs
│ │ ├── media.rs
│ │ ├── mod.rs
│ │ ├── shared_string.rs
│ │ ├── style.rs
│ │ ├── workbook.rs
│ │ └── worksheet.rs
│ └── wordprocessing
│ └── mod.rs
├── drawing
│ └── mod.rs
├── error.rs
├── lib.rs
├── math
│ └── mod.rs
└── packaging
├── app_property.rs
├── content_type.rs
├── custom_property.rs
├── element.rs
├── mod.rs
├── namespace.rs
├── package.rs
├── part
│ ├── container.rs
│ ├── mod.rs
│ └── pair.rs
├── property.rs
├── relationship
│ ├── mod.rs
│ └── reference.rs
├── variant.rs
├── xml.rs
└── zip.rs
对 Crate 的定义
主要设计原则是 一切类型化
。
包
:一个包
是一个压缩的 OpenXML 文档,可以是文字处理/电子表格/演示文稿文档。元素
:一个元素
是一个 OpenXML 元素,表示每个 xml 中的数据细节。部分
:一个部分
是一组元素
或纯数据,这些数据应该序列化到包中的一个文件中。组件
:一个组件
是行为与内部 OpenXML 东西的桥梁,包括包
、元素
和部分
。属性
:一个属性
表示元素的属性。文档
:一个文档
是真实文档的入口组件
,例如电子表格文档
等。关系
:一个关系
是元素与其他资源从部分
的链接关系。
数据流或创建文档将如下所示。
Document -> Package : open/parse from
Package -> Parts : parse to parts
Parts -> Components: build components tree
Components -> Elements: elements one-to-one map
Elements -> Components: elements changes
Components -> Parts: components write back
Parts -> Package: serialize to package
Package <- Document: flush, save or others
Document -> Components: create new document. add or remove components
Components <-> Elements: operations
Components -> Parts: component add/remove
Parts -> Package: serialize to package
Document -> Package: flush, save or others
初始化实现功能
- OPC 解析,包括读取和写入
- 共享组件
- 内容类型
- 核心属性
- 应用程序属性
- 文件属性(不在计划中)
- 嵌入式包(不在计划中)
- 图片
- 主题
- 样式
- 电子表格 ML
- 工作簿
- 工作表
待办事项
- 为 OpenXML 元素创建标记特征,使其更通用。
- 在 xml 部分中使用
minidom
,跟踪更改并将其写回 DOM 树。 - 延迟解析一些 OpenXML 部分以加快首次启动速度。
- 实现组件生成的辅助宏。
Tokei - 2020-11-04-11:35:51
===============================================================================
Language Files Lines Code Comments Blanks
===============================================================================
Markdown 1 272 0 230 42
Plain Text 1 1 0 1 0
TOML 1 23 21 1 1
XML 52 164 164 0 0
-------------------------------------------------------------------------------
Rust 34 2721 2189 194 338
|- Markdown 14 106 7 90 9
(Total) 2827 2196 284 347
===============================================================================
Total 89 3287 2381 516 390
===============================================================================
概念
Office Open XML 或 OpenXML
Office Open XML(非正式称为OOXML或Microsoft Open XML (MOX))是由Microsoft开发的一种压缩的XML文件格式,用于表示电子表格、图表、演示文稿和文字处理文档。该格式最初由Ecma(作为ECMA-376)以及后来的ISO和IEC(作为ISO/IEC 29500)标准化。
Microsoft Office 2010 为 ECMA-376 提供读取支持,为 ISO/IEC 29500 过渡版提供读取/写入支持,并为 ISO/IEC 29500 严格版提供读取支持。Microsoft Office 2013 和 Microsoft Office 2016 还额外支持 ISO/IEC 29500 严格版的读取和写入。虽然从 Office 2013 开始对 ISO/IEC 29500 严格版提供完全的读取/写入支持,但由于持续的互操作性担忧,Microsoft 尚未将严格非过渡版或原始标准作为默认文件格式实施。
OpenXML 包约定
Open Packaging Conventions (OPC) 是一种容器文件技术,最初由 Microsoft 创建,用于存储一个组合的 XML 和非 XML 文件,这些文件共同形成一个单一实体,例如 Open XML Paper Specification (OpenXPS) 文档。基于 OPC 的文件格式结合了在文档中保留独立文件实体完整性的优点,与正常使用 XML 相比,文件大小小得多。
标准 ECMA-376
标准 ECMA-376 - Office Open XML 文件格式标准。
第 1 版(2006 年 12 月),第 2 版(2008 年 12 月),第 3 版(2011 年 6 月),第 4 版(2012 年 12 月)和第 5 版(第 3 部分,2015 年 12 月;第 1 部和第 4 部分,2016 年 12 月)。
版本下载
目前是第 4 版,技术上与 ISO/IEC 29500 对齐。第 5 版正在进展中。有一个 Office Open XML 概述 介绍 pdf 文件。
电子表格 ML
SpreadsheetML 或 .xlsx 文件是一个包含多个 "部分"(通常是 UTF-8 或 UTF-16 编码)或 XML 文件的压缩文件(一个包)。该包还可以包含其他媒体文件,如图像。结构根据 ECMA-376 标准 OOXML 的第 2 部分的开放打包约定组织。
您可以通过简单地解压缩 .xlsx 文件来查看文件结构和组成 SpreadsheetML 文件的文件。
├── [Content_Types].xml
├── docProps
│ ├── app.xml
│ ├── core.xml
│ └── custom.xml
├── _rels
└── xl
├── charts
│ ├── chart1.xml
│ ├── colors1.xml
│ ├── _rels
│ │ └── chart1.xml.rels
│ └── style1.xml
├── drawings
│ ├── drawing1.xml
│ ├── drawing2.xml
│ └── _rels
│ ├── drawing1.xml.rels
│ └── drawing2.xml.rels
├── media
│ └── image1.png
├── _rels
│ └── workbook.xml.rels
├── sharedStrings.xml
├── styles.xml
├── theme
│ └── theme1.xml
├── workbook.xml
└── worksheets
├── _rels
│ ├── sheet1.xml.rels
│ └── sheet2.xml.rels
├── sheet1.xml
└── sheet2.xml
部分的数量和类型将根据工作表中的内容而变化,但总会包含一个 [Content_Types].xml
、一个或多个关系部分、一个工作簿部分和至少一个工作表。工作表部分包含电子表格的核心数据,详情请参考 xslx 内容概述。
资源
- 维基百科 Office OpenXML:[英文](https://en.wikipedia.org/wiki/Office_Open_XML),[中文](https://zh.wikipedia.org/wiki/Office_Open_XML)。
- Microsoft [DotNet OpenXML SDK](https://docs.microsoft.com/en-us/dotnet/api/overview/openxml/?view=openxml-2.8.1) 文档和 [源代码](https://github.com/OfficeDev/Open-XML-SDK/)。
- 维基百科 [OpenXML 打包约定](https://en.wikipedia.org/wiki/Open_Packaging_Conventions) - [开放打包约定](https://zh.wikipedia.org/wiki/%E5%BC%80%E6%94%BE%E6%89%93%E5%8C%85%E7%BA%A6%E5%AE%9A)。
- 什么是 OOXML:[http://officeopenxml.com/](http://officeopenxml.com/)
- SpreadsheetML:[http://officeopenxml.com/anatomyofOOXML-xlsx.php](http://officeopenxml.com/anatomyofOOXML-xlsx.php)
- Rust [quick-xml](https://crates.org.cn/crates/quick-xml) [文档](https://docs.rs/quick-xml/0.20.0)。
- Rust [docx-rs](https://crates.org.cn/crates/docx-rs) [文档](https://docs.rs/docx-rs) 和 [GitHub 上的源代码](https://github.com/bokuweb/docx-rs)。
- Go Excel 文件解析器 [excelize](https://github.com/360EntSecGroup-Skylar/excelize)。
- 标准 ECMA-376.
依赖项
~14MB
~272K SLoC