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

结语

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

相关推荐
databook8 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar9 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户8356290780519 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_9 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机16 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机17 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机17 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机17 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i17 小时前
drf初步梳理
python·django
每日AI新事件17 小时前
python的异步函数
python