python excel复制数据保留单元格格式(.xls.xlsx)

最近帮朋友开发一个数据excel根据条件动态过率的功能.读取生成用pandas很方便,但是这里有一点比较麻烦的是得保留原来的单元格格式.这点操作起来就要麻烦一点了.下面总结了.xlsx和.xls处理

在这里插入图片描述

1.xlsx 文件处理

xlsx文件处理可以使用openpyxl库进行处理,比较简单,流程如下

1.获取原来的数据cell

2.进行value和style复制

import openpyxl
import copy
# 复制excel 保留格式
# file_path : 原文件地址
# out_file_path : 输出文件地址
# ids : 条件
def copy_xlsx(file_path,out_file_path,ids):# 打开原表workbook = openpyxl.load_workbook(file_path, data_only=True)# 获取第一个sheet表sheet = workbook.sheet_by_index(0)# 创建一个新的 Excel 文件new_workbook = openpyxl.Workbook()new_sheet = new_workbook.active  # 选择新工作表# 复制数据和样式i = 1  # openpyxl 行号从1开始for row in sheet.iter_rows():# todo 这里条件按需添加,可以去掉if i ==1 or row[0].value in ids:# 复制行for source_cell in row:target_cell = new_sheet.cell(row=i, column=source_cell.column,value = source_cell.value)# 复制样式if source_cell.has_style:# 设置样式 得用 copy.copy() 不然会报错target_cell._style = copy.copy(source_cell._style)target_cell.font = copy.copy(source_cell.font)target_cell.border = copy.copy(source_cell.border)target_cell.fill = copy.copy(source_cell.fill)target_cell.number_format = copy.copy(source_cell.number_format)target_cell.protection = copy.copy(source_cell.protection)target_cell.alignment = copy.copy(source_cell.alignment)i += 1# 保存新的 Excel 文件new_workbook.save(out_file_path)

2. xls 文件处理

xls文件处理起来麻烦点,

首先得引入xlrd 只能进行读取,xlwt负责写入,xlutils相当中间人,可以简化很多操作

import xlrd
import xlwt
from xlutils.filter import process, XLRDReader, XLWTWriter

1.xlrd 获取workbook_rb, formatting_info=True 这个一定要加才能获取到格式,formatting_info模式是false是不获取格式.

2.通过 xlutils 获取到所有单元格格式

3.通过 xlwt 的 worksheet.write(i, col_num, cell.value,style) 写入value 及 style

import xlrd
import xlwt
from xlutils.filter import process, XLRDReader, XLWTWriter# 创建 xls 
def create_xls(savePath:str,ids):# 创建一个新的 Excel 文件(写入模式)workbook_rb = xlrd.open_workbook(path.get(),formatting_info=True)  # 打开工作簿# 这里是关键,获取所有样式列表w = XLWTWriter()process(XLRDReader(workbook_rb, 'unknown.xls'), w)style_list = w.style_listsheet = sheet = workbook.sheet_by_index(0)new_workbook = xlwt.Workbook(encoding='utf-8')new_worksheet = new_workbook.add_sheet('sheet1')  # 添加一个新工作表,替换为你的工作表名称# xlrd 的 index 从0开始i=0for row_num, row in enumerate(sheet.get_rows(), start=0):if i ==0 or row[0].value in ids:for col_num, cell in enumerate(row, start=0):# 复制格式style = style_list[cell.xf_index]#获取当前单元格的stylenew_worksheet.write(i, col_num, cell.value,style)i+=1  new_workbook.save(savePath)return savePath

经过测试,上述代码是可以的,但是有个小问题

w = XLWTWriter()
process(XLRDReader(workbook_rb, 'unknown.xls'), w)
style_list = w.style_list

这段代码我就想获取到style_list 但的东西有点多,这里其实是复制了一个新的workbook对象.新对象里面有原始workbook的所有信息.

在这里插入图片描述
可以看到它包含的 原始 xlrd.book信息 ,xlwt.worksheet 信息(他已经将xlrd.book原始信息进行复制),style_list信息.

这个如果只是对于我们想获取style_list,那么这里信息有点太多.

因此我们能不能只获取style_list呢,我们通过XLWTWriter源码查询下style_list是如何获取的.看下能不能一探究竟.

通过过w.style_list进入源码查看,我们发现在xlutils.filter.BaseWriter.workbook 进行了定义.
在这里插入图片描述
接着我们找下style_list是如何进行赋值的,查询下发现如下代码self.style_list.append(wtxf),这个就是赋值代码.
在这里插入图片描述
让我们看下它是如何实现的,核心代码就是下面这个,大致流程就是

1.创建一个 xlwt.Style.XFStyle() 对象 wtxf

2.从rdbook中获取到格式信息 rdbook.xf_list

