Python 挖坑式填充Excel模板内容(包括页眉/SheetName/logo)

纵览

  • Python处理Excel的方式--解压缩方式
      • 1、导包
      • 2、对模板文件进行解压缩
      • 3、对解压缩后文件层级进行介绍
      • 4、准备需要载入的数据
      • 5、模板挖坑
      • 6、运行替换代码
      • 7、压缩文件
      • 8、生成文件
      • 9、完成代码
      • 10、可能遇到的问题
  • 结语

Python处理Excel的方式–解压缩方式

在处理Excel中过程中,总是会遇到往已经存在的模板中填写特殊信息,一开始我使用的是常见的 openpyxl包,但是在我修改页眉中的字符时,发生页眉中的logo丢失现象,然后我就百度、ChatGPT搜索,最终找到了一种方法,那就是解压缩xlsx文件,然后修改内容,再进行压缩的方式实现修改内容的功能,利用的zipfile包,当然这个包应该是自带的吧,我使用的是Anaconda

1、导包

其中部分包没有用到

import zipfile
import os
import shutil
from openpyxl import load_workbook
import pandas as pd

2、对模板文件进行解压缩

# 模板Excel文件路径
excel_path = r'D:\MyPython\程序\模版.xlsx'
# 解压缩 Excel 文件
with zipfile.ZipFile(excel_path, 'r') as zip_ref:
	zip_ref.extractall('excel_temp')

3、对解压缩后文件层级进行介绍

运行上述代码,会在当前目录下,生成一个文件夹excel_temp,目录结构如下:
在这里插入图片描述
其中,主要关注的是xl文件夹里面的文件,文件内容意思如下:

路径文件名功能
excel_temp/xl/sharedStrings.xmlExcel中的所有单元格内容,除页脚、页眉外,所有的信息都在这里
excel_temp/xl/workbook.xmlsheetname修改位置
excel_temp/xl/worksheets/styles.xml修改单元格的样式
excel_temp/xl/worksheets/sheet?.xml页眉页脚修改区域修改位置,每个sheet对应1个文件
excel_temp/xl/drawings/_rels/drawing1.xml.rels页眉页脚修改区域修改位置,每个sheet对应1个文件图片路径的,如果模板中已经存在图片的,如果想要换个图标,可以通过覆盖下面的图片就行
excel_temp/xl/media/image?.png将新的文件覆盖掉对应的png文件就行,可以利用shutil.copy(替换图片路径,要被替换的路径)

4、准备需要载入的数据

替换模板数据,最重要的是先将你要替换的数据整理好,然后再在模板中相应的位置挖空,填充就行,我的数据格式是excel,如下:A列是替换名称,B到D列是数据,然后运行代码会生成填入B、C、D对应的数据的三个文件;
在这里插入图片描述

5、模板挖坑

打开模板文件,将需要替换的位置成相应的字符,比如:现在我想要替换发光点数量,输入发光点数量替换值,这个可以根据自己实际情况更换;
在这里插入图片描述

6、运行替换代码

excel_path是模板路径,soure_file数据文件;

data_df = pd.read_excel(soure_file,sheet_name=0) #,usecols=[0,1]
# 将某一列(例如'index_column')设为索引
data_df.set_index('字段', inplace=True)
# 将DataFrame转换为字典
data_dict = data_df.to_dict()

# 删除值为NaN的键值对
data1_dict = {col: {index: value for index, value in data_dict[col].items() if pd.notna(value)} for col in data_dict}
# 修改页眉 文件
for keya in data1_dict.keys():
    # 解压缩 Excel 文件
    with zipfile.ZipFile(excel_path, 'r') as zip_ref:
        zip_ref.extractall('excel_temp')
    # 修改相关 XML 文件
    content_path = 'excel_temp/xl/sharedStrings.xml'
    workbook_path = 'excel_temp/xl/workbook.xml'
    for fm in os.listdir('excel_temp/xl/worksheets'):
        if '.xml' in fm:
            with open(f'excel_temp/xl/worksheets/{fm}', 'r+') as f:
                header_footer_xml = f.read()
                for key,value in data1_dict[keya].items():
                    header_footer_xml = header_footer_xml.replace(key+'替换值', str(value))
                f.seek(0)
                f.write(header_footer_xml)
                f.truncate()

    # 修改内容 文件
    with open(content_path, 'r+') as f:
        header_footer_xml = f.read()
        for key,value in data1_dict[keya].items():
            header_footer_xml = header_footer_xml.replace(key+'替换值', str(value))
        f.seek(0)
        f.write(header_footer_xml)
        f.truncate()

    # 修改类似:sheetname 这样的字符
    # 修改Sheetname文件
    with open(workbook_path, 'r+') as f:
        header_footer_xml = f.read()
        header_footer_xml = header_footer_xml.replace("SHEETNAME", data1_dict[keya]['SheetName'].replace('/',''))
        f.seek(0)
        f.write(header_footer_xml)
        f.truncate()

7、压缩文件

将修改后的文件,重新压缩,并且删除临时文件夹excel_temp

