【小工具-生成合并文件】使用python实现2个excel文件根据主键合并生成csv文件

1 小工具说明

1.1 功能说明

一般来说,我们会先有一个老的文件,这个文件内容是定制好相关列的表格,作为每天的报告。
当下一天来的时候,需要根据新的报表文件和昨天的报表文件做一个合并,合并的时候就会出现有些事新增条目、有些是可能要删除的条目、有些是要更新状态的条目。
当前使用python编写的练习就是达到这个简单目的。

1.2 配置文件

配置文件内容样例:

yesterday=F:\projects\daily_merge_tool\test_files\scene1_no_diff\yesterday.xlsx
today=F:\projects\daily_merge_tool\test_files\scene1_no_diff\today.xlsx
report=F:\projects\daily_merge_tool\test_files\scene1_no_diff\report.csv
yesterday_primary_key_column=D
yesterday_status_column=E
today_primary_key_column=F
today_status_column=E
today_mapping_yesterday=C:B,D:C,F:D,E:E,H:F,I:G,J:H,K:I,L:J,M:K

yesterday的值为昨天的报表文件绝对路径
today的值为今天从其他系统新导出来的报表文件的绝对路径
report的值为存放合并当天最新报表的csv文件的绝对路径
yesterday_primary_key_column的值为昨天的报表文件中能够唯一代表一行数据的属性所在的列,例如:如果值是字母A是excel表格的第一列
yesterday_status_column的值为昨天的报表文件中当前行数据的状态列,例如:如果值是字母A是excel表格的第一列
today_primary_key_column值为今天的报表文件中能够唯一代表一行数据的属性所在的列,例如:如果值是字母A是excel表格的第一列
today_status_column的值为今天的报表文件中当前行数据的状态列,例如:如果值是字母A是excel表格的第一列
today_mapping_yesterday的值为昨天报表文件中各个列的数据来源映射到今天新导出的报表文件中的列

1.3 几个文件的样例

yesterday.xlsx
在这里插入图片描述
today.xlsx
在这里插入图片描述
生成的report.csv,相比yesterday.xlsx,增加了1列Tag,标示当前行是新加还是修改了状态还是确认是否要删除
在这里插入图片描述

2 工具代码

https://download.csdn.net/download/WolfOfSiberian/88399882

