【小工具-生成合并文件】使用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.rhkb.cn/news/153297.html

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

相关文章

H5逆向之远程RPC

引言前一讲说过H5 怎么去抓包,逆向分析。其中说到RPC。这一节详细讲一下。有一种情况,JS 比较复杂,混淆的厉害。 这个时候就用到RPC。原理就是,hook web 浏览器,直接调用js 里边的方法。 Node 服务。为什么用到Node 服务,先来看下这架构 Node 对外提供各种接口,外部可以…

基于乌燕鸥优化的BP神经网络(分类应用) - 附代码

基于乌燕鸥优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于乌燕鸥优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.乌燕鸥优化BP神经网络3.1 BP神经网络参数设置3.2 乌燕鸥算法应用 4.测试结果&#x…

【pycharm】sqlite3:Driver class ‘org.sqlite.JDBC‘ not found

pycharm 连接sqlite3的时候&#xff0c;点击&#xff1a;Test Connection 提示&#xff1a;Driver class ‘org.sqlite.JDBC’ not found. 点击&#xff1a;Download missing driver files 点击&#xff1a;Test Connection 这样就ok了&#xff1b;

VR全景拍摄酒店,为用户消除“不透明度”

近日在各大社交平台上&#xff0c;出现了不少吐槽国庆期间酒店价格太贵的帖子&#xff0c;而一些热门旅游地的度假酒店、网红民宿的热门房型已经“一房难求”&#xff0c;这就出现酒店房型与预定房型不同的现象出现&#xff0c;VR全景拍摄技术同酒店行业的结合&#xff0c;就可…

linux中Crontab定时参数

注&#xff1a;图片转载于 点我进入图片出处 * * * * * sh /data/var/test.sh >> test_crontab_log.log分钟 0~59 0表示没分周 小时 0~23 0表示每小时 天 1~31 *表示每天 月 1~12 *表示每月 周 0~7 */0/7表示每周

PDF编辑和OCR文字识别工具ABBYY FineReader PDF

ABBYY FineReader PDF是一款专业的OCR文字识别和PDF编辑工具&#xff0c;可以帮助用户更好地处理和管理PDF文档。以下是ABBYY FineReader PDF的一些特点&#xff1a; 1. 文字识别精准&#xff1a;ABBYY FineReader PDF具有强大的OCR文字识别功能&#xff0c;可以将PDF中的文字…

【香橙派-OpenCV-Torch-dlib】TF损坏变成RAW格式解决方案及python环境配置

前言 本文将介绍在香橙派&#xff08;Orange Pi&#xff09;开发板上进行软件配置和环境搭建的详细步骤&#xff0c;以便运行Python应用程序。这涵盖了以下主要内容&#xff1a; 获取所需软件&#xff1a;提供了香橙派操作系统和balenaEtcher工具的下载链接&#xff0c;以确保…

Netty通信在中间件组件中的广泛使用-Dubbo3举例

Netty是一个高性能异步IO通信框架&#xff0c;封装了NIO&#xff0c;对各种bug做了很好的优化解决。所以很多中间件底层的通信都会使用Netty&#xff0c;比如说&#xff1a;Dubbo3&#xff0c;rocketmq&#xff0c;ElasticSearch等。 比方说&#xff0c;我们使用dubbo作为rpc跨…

flutter出现entrypoint isn‘t within the current project

更新了android studio版本&#xff0c;打开一个老的flutter项目时&#xff0c;无法运行&#xff0c;打开configuration配置&#xff0c;提示错误entrypoint isn’t within the current project. 解决办法 1、删掉目录.idea, .gradle, .dart_tool退出重新打开项目 2、选中根目…

国内首档大模型技术直播专栏重磅推出!

你会好奇AI应用背后的故事吗&#xff1f;它的功能如何实现、如何实现最佳效果&#xff1f;或许大家都曾有过这样的好奇。 每一段代码&#xff0c;都被开发者赋予灵魂&#xff0c;每一个应用背后&#xff0c;都蕴含着长久的思考和深厚的技术基础。我们希望能在开发者之间建立交流…