# 重新压缩 Excel 文件
with zipfile.ZipFile(data1_dict[keya]['Name'].replace('/','')+'.xlsx', 'w') as zip_ref:
    for folder_name, subfolders, filenames in os.walk('excel_temp'):
        for filename in filenames:
            file_path = os.path.join(folder_name, filename)
            arcname = os.path.relpath(file_path, 'excel_temp')
            zip_ref.write(file_path, arcname)
# 删除临时文件夹
shutil.rmtree('excel_temp')

8、生成文件

运行完成后,会在当前目录下生成对应的文件,如果你想要放在其他路径可以修改data1_dict[keya]['Name'].replace('/','')+'.xlsx'这个位置的代码,利用os.path.join()进行路径拼接即可。

9、完成代码

文件存在关键信息,我就不展示了,代码如下:

import zipfile
import os
import shutil
from openpyxl import load_workbook
import pandas as pd
# 修改页眉 文件
def get_file(excel_path, soure_file):
    data_df = pd.read_excel(soure_file,sheet_name=0) #,usecols=[0,1]
    # 将某一列(例如'index_column')设为索引
    data_df.set_index('序列', inplace=True)
    # 将DataFrame转换为字典
    data_dict = data_df.to_dict()

    # 删除值为NaN的键值对
    data1_dict = {col: {index: value for index, value in data_dict[col].items() if pd.notna(value)} for col in data_dict}

    for keya in data1_dict.keys():
        # 解压缩 Excel 文件
        with zipfile.ZipFile(excel_path, 'r') as zip_ref:
            zip_ref.extractall('excel_temp')
        # 修改相关 XML 文件
        content_path = 'excel_temp/xl/sharedStrings.xml'
        workbook_path = 'excel_temp/xl/workbook.xml'
        for fm in os.listdir('excel_temp/xl/worksheets'):
            if '.xml' in fm:
                with open(f'excel_temp/xl/worksheets/{fm}', 'r+') as f:
                    header_footer_xml = f.read()
                    for key,value in data1_dict[keya].items():
                        header_footer_xml = header_footer_xml.replace(key+'替换值', str(value))
                    f.seek(0)
                    f.write(header_footer_xml)
                    f.truncate()

        # 修改内容 文件
        with open(content_path, 'r+') as f:
            header_footer_xml = f.read()
            for key,value in data1_dict[keya].items():
                header_footer_xml = header_footer_xml.replace(key+'替换值', str(value))
            f.seek(0)
            f.write(header_footer_xml)
            f.truncate()

        # 修改类似:这样的字符
        # 修改Sheetname文件
        with open(workbook_path, 'r+') as f:
            header_footer_xml = f.read()
            header_footer_xml = header_footer_xml.replace("SHEETNAME", data1_dict[keya]['SheetName'].replace('/',''))
            f.seek(0)
            f.write(header_footer_xml)
            f.truncate()
        # 重新压缩 Excel 文件
        with zipfile.ZipFile(data1_dict[keya]['产品类别'].replace('/','')+'.xlsx', 'w') as zip_ref:
            for folder_name, subfolders, filenames in os.walk('excel_temp'):
                for filename in filenames:
                    file_path = os.path.join(folder_name, filename)
                    arcname = os.path.relpath(file_path, 'excel_temp')
                    zip_ref.write(file_path, arcname)
        # 删除临时文件夹
        shutil.rmtree('excel_temp')
excel_path = r'D:\MyPython\程序\Nan_Czy\流程单自动生成\模版.xlsx'
soure_file = r'D:\MyPython\程序\Nan_Czy\流程单自动生成\关键信息清单.xlsx'
get_file(excel_path, soure_file)

10、可能遇到的问题

  • 读取文件存在问题,需要在对应位置加上:encoding='utf-8'
  • 打开文件失败,肯定是替换的字符存在问题,需要一一排查;

结语

好的,本次遇到的问题已经解决并且记录下来了,希望能够帮助你!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024-6-26 石群电路-30

2024-6-26,星期三,10:38,天气:雨,心情:晴。今天没有什么事情发生,继续学习,加油!!!!! 今日观看了石群老师电路课程的视频…

SpringBoot中使用多线程调用异步方法,异步方法有无返回值例子。

快速了解Async注解的用法,包括异步方法无返回值、有返回值,最后总结Async注解失效的几个坑。 在我们的 SpringBoot 应用中,经常会遇到在一个接口中,同时做事情1,事情2,事情3,如果同步执行的话&a…

2024期权交易佣金手续费最低是多少?期权交易有哪些成本?

显性成本 期权交易的显性成本包含期权交易的佣金和交易所费用,分别支付给券商和交易所,统一由券商代收。 佣金 期权佣金是期权交易时支付给券商的费用,佣金通常以交易金额的一定比例计算,可以是固定费用,也可以是滑…

深入理解计算机系统 CSAPP 家庭作业7.12

A:refptr (unsigned)(ADDR(r.symbol) r.addend - refaddr) 0x4004f8 (-4) - 0x4004ea 0xa B:refaddr 0x4004d0 0xa 0x4004da refptr 0x400500 (-4) - 0x4004da 0x22 ​​​​​​​