import sys
import datetime
import xlrddef read_excel(excel_file_path):print("read excel: " + str(excel_file_path))readfile = xlrd.open_workbook(excel_file_path)names = readfile.sheet_names()obj_sheet = readfile.sheet_by_name(names[0])row = obj_sheet.nrows# col = obj_sheet.ncolsresult = [0 for i in range(row)]for i in range(row):result[i] = obj_sheet.row_values(i)return resultdef get_id_list(filepath, primary_key_column):print(str(datetime.datetime.now()) + " method get_id_list() invoked.")file_arrary = read_excel(filepath)data_row_num = len(file_arrary)id_list = []for i in range(1, data_row_num):id_list.append(file_arrary[i][ord(primary_key_column) - ord('A')])print(str(datetime.datetime.now()) + "file: " + filepath + ", id list:" + str(id_list))return id_listdef get_operation_list(yesterday_filepath, today_filepath,yesterday_primary_key_column,today_primary_key_column):yesterday_id_list = get_id_list(yesterday_filepath, yesterday_primary_key_column)today_id_list = get_id_list(today_filepath, today_primary_key_column)to_add = []to_del = []to_update = []operationList = [yesterday_id_list, today_id_list, to_add, to_del, to_update]for i in range(len(yesterday_id_list)):is_exist_in_today = 0curr_yesterday_id = yesterday_id_list[i]for j in range(len(today_id_list)):if curr_yesterday_id == today_id_list[j]:if curr_yesterday_id not in to_update:to_update.append(curr_yesterday_id)is_exist_in_today = 1breakif is_exist_in_today == 0:if curr_yesterday_id not in to_del:to_del.append(curr_yesterday_id)is_exist_in_today = 0    #reset statusfor i in range(len(today_id_list)):curr_today_id = today_id_list[i]if curr_today_id not in yesterday_id_list:if curr_today_id not in to_add:to_add.append(curr_today_id)print("operationList: \nyesterday_id_list," + str(operationList[0])+ ",\ntoday_id_list" + str(operationList[1])+ ",\nto_add" + str(operationList[2]) + ",\nto_del" +  str(operationList[3]) + ",\nto_update" +  str(operationList[4]))return operationListdef get_status_by_id(id, primary_key_column, status_column, total_result):for i in range(1, len(total_result)):if id == total_result[i][ord(primary_key_column) - ord('A')]:return total_result[i][ord(status_column) - ord('A')]return "N/A"def read_configurations(configuration_filepath):#configuration.txt内容例子# yesterday=F:\\projects\\daily_merge\\test_files\\scene1_no_diff\\yesterday.xlsx# today=F:\\projects\\daily_merge\\test_files\\scene1_no_diff\\today.xlsx# report=F:\\projects\\daily_merge\\test_files\\scene1_no_diff\\report.csv# yesterday_primary_key_column=D# yesterday_status_column=E# today_primary_key_column=F# today_status_column=E# today_mapping_yesterday=C:B,D:C,F:D,E:E,H:F,I:G,J:H,K:I,L:J,M:Kprint("configuration filepath:" + configuration_filepath)configuration_file = open(configuration_filepath, mode='r')lines = configuration_file.readlines()configurations = {}for line in lines:entry = line.strip().split("=")if "," in entry[1]:# today_mapping_yesterdaymapping_entry_array = entry[1].split(",")today_mapping_yesterday = {}for mapping_entry in mapping_entry_array:mapping_key_value = mapping_entry.split(":")today_mapping_yesterday[mapping_key_value[0]] = mapping_key_value[1]configurations[entry[0]] = today_mapping_yesterdayelse :configurations[entry[0]] = entry[1]return configurationsdef generate_today_report(configuration_filepath):yesterday = "F:\\projects\\daily_merge\\test_files\\scene1_no_diff\\yesterday.xlsx"# today = "F:\\projects\\daily_merge\\test_files\\scene1_no_diff\\today.xlsx"# report = "F:\\projects\\daily_merge\\test_files\\scene1_no_diff\\report.csv"# yesterday_primary_key_column = 'D'# yesterday_status_column = 'E'# today_primary_key_column = 'F'# today_status_column = 'E'# today_mapping_yesterday = {'C':'B',#                            'D':'C',#                            'F':'D',#                            'E':'E',#                            'H':'F',#                            'I':'G',#                            'J':'H',#                            'K':'I',#                            'L':'J',#                            'M':'K'}configurations = read_configurations(configuration_filepath)today = configurations['today']report = configurations['report']yesterday_primary_key_column = configurations['yesterday_primary_key_column']yesterday_status_column = configurations['yesterday_status_column']today_primary_key_column = configurations['today_primary_key_column']today_status_column = configurations['today_status_column']today_mapping_yesterday = configurations['today_mapping_yesterday']yesterday_result = read_excel(yesterday)today_result = read_excel(today)operation_list = get_operation_list(yesterday, today, yesterday_primary_key_column, today_primary_key_column)try:report_file = open(report, mode='w')#write titlefor i in range(len(yesterday_result[0])):report_file.write(yesterday_result[0][i])    report_file.write(",")report_file.write("Tag")report_file.write("\n")#write contentfor i in range(1, len(today_result)):id = operation_list[1][i - 1]if id in operation_list[2]:#add#extract for report according by column index mappingto_add_report_record = []for x in range(len(yesterday_result[0])):to_add_report_record.append("")for j in range(len(today_result[i])):current_today_column = chr(j + ord('A'))if current_today_column in today_mapping_yesterday:to_add_report_record[ord(today_mapping_yesterday[current_today_column]) - ord('A')] = today_result[i][j]#write to report for m in range(len(to_add_report_record)):report_file.write(str(to_add_report_record[m]))report_file.write(",")report_file.write("to add")report_file.write("\n")for i in range(1, len(yesterday_result)):id = operation_list[0][i - 1]if id in operation_list[3]:#deletefor j in range(len(yesterday_result[i])):report_file.write(str(yesterday_result[i][j]))report_file.write(",")report_file.write("to delete")else :#updatefor j in range(len(yesterday_result[i])):today_status = get_status_by_id(id, today_primary_key_column, today_status_column, today_result)if j == ord(yesterday_status_column) - ord('A'):report_file.write(today_status)else :report_file.write(str(yesterday_result[i][j]))report_file.write(",")report_file.write("to update")report_file.write("\n")except Exception as e:print("failed to generate report.")print(e)finally:report_file.close()print("generate report successfully.")return
print("==^^==^^==")
if len(sys.argv) <= 1:print("please input the configuration filepath when running this python file.")
else :generate_today_report(sys.argv[1])
print("==^^==^^==")

