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,一经查实,立即删除!

相关文章

[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…

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

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

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

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

swift 天气

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

记录crack某IDE插件过程

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

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

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

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. 提供不同扩散模型的实现的库,代码上最简洁,国内的问题是 huggingface 需要翻墙。 Transformers A Hugging Face library that pr…

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

怎么将几张图片做成pdf合在一起?在我们平时的工作中,图片和pdf都是非常重要的电脑文件,使用也非常频繁,图片能够更为直观的展示内容,而pdf则更加的正规,很多重要文件大多会做成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的缩写,即我们所说的比较交换。该操作的作用就是保证数据一致性、操作原子性。 cas是一种基于锁的操作,而且是乐观锁。在java中锁分为乐观锁和悲观锁。悲观锁是将资源锁住,等之前获得锁的线程释放锁之后&am…

React 全栈体系(九)

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

el-select 下拉框全选、多选的几种方式组件

组件一、基础多选 适用性较广的基础多选&#xff0c;用 Tag 展示已选项 <template><el-select v-model"value1" multiple placeholder"请选择"><el-optionv-for"item in options":key"item.value":label"item.la…

基于SpringBoot+Vue的宠物领养饲养交流管理平台设计与实现

前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb;…

vue3+TS前端JS实现 搜索关键词变红

起初在网上搜索获得的处理方式大都是类似这种&#xff1a; 但是实际使用中发现&#xff0c;对于汉字和数字是没有问题的&#xff0c;但是如果有字母就会出现问题。 1.只有汉字和数字的时候&#xff1a;匹配正常。 2.当有字母的时候&#xff1a;异常替换。 原因&#xff1a;第二…

TuyaLink 快速入门教程

通过本入门教程&#xff0c;大家能了解到如何在涂鸦 IoT 开发平台上使用 TuyaLink 完成智能设备接入。并通过 Java 程序&#xff0c;在 IntelliJ IDEA 中使用 TuyaLink 的 GitHub Demo 工程&#xff0c;对一个电工开关设备&#xff0c;实现基本的数据上报下发功能。 准备工作 …

测试与FastAPI应用数据之间的差异

【squids.cn】 全网zui低价RDS&#xff0c;免费的迁移工具DBMotion、数据库备份工具DBTwin、SQL开发工具等 当使用两个不同的异步会话来测试FastAPI应用程序与数据库的连接时&#xff0c;可能会出现以下错误&#xff1a; 在测试中&#xff0c;在数据库中创建了一个对象&#x…

QT记事本+登陆界面的简单实现

主体头文件 #ifndef JSB_H #define JSB_H#include <QMainWindow> #include <QMenuBar>//菜单栏 #include <QToolBar>//工具栏 #include <QStatusBar>//状态栏 #include <QTextEdit>//文本 #include <QLabel>//标签 #include <QDebug&g…

Golang gorm 一对一关系

一对一关系 一对一关系比较少&#xff0c;一般用于表的扩展例如一张用户表&#xff0c;有很多字段那么就可以把它拆分为两张表&#xff0c;常用的字段放主表&#xff0c;不常用的字段放详情表。 针对用户表来说可以通过user去点出userinfo。 创建表和插入数据 package mainimp…

纯js实现html指定页面导出word

因为最近做了范文网站需要&#xff0c;所以要下载为word文档&#xff0c;如果php进行处理&#xff0c;很吃后台服务器&#xff0c;所以想用前端进行实现。查询github发现&#xff0c;确实有这方面的插件。 js导出word文档所需要的两个插件&#xff1a; FileSaver.js jquery.w…

【AI视野·今日NLP 自然语言处理论文速览 第三十六期】Tue, 19 Sep 2023

AI视野今日CS.NLP 自然语言处理论文速览 Tue, 19 Sep 2023 (showing first 100 of 106 entries) Totally 106 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Speaker attribution in German parliamentary debates with QLoRA-ada…