docker安装与入门使用(适用于小白)

总结:Docker 是一个开源的容器化平台,旨在使开发、部署和运行应用程序的过程更加简单和高效。Docker 使用操作系统级虚拟化在单个主机上运行多个独立的容器。每个容器包含应用程序及其所有依赖项,确保在不同环境中具有一致的运行表现。 下面…

【招聘贴】JAVA后端·唯品会·BASE新加坡

作者|老夏(题图:公司业务介绍页) “ 请注意,这两个岗是BASE新加坡的,欢迎推荐给身边需要的朋友(特别是在新加坡的)。” VIP海外业务-产品技术团队,这两个岗位属于后端工程组的岗&…

【ocean】ocnPrin结合getData导出数据

核心就是这一句ocnPrint(?output fout leafValue( getData(“/output” ?result “dc”))) r_list list(4000, 4100, 4200) multi_list list(20,21,22) fout outfile("/home/yourpath/results.txt" "w") foreach(r_value r_listforeach(multi_value …

第11周 多线程接口并行对数据字典的查询优化

第11周 多线程接口并行对数据字典的查询优化 本章概述1. 多线程的初始化方式1.1 简单实现多线程的启动方式(3种)1. 继承Thread实现2. 实现Runnable接口3. 实现callable接口(返回值)1.2 基于线程池实现多线程的启动方式❤❤❤2. 多线程编排工具CompletableFuture2.1 Completable…

onlyoffice实现在单页面加载文档的功能

草图 实现案例的基本原型 这里我们的样式库使用的是Tailwindcss,我们的前端UI组件库使用的是Ant Design Vue。 基本原型是,有个按钮,没有点击按钮的时候,页面显示的时普通的内容。当点击这个按钮的时候,页面加载文档…

UNIAPP编译到微信小程序时,会多一层以组件命名的标签

UNIAPP编译到微信小程序时,会多一层以组件命名的标签 解决方案 可以配置virtualHost来配置 export default {options: {virtualHost: true} }

化茧成蝶 | 继HuggingFace首家落地大模型具身智能场景

关于具身智能的起源 近年来,大语言模型(LLMs)的兴起给机器人领域带来了革命性的改变,大模型赋予了传统机器人理解和推理的能力,让具身智能这一概念再度出现在大众的视角中。OpenCSG 作为国内 AI 开源社区的先锋&#…

Flask之数据库

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 目录 一、数据库的分类 1.1、SQL 1.2、NoSQL 1.3、如何选择? 二、ORM魔法 三、使用Flask-SQLALchemy管理数据库 3.1、连接数据库服…

美创携手浙江长征职业技术学院,共建智云数据安全大师工作室

6月24日,“美创科技浙江长征职业技术学院智云数据安全大师工作室揭牌暨中国特色学徒制第四期云数据安全和智能运维人才选拔培养启动仪式”在长征职业技术学院隆重举行。 浙江长征职业技术学院计算机与信息技术学院院长梅灿华、计算机与信息技术学院学工办副主任华春…

[深度学习] Transformer

Transformer是一种深度学习模型,最早由Vaswani等人在2017年的论文《Attention is All You Need》中提出。它最初用于自然语言处理(NLP)任务,但其架构的灵活性使其在许多其他领域也表现出色,如计算机视觉、时间序列分析…

Orangepi Zero2使用外设驱动库wiringOP配合时间函数驱动HC-SR04超声波测距模块

目录 一、HC-SR04超声波模块原理和硬件接线 1.1 超声波测距原理: 1.2 超声波时序图: 1.3 HC-SR04超声波模块硬件接线: 二、时间函数 2.1 时间函数gettimeofday()原型和头文件: 2.2 使用gettimeofday()函数获取当前时间的秒数…

经验分享,免费商标查询网站

有时候想快速查询商标状况,官方网站比较慢,这里分享一个免费快速的网站。 网址:https://www.sscha.com/ 截图:

platform 设备驱动实验

platform 设备驱动实验 Linux 驱动的分离与分层 代码的重用性非常重要,否则的话就会在 Linux 内核中存在大量无意义的重复代码。尤其是驱动程序,因为驱动程序占用了 Linux内核代码量的大头,如果不对驱动程序加以管理,任由重复的…

电脑没声音是什么原因?一篇文章帮你解决疑惑

在使用电脑时,声音是至关重要的一部分,无论是播放音乐、观看视频还是进行视频会议。然而,有时候电脑可能会出现没声音的情况,这让人感到非常困扰。那么电脑没声音是什么原因呢?本文将详细介绍解决电脑没声音问题的三种…

【Java Web】XML格式文件

目录 一、XML是什么 二、常见配置文件类型 *.properties类型: *.xml类型: 三、DOM4J读取xml配置文件 3.1 DOM4J的使用步骤 3.2 DOM4J的API介绍 一、XML是什么 XML即可扩展的标记语言,由标记语言可知其基本语法和HTML一样都是由标签构成的文件…

仓库管理系统12--物资设置供应商设置

1、添加供应商窗体 2、布局控件UI <UserControl x:Class"West.StoreMgr.View.SupplierView"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc"http://…