3.对 wtxf 进行各种赋值

		if not rdbook.formatting_info:returnfor rdxf in rdbook.xf_list:wtxf = xlwt.Style.XFStyle()## number format#wtxf.num_format_str = rdbook.format_map[rdxf.format_key].format_str## font#wtf = wtxf.fontrdf = rdbook.font_list[rdxf.font_index]wtf.height = rdf.heightwtf.italic = rdf.italicwtf.struck_out = rdf.struck_outwtf.outline = rdf.outlinewtf.shadow = rdf.outlinewtf.colour_index = rdf.colour_indexwtf.bold = rdf.bold #### This attribute is redundant, should be driven by weightwtf._weight = rdf.weight #### Why "private"?wtf.escapement = rdf.escapementwtf.underline = rdf.underline_type #### # wtf.???? = rdf.underline #### redundant attribute, set on the fly when writingwtf.family = rdf.familywtf.charset = rdf.character_setwtf.name = rdf.name# # protection#wtp = wtxf.protectionrdp = rdxf.protectionwtp.cell_locked = rdp.cell_lockedwtp.formula_hidden = rdp.formula_hidden## border(s) (rename ????)#wtb = wtxf.bordersrdb = rdxf.borderwtb.left   = rdb.left_line_stylewtb.right  = rdb.right_line_stylewtb.top    = rdb.top_line_stylewtb.bottom = rdb.bottom_line_style wtb.diag   = rdb.diag_line_stylewtb.left_colour   = rdb.left_colour_index wtb.right_colour  = rdb.right_colour_index wtb.top_colour    = rdb.top_colour_indexwtb.bottom_colour = rdb.bottom_colour_index wtb.diag_colour   = rdb.diag_colour_index wtb.need_diag1 = rdb.diag_downwtb.need_diag2 = rdb.diag_up## background / pattern (rename???)#wtpat = wtxf.patternrdbg = rdxf.backgroundwtpat.pattern = rdbg.fill_patternwtpat.pattern_fore_colour = rdbg.pattern_colour_indexwtpat.pattern_back_colour = rdbg.background_colour_index## alignment#wta = wtxf.alignmentrda = rdxf.alignmentwta.horz = rda.hor_alignwta.vert = rda.vert_alignwta.dire = rda.text_direction# wta.orie # orientation doesn't occur in BIFF8! Superceded by rotation ("rota").wta.rota = rda.rotationwta.wrap = rda.text_wrappedwta.shri = rda.shrink_to_fitwta.inde = rda.indent_level# wta.merg = ????#self.style_list.append(wtxf)

拿到这个代码后就简单了,我们就是照着封装一下,就是使用了.这样我们只要能够获取到rdbook (也就是xlrd获取到的book),就是获取到style_list了.无需获取到其他我们不关注的信息.

这样代码就是可以简单搞成这样,效率会提高不少,只需引入xlrd,xlwt

import xlrd
import xlwt
# 获取到表的所有单元格格式
def get_style_list(rdbook:xlrd.Book):style_list=[]if not rdbook.formatting_info:returnfor rdxf in rdbook.xf_list:wtxf = xlwt.Style.XFStyle()## number format#wtxf.num_format_str = rdbook.format_map[rdxf.format_key].format_str## font#wtf = wtxf.fontrdf = rdbook.font_list[rdxf.font_index]wtf.height = rdf.heightwtf.italic = rdf.italicwtf.struck_out = rdf.struck_outwtf.outline = rdf.outlinewtf.shadow = rdf.outlinewtf.colour_index = rdf.colour_indexwtf.bold = rdf.bold  # This attribute is redundant, should be driven by weightwtf._weight = rdf.weight  # Why "private"?wtf.escapement = rdf.escapementwtf.underline = rdf.underline_type# wtf.???? = rdf.underline #### redundant attribute, set on the fly when writingwtf.family = rdf.familywtf.charset = rdf.character_setwtf.name = rdf.name## protection#wtp = wtxf.protectionrdp = rdxf.protectionwtp.cell_locked = rdp.cell_lockedwtp.formula_hidden = rdp.formula_hidden## border(s) (rename ????)#wtb = wtxf.bordersrdb = rdxf.borderwtb.left = rdb.left_line_stylewtb.right = rdb.right_line_stylewtb.top = rdb.top_line_stylewtb.bottom = rdb.bottom_line_stylewtb.diag = rdb.diag_line_stylewtb.left_colour = rdb.left_colour_indexwtb.right_colour = rdb.right_colour_indexwtb.top_colour = rdb.top_colour_indexwtb.bottom_colour = rdb.bottom_colour_indexwtb.diag_colour = rdb.diag_colour_indexwtb.need_diag1 = rdb.diag_downwtb.need_diag2 = rdb.diag_up## background / pattern (rename???)#wtpat = wtxf.patternrdbg = rdxf.backgroundwtpat.pattern = rdbg.fill_patternwtpat.pattern_fore_colour = rdbg.pattern_colour_indexwtpat.pattern_back_colour = rdbg.background_colour_index## alignment#wta = wtxf.alignmentrda = rdxf.alignmentwta.horz = rda.hor_alignwta.vert = rda.vert_alignwta.dire = rda.text_direction# wta.orie # orientation doesn't occur in BIFF8! Superceded by rotation ("rota").wta.rota = rda.rotationwta.wrap = rda.text_wrappedwta.shri = rda.shrink_to_fitwta.inde = rda.indent_level# wta.merg = ????#style_list.append(wtxf)return style_list# 创建 xls
def copy_xls(file_path:str, savePath: str, ids):# 创建一个新的 Excel 文件(写入模式)workbook_rb = xlrd.open_workbook(file_path, formatting_info=True)  # 打开工作簿# 这里是关键,获取所有样式列表style_list = get_style_list(workbook_rb)# 获取第一个sheetsheet = sheet = workbook_rb.sheet_by_index(0)new_workbook = xlwt.Workbook(encoding='utf-8')new_worksheet = new_workbook.add_sheet('sheet1')  # 添加一个新工作表,替换为你的工作表名称# xlrd 的 index 从0开始i = 0for row in sheet.get_rows():# todo 这里条件按需添加,可以去掉if i == 0 or row[0].value in ids:for col_num, cell in enumerate(row, start=0):# 复制格式style = style_list[cell.xf_index]# 获取当前单元格的stylenew_worksheet.write(i, col_num, cell.value, style)i += 1new_workbook.save(savePath)return savePath