【深度学习实验】卷积神经网络(七):实现深度残差神经网络ResNet

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. Residual&#xff08;残差连接&#xff09; __init__&#xff08;初始化&#xff09; forward&#xff08;前向传播&#xff09; 2. resnet_block&#xff08;残…

HTML基础入门01

目录 1.HTML基础 1.1HTML标签 1.2HTML 文件基本结构 1.3标签层次结构 1.4快速生成代码框架 2.HTML 常见标签 2.1注释标签 2.2标题标签: h1-h6 2.3段落标签: p 2.4.换行标签: br 3.综合案例: 展示博客 1.HTML基础 1.1HTML标签 HTML 代码是由 "标签" 构成…

0基础学习VR全景平台篇 第104篇:720全景后期软件安装

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 摄影进入数码时代&#xff0c;后期软件继承“暗房工艺”&#xff0c;成为摄影师表达内在情感的必备工具。 首先说明&#xff0c;全景摄影与平面摄影的一个显著的区别是全景图片需…

MyCat-web安装文档:安装Zookeeper、安装Mycat-web

安装Zookeeper A. 上传安装包 zookeeper-3.4.6.tar.gzB. 解压 #解压到当前目录&#xff0c;之后会生成一个安装后的目录 tar -zxvf zookeeper-3.4.6.tar.gz#加上-c 代表解压到指定目录 tar -zxvf zookeeper-3.4.6.tar.gz -C /usr/local/C. 在安装目录下&#xff0c;创建数据…

CasA:用于点云 3D 目标检测的级联注意力网络

论文摘要 LiDAR 收集的数据通常表现出稀疏和不规则的分布。 3D 空间中的 LiDAR 扫描并不均匀。近处和远处的物体之间存在巨大的分布差距。 CasA(Cascade Attention) 由 RPN&#xff08;Region proposal Network&#xff09;和 CRN&#xff08;cascade refinement Network&…

uni-app:引入echarts(使用renderjs)

效果 代码 <template><view click"echarts.onClick" :prop"option" :change:prop"echarts.updateEcharts" id"echarts" class"echarts"></view> </template><script>export default {data()…

用netty实现简易rpc

文章目录 rpc介绍&#xff1a;rpc调用流程:代码&#xff1a; rpc介绍&#xff1a; RPC是远程过程调用&#xff08;Remote Procedure Call&#xff09;的缩写形式。SAP系统RPC调用的原理其实很简单&#xff0c;有一些类似于三层构架的C/S系统&#xff0c;第三方的客户程序通过接…

谷歌 Chrome 浏览器正推进“追踪保护”功能

导读近日消息&#xff0c;根据国外科技媒体 Windows Latest 报道&#xff0c;谷歌计划在 Chrome 浏览器中推进“追踪保护”&#xff08;Tracking Protection&#xff09;功能&#xff0c;整合浏览器现有隐私功能&#xff0c;保护用户被网站跟踪。 根据一项 Chromium 提案&…

unity 控制玩家物体

创建场景 放上一个plane&#xff0c;放上一个球 sphere&#xff0c;假定我们的球就是我们的玩家&#xff0c;使用控制键w a s d 来控制球也就是玩家移动。增加一个材质&#xff0c;把颜色改成绿色&#xff0c;把材质赋给plane&#xff0c;区分我们增加的白球。 增加组件和脚…

06_Node.js服务器开发

1 服务器开发的基本概念 1.1 为什么学习服务器开发 Node.js开发属于服务器开发&#xff0c;那么作为一名前端工程师为什么需要学习服务器开发呢&#xff1f; 为什么学习服务器开发&#xff1f; 能够和后端程序员更加紧密配合网站业务逻辑前置扩宽知识视野 1.2 服务器开发可…