Skip to content

Commit ef03a06

Browse files
committed
add a more readable readme
1 parent 8e170d6 commit ef03a06

File tree

6 files changed

+126
-30
lines changed

6 files changed

+126
-30
lines changed

README.md

Lines changed: 125 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,146 @@
1-
# ExcelAlchemy 开发指南
1+
# ExcelAlchemy 使用指南
22

3-
## 1. 项目介绍
3+
# 📊 ExcelAlchemy
44

5-
* ExcelAlchemy 负责从 Excel 解析用户的输入,转换、生成对应的数据结构,给后端使用。
6-
* ExcelAlchemy 负责将后端给定的数据,转换、生成对应的 Excel,给用户下载。
5+
ExcelAlchemy 是一个用于从 Minio 下载 Excel 文件,解析用户输入并生成对应 Pydantic 类的 Python 库,同时也可以将 Pydantic 数据生成对应的 Excel,便于用户下载。
76

8-
## 2. 核心设计
7+
## 安装
98

10-
### 2.1 ABCValueType
9+
在使用该库前,请先安装以下依赖:
1110

12-
负责实现表头的渲染,用户输入值的解析,反向解析,数据验证。
11+
- Python 3.6+
12+
- Pydantic
13+
- openpyxl
14+
- minio
1315

14-
* comment: 用于生成表头的注释
15-
* serialize: 将用户输入在 Excel 的值,转换为 Python 的值。需要注意的类型如时间。
16-
* deserialize: 将 Python 的值,转换为 Excel 的值。如 datatime 转换成 str 类型。
17-
* _validate: 私有方法,对数据进行验证,OptionId/name 的转换逻辑在这里完成。
16+
使用 pip 安装:
1817

19-
### 2.2 Writer 文件
18+
```
19+
pip install ExcelAlchemy
20+
```
2021

21-
负责将捕获到的错误正确的填写到 Excel 的单元表格(cell)中,核心是计算单元格横纵坐标。
22-
注意以下两点即可
22+
## 使用方法
2323

24-
* pandas 的横纵坐标从 0 开始,而 openpyxl 的横纵坐标从 1 开始。
25-
* 对于合并的单元格,合并之后,无法再写入值,无法再写入格式,因此一定要先写入值和格式,再合并单元格(对于合并的单元格,本质上值在左上角第一个)。
24+
### 从 Pydantic 类生成 Excel 模板
2625

27-
### 2.3 如何捕捉中文错误
26+
```python
27+
from excelalchemy import ExcelAlchemy, FieldMeta, ImporterConfig, Number, String
28+
from pydantic import BaseModel
2829

29-
pydantic 支持自定义 validate 函数, 通过不同的 ValueType 实现不同的 validate 函数,从而捕捉不同的错误。
3030

31+
class Importer(BaseModel):
32+
age: Number = FieldMeta(label='年龄', order=1)
33+
name: String = FieldMeta(label='名称', order=2)
34+
phone: String | None = FieldMeta(label='电话', order=3)
35+
address: String | None = FieldMeta(label='地址', order=4)
3136

32-
### 2.4 FieldMetaInfo
37+
alchemy = ExcelAlchemy(ImporterConfig(Importer))
38+
base64content = alchemy.download_template()
39+
print(base64content)
3340

34-
* 用于描述 Excel 的表头,包括表头的名称,表头的类型,表头的注释,后续很多地方,都会用到这个类。
41+
```
42+
* 上面是一个简单的例子,从 Pydantic 类生成 Excel 模板,Excel 模版中将会有一个 Sheet,Sheet 名称为 `Sheet1`,并且会有四列,分别为 `年龄``名称``电话``地址`,其中 `年龄``名称` 为必填项,`电话``地址` 为可选项。
43+
* 返回一个 base64 编码的 Excel 字符串,可以直接在前端页面中使用 `window.open` 方法打开 Excel 文件,或者在浏览器地址栏中输入 base64content,即可下载 Excel 文件。
44+
* 在下载模版时,您也可以指定一写默认值,例如:
3545

46+
```python
47+
from excelalchemy import ExcelAlchemy, FieldMeta, ImporterConfig, Number, String
48+
from pydantic import BaseModel
3649

37-
## 3、重难点解释
3850

39-
### 3.1 如何解析表头是否有合并
51+
class Importer(BaseModel):
52+
age: Number = FieldMeta(label='年龄', order=1)
53+
name: String = FieldMeta(label='名称', order=2)
54+
phone: String | None = FieldMeta(label='电话', order=3)
55+
address: String | None = FieldMeta(label='地址', order=4)
4056

41-
这是通过观察 pandas 读取 Excel 时的行为,而得出的结论。
4257

43-
对于有合并的表头,pandas 会将合并的单元格的值,赋值给合并的单元格的第一个单元格,而其他的单元格的值为 None。
44-
因此,我们可以通过判断是否为 None 来判断是否有合并。
58+
alchemy = ExcelAlchemy(ImporterConfig(Importer))
59+
sample = [
60+
{'age': 18, 'name': '张三', 'phone': '12345678901', 'address': '北京市'},
61+
{'age': 19, 'name': '李四', 'address': '上海市'},
62+
{'age': 20, 'name': '王五', 'phone': '12345678901'},
63+
]
64+
base64content = alchemy.download_template(sample)
65+
print(base64content)
66+
```
4567