3 参考资料

解决python中XLRDError: Excel xlsx file; not supported
https://blog.csdn.net/qq_53464193/article/details/128407954
VSCode使用 - 搭建python运行调试环境
https://zhuanlan.zhihu.com/p/625844895?utm_id=0&wd=&eqid=b12208f700185aeb000000036498f302
Python读取Excel文件
https://blog.csdn.net/weixin_49895216/article/details/127812149
python操作Excel读写–使用xlrd
https://blog.csdn.net/qq_36396104/article/details/77875703

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/95963.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【BI看板】Superset2.0+图表二次开发初探

Superset图表功能也很丰富了&#xff0c;但一些个性化的定制需求就需要二次开发了。网上二开的superset版本大多是0.xxx版本的或1.5xxx版本&#xff0c;本次用的是2.xxx。 源码相关说明 源码目录 superset-2.0\superset-frontend\plugins\plugin-chart-echarts 插件相关资料 官…

【重拾C语言】六、批量数据组织(二)线性表——分类与检索(主元排序、冒泡排序、插入排序、顺序检索、对半检索)

目录 前言 六、批量数据组织——数组 6.4 线性表——分类与检索 6.4.1 主元排序 6.4.2 冒泡排序 6.4.3 插入排序 6.4.4 顺序检索&#xff08;线性搜索&#xff09; 6.4.5 对半检索&#xff08;二分查找&#xff09; 算法比较 前言 线性表是一种常见的数据结构&#xf…

在linux下预览markdown的方法,转换成html和pdf

背景 markdown是一种便于编写和版本控制的格式&#xff0c;但却不便于预览——特别是包含表格等复杂内容时&#xff0c;单纯的语法高亮是远远不够的——这样就不能边预览边调整内容&#xff0c;需要找到一种预览方法。 思路 linux下有个工具&#xff0c;叫pandoc&#xff0c…

Go Gin Gorm Casbin权限管理实现 - 2. 使用Gorm存储Casbin权限配置以及`增删改查`

文章目录 0. 背景1. 准备工作2. 权限配置以及增删改查2.1 策略和组使用规范2.2 用户以及组关系的增删改查2.2.1 获取所有用户以及关联的角色2.2.2 角色组中添加用户2.2.3 角色组中删除用户 2.3 角色组权限的增删改查2.3.1 获取所有角色组权限2.3.2 创建角色组权限2.3.3 修改角色…

Spring MVC工作原理

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Qt model/view 理解01

在 Qt 中对数据处理主要有两种方式&#xff1a;1&#xff09;直接对包含数据的的数据项 item 进行操作&#xff0c;这种方法简单、易操作&#xff0c;现实方式单一的缺点&#xff0c;特别是对于大数据或在不同位置重复出现的数据必须依次对其进行操作&#xff0c;如果现实方式改…

10.1select并发服务器以及客户端

服务器&#xff1a; #include<myhead.h>//do-while只是为了不让花括号单独存在&#xff0c;并不循环 #define ERR_MSG(msg) do{\fprintf(stderr,"%d:",__LINE__);\perror(msg);\ }while(0);#define PORT 8888//端口号1024-49151 #define IP "192.168.2.5…

【16】c++设计模式——>建造者(生成器)模式

什么是建造者模式? 建造者模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;它允许你构造复杂对象步骤分解。你可以不同的步骤中使用不同的方式创建对象&#xff0c;且对象的创建与表示是分离的。这样&#xff0c;同样的构建过程可以创建不同的表…

数据结构-快速排序-C语言实现

引言&#xff1a;快速排序作为一种非常经典且高效的排序算法&#xff0c;无论是工作还是面试中广泛用到&#xff0c;作为一种分治思想&#xff0c;需要熟悉递归思想。下面来讲讲快速排序的实现和改进。 老规矩&#xff0c;先用图解来理解一下&#xff1a;&#xff08;这里使用快…

MATLAB中syms函数使用

