ChatCausalGPT commited on
Commit
6841f24
·
1 Parent(s): 1f26669

refactor: simplify project structure

Browse files
Files changed (3) hide show
  1. README.md +7 -73
  2. generate_quality_inspection_reports.py +0 -133
  3. main.py +113 -0
README.md CHANGED
@@ -1,30 +1,15 @@
1
- # Quality Inspection Report Generator
2
 
3
  一个用于从 Excel 数据生成质量检验报告的 Python 工具。
4
 
5
- ## 功能特点
6
-
7
- - 从源数据 Excel 文件自动生成质量检验报告
8
- - 支持多个客户的批量处理
9
- - 保持模板格式和样式
10
- - 自动计算日期和有效期
11
- - 完整的化学元素和尺寸数据处理
12
-
13
  ## 系统要求
14
 
15
  - Python 3.6+
16
  - pandas
17
  - openpyxl
18
 
19
- ## 安装
20
-
21
- 1. 克隆仓库:
22
- ```bash
23
- git clone https://github.com/1587causalai/quality-inspection-report-generator.git
24
- cd quality-inspection-report-generator
25
- ```
26
 
27
- 2. 安装依赖:
28
  ```bash
29
  pip install -r requirements.txt
30
  ```
@@ -32,67 +17,16 @@ pip install -r requirements.txt
32
  ## 使用方法
33
 
34
  1. 准备输入文件:
35
- - 源数据文件(参考 `examples/example_source_data.xls`):
36
- * HEADER 工作表:包含基本信息
37
- * Dimension 工作表:包含尺寸数据
38
- * Sand 工作表:包含化学元素测试数据
39
- - 模板文件(参考 `examples/example_template.xlsx`):
40
- * 包含预设的报告格式
41
 
42
  2. 运行脚本:
43
  ```bash
44
- python generate_quality_inspection_reports.py
45
  ```
46
 
47
- 3. 检查输出:
48
- - 生成的报告将保存为 `2_updated.xlsx`
49
- - 每个客户的数据将保存在单独的工作表中
50
-
51
- ## 示例文件
52
-
53
- 在 `examples` 目录中提供了示例文件:
54
-
55
- 1. `example_source_data.xls`:源数据文件示例
56
- - 展示了正确的数据格式和结构
57
- - 包含了所有必需的工作表和字段
58
-
59
- 2. `example_template.xlsx`:模板文件示例
60
- - 展示了标准的报告格式
61
- - 包含了所有必需的字段和公式
62
-
63
- 您可以参考这些示例文件来准备您自己的输入文件。
64
-
65
- ## 数据格式要求
66
-
67
- ### 输入文件结构
68
-
69
- 1. 源数据文件需要包含:
70
- - HEADER:基本信息(数量、批准人等)
71
- - Dimension:尺寸数据和检验日期
72
- - Sand:化学元素测试数据
73
-
74
- 2. 模板文件需要包含:
75
- - WACKER:报告模板格式
76
-
77
- ### 输出报告格式
78
-
79
- - 基本信息(B3-D5):数量、批号、日期等
80
- - 化学元素数据(D9-D19):11种元素的测试结果
81
- - 尺寸数据(D20-D28):外径、高度、壁厚等
82
- - 批准信息(D29):批准人姓名
83
-
84
- ## 文档
85
-
86
- 详细的代码文档请参考 `quality_inspection_documentation.py`。
87
 
88
  ## 许可证
89
 
90
- MIT License
91
-
92
- ## 作者
93
-
94
- [Your Name]
95
-
96
- ## 贡献
97
-
98
- 欢迎提交 Issue 和 Pull Request!
 
1
+ # 质量检验报告生成工具
2
 
3
  一个用于从 Excel 数据生成质量检验报告的 Python 工具。
4
 
 
 
 
 
 
 
 
 
5
  ## 系统要求
6
 
7
  - Python 3.6+
8
  - pandas
9
  - openpyxl
10
 
11
+ ## 安装依赖
 
 
 
 
 
 
12
 
 
13
  ```bash
14
  pip install -r requirements.txt
15
  ```
 
17
  ## 使用方法
18
 
19
  1. 准备输入文件:
20
+ - `1.xls`:源数据文件,包含 HEADER、Dimension 和 Sand 工作表
21
+ - `2.xlsx`:模板文件,包含 WACKER 工作表
 
 
 
 
22
 
23
  2. 运行脚本:
24
  ```bash
25
+ python main.py
26
  ```
27
 
28
+ 3. 检查输出文件 `2_updated.xlsx`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
  ## 许可证
31
 
32
+ MIT License
 
 
 
 
 
 
 
 
generate_quality_inspection_reports.py DELETED
@@ -1,133 +0,0 @@
1
- import pandas as pd
2
- from openpyxl import load_workbook
3
- from datetime import datetime, timedelta
4
- import os
5
-
6
- def generate_reports(source_file='examples/example_source_data.xls',
7
- template_file='examples/example_template.xlsx',
8
- output_file='quality_inspection_report.xlsx'):
9
- """
10
- 生成质量检验报告。
11
-
12
- 参数:
13
- source_file (str): 源数据文件路径
14
- template_file (str): 模板文件路径
15
- output_file (str): 输出文件路径
16
- """
17
- # 检查文件是否存在
18
- if not os.path.exists(source_file):
19
- raise FileNotFoundError(f"源数据文件不存在: {source_file}")
20
- if not os.path.exists(template_file):
21
- raise FileNotFoundError(f"模板文件不存在: {template_file}")
22
-
23
- # 读取第一个文件
24
- header_df = pd.read_excel(source_file, sheet_name='HEADER')
25
-
26
- # 读取Dimension表,跳过前12行,然后使用第13行作为列名
27
- dimension_df = pd.read_excel(source_file, sheet_name='Dimension', skiprows=12)
28
- # 使用第一行作为列名
29
- dimension_df.columns = dimension_df.iloc[0]
30
- # 删除第一行(现在已经作为列名)并重置索引
31
- dimension_df = dimension_df.iloc[1:].reset_index(drop=True)
32
-
33
- # 读取Sand表的数据
34
- sand_df = pd.read_excel(source_file, sheet_name='Sand', header=None)
35
-
36
- # 读取第二个文件
37
- wb = load_workbook(template_file)
38
- wacker_sheet = wb['WACKER']
39
-
40
- # 获取Sales Order Quantity和Quality Assured By
41
- sales_order_quantity = header_df.iloc[5, 2] # Sales Order Quantity位置
42
- quality_assured_by = header_df.iloc[3, 7] # Quality Assured By在第4行最后一列
43
-
44
- # 定义元素和行号的对应关系
45
- element_row_mapping = {
46
- 'Al': 9, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Al
47
- 'Ca': 10, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Ca
48
- 'Cu': 11, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Cu
49
- 'Fe': 12, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Fe
50
- 'K': 13, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_K
51
- 'Li': 14, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Li
52
- 'Mg': 15, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Mg
53
- 'Mn': 16, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Mn
54
- 'Na': 17, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Na
55
- 'Ti': 18, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Ti
56
- 'Zr': 19 # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Zr
57
- }
58
-
59
- # 定义元素在Sand表中的列索引
60
- element_col_mapping = {
61
- 'Al': 4, # 第5列
62
- 'Ca': 5, # 第6列
63
- 'Cu': 6, # 第7列
64
- 'Fe': 7, # 第8列
65
- 'K': 8, # 第9列
66
- 'Li': 9, # 第10列
67
- 'Mg': 10, # 第11列
68
- 'Mn': 11, # 第12列
69
- 'Na': 12, # 第13列
70
- 'Ti': 13, # 第14列
71
- 'Zr': 14 # 第15列
72
- }
73
-
74
- # 遍历Dimension表格中的每个Customer ID
75
- for index, row in dimension_df.iterrows():
76
- customer_id = row['Customer ID'] # 现在这个列名应该是正确的了
77
- inspection_date = pd.to_datetime(row['Inspection Date']).strftime('%Y-%m-%d') # 格式化日期
78
-
79
- # 创建新的工作表
80
- new_sheet = wb.create_sheet(title=str(customer_id))
81
-
82
- # 复制WACKER表格的内容到新工作表(这样会保持原有的客户名称)
83
- for row_wacker in wacker_sheet.iter_rows(values_only=True):
84
- new_sheet.append(row_wacker)
85
-
86
- # 填充数据(不再覆盖客户名称)
87
- new_sheet['B3'] = str(sales_order_quantity) + ' PCS' # Number+Unit/数量+单位
88
- new_sheet['B4'] = customer_id # Batch reference/批号
89
- new_sheet['D4'] = inspection_date # Date of issue/报告日期
90
- new_sheet['B5'] = inspection_date # Production date/生产日期
91
- new_sheet['D5'] = (datetime.strptime(inspection_date, '%Y-%m-%d') + timedelta(days=730)).strftime('%Y-%m-%d') # Expiring date/失效日期
92
-
93
- # 从sand表中获取当前customer_id的数据
94
- sand_rows = sand_df[sand_df[2] == customer_id] # 使用第3列(索引2)作为Crucible ID
95
- if not sand_rows.empty:
96
- sand_row = sand_rows.iloc[0]
97
-
98
- # 填充元素数据
99
- for element, target_row in element_row_mapping.items():
100
- source_col = element_col_mapping[element]
101
- new_sheet[f'D{target_row}'] = sand_row[source_col]
102
-
103
- # 填充Analysis result/分析结果
104
- # 保持原有的测试项目名称,只更新分析结果列
105
- for i in range(20, 29):
106
- if i == 20:
107
- new_sheet[f'D{i}'] = row['OD1'] # 外径1
108
- elif i == 21:
109
- new_sheet[f'D{i}'] = row['OD2'] # 外径2
110
- elif i == 22:
111
- new_sheet[f'D{i}'] = row['OD3'] # 外径3
112
- elif i == 23:
113
- new_sheet[f'D{i}'] = row['Height'] # 高度
114
- elif i == 24:
115
- new_sheet[f'D{i}'] = row['Wall11'] # 壁厚11
116
- elif i == 25:
117
- new_sheet[f'D{i}'] = row['Wall12'] # 壁厚12
118
- elif i == 26:
119
- new_sheet[f'D{i}'] = row['Wall13'] # 壁厚13
120
- elif i == 27:
121
- new_sheet[f'D{i}'] = row['Wall2'] # 壁厚2
122
- elif i == 28:
123
- new_sheet[f'D{i}'] = row['Wall3'] # 壁厚3
124
-
125
- # 保持"批准人:"文本,并在其后添加名字
126
- new_sheet['D29'] = f"批准人:{quality_assured_by}"
127
-
128
- # 保存修改后的文件
129
- wb.save(output_file)
130
- print(f"报告已生成: {output_file}")
131
-
132
- if __name__ == "__main__":
133
- generate_reports()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
main.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ from openpyxl import load_workbook
3
+ from datetime import datetime, timedelta
4
+
5
+ # 读取第一个文件
6
+ file1 = '1.xls'
7
+ header_df = pd.read_excel(file1, sheet_name='HEADER')
8
+
9
+ # 读取Dimension表,跳过前12行,然后使用第13行作为列名
10
+ dimension_df = pd.read_excel(file1, sheet_name='Dimension', skiprows=12)
11
+ # 使用第一行作为列名
12
+ dimension_df.columns = dimension_df.iloc[0]
13
+ # 删除第一行(现在已经作为列名)并重置索引
14
+ dimension_df = dimension_df.iloc[1:].reset_index(drop=True)
15
+
16
+ # 读取Sand表的数据
17
+ sand_df = pd.read_excel(file1, sheet_name='Sand', header=None)
18
+
19
+ # 读取第二个文件
20
+ file2 = '2.xlsx'
21
+ wb = load_workbook(file2)
22
+ wacker_sheet = wb['WACKER']
23
+
24
+ # 获取Sales Order Quantity和Quality Assured By
25
+ sales_order_quantity = header_df.iloc[5, 2] # Sales Order Quantity位置
26
+ quality_assured_by = header_df.iloc[3, 7] # Quality Assured By在第4行最后一列
27
+
28
+ # 定义元素和行号的对应关系
29
+ element_row_mapping = {
30
+ 'Al': 9, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Al
31
+ 'Ca': 10, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Ca
32
+ 'Cu': 11, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Cu
33
+ 'Fe': 12, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Fe
34
+ 'K': 13, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_K
35
+ 'Li': 14, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Li
36
+ 'Mg': 15, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Mg
37
+ 'Mn': 16, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Mn
38
+ 'Na': 17, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Na
39
+ 'Ti': 18, # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Ti
40
+ 'Zr': 19 # 硅柏_石英坩埚_QC530HS_201410_V3B-CN_Zr
41
+ }
42
+
43
+ # 定义元素在Sand表中的列索引
44
+ element_col_mapping = {
45
+ 'Al': 4, # 第5列
46
+ 'Ca': 5, # 第6列
47
+ 'Cu': 6, # 第7列
48
+ 'Fe': 7, # 第8列
49
+ 'K': 8, # 第9列
50
+ 'Li': 9, # 第10列
51
+ 'Mg': 10, # 第11列
52
+ 'Mn': 11, # 第12列
53
+ 'Na': 12, # 第13列
54
+ 'Ti': 13, # 第14列
55
+ 'Zr': 14 # 第15列
56
+ }
57
+
58
+ # 遍历Dimension表格中的每个Customer ID
59
+ for index, row in dimension_df.iterrows():
60
+ customer_id = row['Customer ID'] # 现在这个列名应该是正确的了
61
+ inspection_date = pd.to_datetime(row['Inspection Date']).strftime('%Y-%m-%d') # 格式化日期
62
+
63
+ # 创建新的工作表
64
+ new_sheet = wb.create_sheet(title=str(customer_id))
65
+
66
+ # 复制WACKER表格的内容到新工作表(这样会保持原有的客户名称)
67
+ for row_wacker in wacker_sheet.iter_rows(values_only=True):
68
+ new_sheet.append(row_wacker)
69
+
70
+ # 填充数据(不再覆盖客户名称)
71
+ new_sheet['B3'] = str(sales_order_quantity) + ' PCS' # Number+Unit/数量+单位
72
+ new_sheet['B4'] = customer_id # Batch reference/批号
73
+ new_sheet['D4'] = inspection_date # Date of issue/报告日期
74
+ new_sheet['B5'] = inspection_date # Production date/生产日期
75
+ new_sheet['D5'] = (datetime.strptime(inspection_date, '%Y-%m-%d') + timedelta(days=730)).strftime('%Y-%m-%d') # Expiring date/失效日期
76
+
77
+ # 从sand表中获取当前customer_id的数据
78
+ sand_rows = sand_df[sand_df[2] == customer_id] # 使用第3列(索引2)作为Crucible ID
79
+ if not sand_rows.empty:
80
+ sand_row = sand_rows.iloc[0]
81
+
82
+ # 填充元素数据
83
+ for element, target_row in element_row_mapping.items():
84
+ source_col = element_col_mapping[element]
85
+ new_sheet[f'D{target_row}'] = sand_row[source_col]
86
+
87
+ # 填充Analysis result/分析结果
88
+ # 保持原有的测试项目名称,只更新分析结果列
89
+ for i in range(20, 29):
90
+ if i == 20:
91
+ new_sheet[f'D{i}'] = row['OD1'] # 外径1
92
+ elif i == 21:
93
+ new_sheet[f'D{i}'] = row['OD2'] # 外径2
94
+ elif i == 22:
95
+ new_sheet[f'D{i}'] = row['OD3'] # 外径3
96
+ elif i == 23:
97
+ new_sheet[f'D{i}'] = row['Height'] # 高度
98
+ elif i == 24:
99
+ new_sheet[f'D{i}'] = row['Wall11'] # 壁厚11
100
+ elif i == 25:
101
+ new_sheet[f'D{i}'] = row['Wall12'] # 壁厚12
102
+ elif i == 26:
103
+ new_sheet[f'D{i}'] = row['Wall13'] # 壁厚13
104
+ elif i == 27:
105
+ new_sheet[f'D{i}'] = row['Wall2'] # 壁厚2
106
+ elif i == 28:
107
+ new_sheet[f'D{i}'] = row['Wall3'] # 壁厚3
108
+
109
+ # 保持"批准人:"文本,并在其后添加名字
110
+ new_sheet['D29'] = f"批准人:{quality_assured_by}"
111
+
112
+ # 保存修改后的文件
113
+ wb.save('2_updated.xlsx')