46-
### 3.2 如何记录错误
68+
* 上面的例子中,我们指定了一个 `sample``sample` 是一个列表,列表中的每个元素都是一个字典,字典中的键为 Pydantic 类中的字段名,值为该字段的默认值。
69+
* 最终下载的 Excel 文件中,`Sheet1` 中的第一行为字段名,第二行开始为默认值,如果某个字段没有默认值,则该字段为空,如图所示:
70+
* ![image](./images/001_sample_template.png)
4771

48-
`ExcelCellError``ExcelRowError` 用于记录错误,其中 `ExcelCellError` 记录单元格错误,`ExcelRowError` 记录行错误。
49-
`ExcelAlchemy.cell_errors` 用于记录单元格错误的横纵坐标信息。
50-
`ExcelAlchemy.row_errors` 用于记录单元格错误的横坐标信息。
72+
### 从 Excel 解析 Pydantic 类并创建数据
73+
74+
```python
75+
import asyncio
76+
from typing import Any
77+
78+
from excelalchemy import ExcelAlchemy, FieldMeta, ImporterConfig, Number, String
79+
from minio import Minio
80+
from pydantic import BaseModel
81+
82+
83+
class Importer(BaseModel):
84+
age: Number = FieldMeta(label='年龄', order=1)
85+
name: String = FieldMeta(label='名称', order=2)
86+
phone: String | None = FieldMeta(label='电话', order=3)
87+
address: String | None = FieldMeta(label='地址', order=4)
88+
89+
90+
def data_converter(data: dict[str, Any]) -> dict[str, Any]:
91+
"""自定义数据转换器, 在这里,你可以对 Importer.dict() 的结果进行转换"""
92+
data['age'] = data['age'] + 1
93+
data['name'] = {"phone": data['phone']}
94+
return data
95+
96+
97+
async def create_func(data: dict[str, Any], context: None) -> Any:
98+
"""你定义的创建函数"""
99+
# do something to create data
100+
return True
101+
102+
103+
async def main():
104+
alchemy = ExcelAlchemy(
105+
ImporterConfig(
106+
create_importer_model=Importer,
107+
creator=create_func,
108+
data_converter=data_converter,
109+
minio=Minio(endpoint=''), # 可访问的 minio 地址
110+
bucket_name='excel',
111+
url_expires=3600,
112+
)
113+
)
114+
result = await alchemy.import_data(input_excel_name='test.xlsx', output_excel_name="test.xlsx")
115+
print(result)
116+
117+
118+
asyncio.run(main())
119+
```
120+
121+
* 倒入功能的文件基于 Minio,因此在使用该功能前,你需要先安装 Minio,并且在 Minio 中创建一个 bucket,用于存放 Excel 文件。
122+
* 倒入的 Excel 文件,必须是从 `download_template` 方法生成的 Excel 文件,否则会产生解析错误。
123+
* 上面的示例代码中,我们定义了一个 `data_converter` 函数,该函数用于对 `Importer.dict()` 的结果进行转换,最终返回的结果将会作为 `create_func` 函数的参数。当然,此函数是可选的,如果你不需要对数据进行转换,可以不定义该函数。
124+
* `create_func` 函数用于创建数据,该函数的参数为 `data_converter` 函数的返回值,`context``None`,你可以在该函数中对数据进行创建,例如,你可以将数据存入数据库中。
125+
* `import_data` 方法的参数 `input_excel_name` 为 Excel 文件在 Minio 中的名称,`output_excel_name` 为解析结果 Excel 文件在 Minio 中的名称,该文件包含所有输入的数据,如果某条数据解析失败,则在该条数据的第一列中会有错误信息,并且会讲产生错误的单元格标红。
126+
* 返回 ImportResult 类型的结果,您可以在代码中查看该类的定义,该类包含了解析结果的所有信息,例如,成功导入的数据条数、失败的数据条数、失败的数据等。
127+
128+
一个倒入结果的示例, 如图所示:
129+
* ![image](./images/002_import_result.png)
130+
131+
132+
133+
## 贡献
134+
135+
如果你在使用 ExcelAlchemy 过程中遇到了问题或者有任何建议,欢迎在 [GitHub Issues](https://github.com/username/repo/issues) 中提出。我们也非常欢迎你提交 Pull Request,贡献你的代码。
136+
137+
## 许可证
138+
139+
ExcelAlchemy 使用 MIT 许可证。详细信息请参阅 [LICENSE](https://github.com/username/repo/blob/main/LICENSE)
140+
## 贡献
141+
142+
如果你在使用 ExcelAlchemy 过程中遇到了问题或者有任何建议,欢迎在 [GitHub Issues](https://github.com/SundayWindy/ExcelAlchemy/issues) 中提出。我们也非常欢迎你提交 Pull Request,贡献你的代码。
143+
144+
## 许可证
145+
146+
ExcelAlchemy 使用 MIT 许可证。详细信息请参阅 [LICENSE](https://github.com/SundayWindy/ExcelAlchemy/blob/master/LICENSE)

excelalchemy/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""A Python Library for Reading and Writing Excel Files"""
22

3-
__version__ = '0.1.0a6'
3+
__version__ = '0.1.0b1'
44

55
from excelalchemy.const import CharacterSet
66
from excelalchemy.const import DataRangeOption

files/倒入模版.xlsx

6.97 KB
Binary file not shown.

files/导入结果.xlsx

7.25 KB
Binary file not shown.

images/001_sample_template.png

50.5 KB
Loading

images/002_import_result.png

83.1 KB
Loading

0 commit comments

Comments
 (0)