目录 语法 说明 示例 创建符号标量变量 创建符号标量变量的向量 创建符号标量变量矩阵 管理符号标量变量的假设 创建和评估符号函数 syms函数的作用是创建符号标量和函数&#xff0c;以及矩阵变量和函数。 语法 syms var1 ... varN syms var1 ... varN [n1 ... nM] …

指数分布优化器(EDO)(含MATLAB代码)

先做一个声明&#xff1a;文章是由我的个人公众号中的推送直接复制粘贴而来&#xff0c;因此对智能优化算法感兴趣的朋友&#xff0c;可关注我的个人公众号&#xff1a;启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法&#xff0c;经典的&#xff0c;或者是近几年…

“秋天第一只大闸蟹”背后,看见京东一体化供应链

京东似乎正在从一个大闸蟹的物流服务商、销售商&#xff0c;转变为一个大闸蟹的“供货商”。 作者|斗斗 编辑|皮爷 出品|产业家 阳澄湖连续几天的降雨&#xff0c;使得通往蟹塘的路异常难走。 长期驻扎此地的京东相关负责人蹲在蟹塘边的小路上&#xff0c;指着蟹塘说道…

【RabbitMQ 实战】08 集群原理剖析

上一节&#xff0c;我们用docker-compose搭建了一个RabbitMQ集群&#xff0c;这一节我们来分析一下集群的原理 一、基础概念 1.1 元数据 前面我们有介绍到 RabbitMQ 内部有各种基础构件&#xff0c;包括队列、交换器、绑定、虚拟主机等&#xff0c;他们组成了 AMQP 协议消息…

Cocos Creator3.8 项目实战(五)背景无限滚屏效果如何实现

在游戏中&#xff0c;我们经常会实现背景无限滚动的效果。那这些效果是怎么实现的呢&#xff1f; 原理很简单&#xff0c;就是使用多张背景图&#xff0c;每张图&#xff0c;每一帧都同时移动&#xff0c;当图移出屏幕外时&#xff0c;将其位置设置到下一张图的初始位置&#x…

【AI视野·今日NLP 自然语言处理论文速览 第四十八期】Thu, 5 Oct 2023

AI视野今日CS.NLP 自然语言处理论文速览 Thu, 5 Oct 2023 Totally 50 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Retrieval meets Long Context Large Language Models Authors Peng Xu, Wei Ping, Xianchao Wu, Lawrence McA…

[架构之路-231]:计算机硬件与体系结构 - 性能评估汇总,性能优化加速比

目录 一、计算机体系结构 二、计算机性能评估 2.1 分类方法1 2.2 分类方法2 三、常见的专项性能测试工具 3.1 浮点运算性能&#xff08;FLOPS&#xff09; 3.2 综合理论性能法 3.3 历史基准测试&#xff08;跑分软件&#xff09;&#xff1a;通过运行典型的综合性的程序…

反爬虫机制与反爬虫技术(一)

反爬虫机制与反爬虫技术一 1、网络爬虫的法律与道德问题2、反爬虫机制与反爬虫技术2.1、User-Agent伪装2.2、代理IP2.3、请求频率控制2.4、动态页面处理2.5、验证码识别3、反爬虫案例:豆瓣电影Top250爬取3.1、爬取目标3.2、库(模块)简介3.3、翻页分析3.4、发送请求3.5、提取…

【VUE·疑难问题】定义 table 中每行的高度(使用 element-UI)

一、如何定义 table 中每一行的 height &#xff1f; 1.table例子 <!-- 二、table --><div style"overflow: hidden;display: block;height: 68vh;width: 100%;"><el-table stripe show-header style"width: 100%" :data"tableData&q…

mysql面试题20:有哪些合适的分布式主键方案

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:有哪些合适的分布式主键方案? UUID:UUID通常是由一个二进制的128位整数表示,可以保证全局的唯一性。在Java中,可以通过UUID类生成一个UUID。例…

Hadoop伪分布式环境搭建

什么是Hadoop伪分布式集群&#xff1f; Hadoop 伪分布式集群是一种在单个节点上模拟分布式环境的配置&#xff0c;用于学习、开发和测试 Hadoop 的功能和特性。它提供了一个简化的方式来体验和熟悉 Hadoop 的各个组件&#xff0c;而无需配置和管理一个真正的多节点集群。 在 Ha…