参考:

https://www.cnblogs.com/KeenLeung/p/14101049.html

https://blog.csdn.net/weixin_39804265/article/details/105127786

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

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

相关文章

自定义事件的使用

绑定自定义事件 在Vue.js中&#xff0c;你可以使用自定义事件来实现组件之间的通信。自定义事件允许你在一个组件中触发事件&#xff0c;并在另一个组件中监听并响应该事件。以下是自定义事件的使用方法&#xff1a; 定义一个触发事件的组件&#xff1a; <template>&l…

蓝桥杯每日一题2023.9.15

蓝桥杯2022年第十三届省赛真题-修剪灌木 - C语言网 (dotcpp.com) 题目描述 爱丽丝要完成一项修剪灌木的工作。有 N 棵灌木整齐的从左到右排成一排。爱丽丝在每天傍晚会修剪一棵灌木&#xff0c;让灌木的高度变为 0 厘米。爱丽丝修剪灌木的顺序是从最左侧的灌木开始&#xff0…

Python爬虫:aiohttp的介绍和基本使用

aiohttp 是一个用于编写异步网络应用程序的Python库&#xff0c;它建立在 Python 3.5 的 asyncio 框架之上。它允许你创建高性能的异步HTTP客户端和服务器&#xff0c;以处理并发请求和响应。下面是关于 aiohttp 的介绍和基本使用方法&#xff1a; 安装 aiohttp 你可以使用 p…

[hive]搭建hive3.1.2hiveserver2高可用可hive metastore高可用

参考: Apache hive 3.1.2从单机到高可用部署 HiveServer2高可用 Metastore高可用 hive on spark hiveserver2 web UI 高可用集群启动脚本_薛定谔的猫不吃猫粮的博客-CSDN博客 没用里头的hive on spark,测试后发现版本冲突 一、Hive 集群规划(蓝色部分) ck1ck2ck3Secondary…

java集合 list转map一些常用的方式(Stream流,,,)

Java 集合之间的转换 java集合 list转map一些常用的方式&#xff08;Stream流&#xff0c;&#xff0c;&#xff0c;&#xff09; 提示&#xff1a;帮助文档 文章目录 Java 集合之间的转换前言一、List转换为Map&#xff1f;1.1、**List**<**Object**>**转化为Map<Int…

【虚幻引擎】UE5 VLC接入网络监控、视频直播、网络直播支持RTSP、RTMP

一、如何更新自己的插件匹配自己想要的UE版本 我们在网上下载的插件一般是UE4版本的插件&#xff0c;这个时候就需要我们自己去修改编译&#xff0c;接下来教大家修改插件来适配自己的引擎。 如果不想自己编译代码&#xff0c;可以直接找我拿编译好的UE5.0、UE5.1、UE5.2的插件…

学习路之PHP--laravel postman 提交表单出现419错误

问题图片 解决&#xff1a; 白名单 有时候你可能希望设置一组不需要 CSRF 保护的 URL 。例如&#xff0c;如果你正在使用 Stripe 处理付款并使用了他们的 webhook 系统&#xff0c;你会需要从 CSRF 的保护中排除 Stripe webhook 处理程序路由&#xff0c;因为 Stripe 不知道要发…

