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

纵览

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

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

1、导包

其中部分包没有用到

python 复制代码
import zipfile
import os
import shutil
from openpyxl import load_workbook
import pandas as pd

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

python 复制代码
# 模板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.xml Excel中的所有单元格内容,除页脚、页眉外,所有的信息都在这里
excel_temp/xl/ workbook.xml sheetname修改位置
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数据文件;

python 复制代码
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

python 复制代码
# 重新压缩 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、完成代码

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

python 复制代码
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'
  • 打开文件失败,肯定是替换的字符存在问题,需要一一排查;

结语

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

相关推荐
懒大王爱吃狼34 分钟前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
秃头佛爷2 小时前
Python学习大纲总结及注意事项
开发语言·python·学习
待磨的钝刨2 小时前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
深度学习lover3 小时前
<项目代码>YOLOv8 苹果腐烂识别<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·苹果腐烂识别
XiaoLeisj4 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
API快乐传递者4 小时前
淘宝反爬虫机制的主要手段有哪些?
爬虫·python
励志成为嵌入式工程师5 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉5 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer5 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq5 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端