swift 天气

定义不同模式主题 自定义颜色 输入框 委托和协议 扩展 协议 http 请求 调用api 闭包

记录crack某IDE插件过程

声明&#xff1a;本文仅记录学习过程&#xff0c;已对关键位置脱敏处理&#xff0c;未提供任何工具&#xff0c;请支持正版。 反编译jar包 使用cfr进行对插件核心jar包MyBxxxxxx-obfuss.jar进行反编译&#xff0c;在本地生成a.txt。 java -jar cfr-0.152.jar MyBxxxx-obfuss.…

面试被问:Mysql的InnoDB下RR是如何解决幻读问题的

这个问题应该分几方面来答 第一方面&#xff1a;什么是幻读 Mysql事务在并发下会产生脏读、不可重复读、幻读问题。 赃读&#xff1a;一个事务可以读到另一个事务还没有提交的数据&#xff1b; 不可重复读&#xff1a;一个事务可以读到另一个事务修改并提交的数据&#xff1…

神经网络小记-混淆矩阵

混淆矩阵&#xff08;Confusion Matrix&#xff09;是在机器学习和统计学中用于评估分类模型性能的一种常用工具。它以表格的形式显示了模型的预测结果与实际真值之间的关系&#xff0c;特别适用于二元分类问题。混淆矩阵通常包含以下四个重要的指标&#xff1a; 假设我们有一…

WPF控件模板

在过去&#xff0c;Windows开发人员必须在方便性和灵活性之间做出选择。为得到最大的方便性&#xff0c;他们可以使用预先构建好的控件。这些控件可以工作的足够好&#xff0c;但可定制性十分有限&#xff0c;并且几乎总是具有固定的可视化外观。偶尔&#xff0c;某些控件提供了…

用flask框架flask-sock和websocket创建一个自己的聊天界面

WebSocket 协议在10年前就已经标准化了(在2011年&#xff0c;你能相信吗?)所以我相信你不需要介绍。但是如果你不熟悉它&#xff0c;WebSocket 是 HTTP 协议的一个扩展&#xff0c;它在客户端和服务器之间提供了一个永久的、双向的通信通道&#xff0c;在这里双方可以实时地发…

Hugging Face使用Stable diffusion Diffusers Transformers Accelerate Pipelines VAE

Diffusers A library that offers an implementation of various diffusion models, including text-to-image models. 提供不同扩散模型的实现的库&#xff0c;代码上最简洁&#xff0c;国内的问题是 huggingface 需要翻墙。 Transformers A Hugging Face library that pr…

Java手写归并排序和案例拓展

Java手写归并排序和案例拓展 手写归并排序具必要性&#xff1a; 理解算法原理&#xff1a;通过手写归并排序算法&#xff0c;可以深入理解其原理和操作步骤。从头开始编写算法代码可以加深对归并排序的理解&#xff0c;包括分割、合并等步骤。 学习编程技巧&#xff1a;手写归…

怎么将几张图片做成pdf合在一起

怎么将几张图片做成pdf合在一起&#xff1f;在我们平时的工作中&#xff0c;图片和pdf都是非常重要的电脑文件&#xff0c;使用也非常频繁&#xff0c;图片能够更为直观的展示内容&#xff0c;而pdf则更加的正规&#xff0c;很多重要文件大多会做成pdf格式的。在职场人的日常工…

C# OpenCvSharp 图片模糊检测(拉普拉斯算子)

效果 项目 代码 using OpenCvSharp; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Windows.Forms.VisualStyl…

java CAS详解(深入源码剖析)

CAS是什么 CAS是compare and swap的缩写&#xff0c;即我们所说的比较交换。该操作的作用就是保证数据一致性、操作原子性。 cas是一种基于锁的操作&#xff0c;而且是乐观锁。在java中锁分为乐观锁和悲观锁。悲观锁是将资源锁住&#xff0c;等之前获得锁的线程释放锁之后&am…

Linux下,基于TCP与UDP协议,不同进程下单线程通信服务器

C语言实现Linux下&#xff0c;基于TCP与UDP协议&#xff0c;不同进程下单线程通信服务器 一、TCP单线程通信服务器 先运行server端&#xff0c;再运行client端输入"exit" 是退出 1.1 server_TCP.c **#include <my_head.h>#define PORT 6666 #define IP &qu…

React 全栈体系(九)

第五章 React 路由 一、相关理解 1. SPA 的理解 单页 Web 应用&#xff08;single page web application&#xff0c;SPA&#xff09;。整个应用只有一个完整的页面。点击页面中的链接不会刷新页面&#xff0c;只会做页面的局部更新。数据都需要通过 ajax 请求获取, 并在前端…