案例背景
我在使用openpyxl写入excel的公式的时候,我发现直接wb.save()存下来后,再进行读取的话,公式格子都是空值,需要手动另存为才会算出数值来...这太麻烦了,我写个周报算数据就是为了用代码自动化...还要手动另存为太不智能了。使用我们可以用代码进行另存为。
主要依靠这个包pywin32。下面是gpt对它的介绍:
pywin32
是一个 Python 库,用于与 Windows 操作系统进行交互和操作。通过这个库,你可以编写 Python 脚本来控制和自动化许多 Windows 应用程序和服务,包括与操作系统底层的交互。
以下是一些 pywin32
常用的功能:
- 与 Windows 应用程序交互:可以自动化与 Office 应用程序(如 Excel、Word 和 Outlook)的交互,自动填充表格、创建文档等。
- 访问 Windows API:可以直接访问和调用 Windows API,实现深入操作系统的各种功能。
- 操作 Windows 服务:可以启动、停止、暂停和恢复 Windows 服务,以及创建和管理服务。
- 访问 Windows 注册表:可以读取和修改 Windows 注册表,用于配置系统和应用程序设置。
- 与 COM 对象交互:可以与 Windows 的 Component Object Model (COM) 对象交互,实现更深层次的系统控制和自动化。
通过这些功能,你可以自动化许多日常办公任务,如生成报告、填充表格、批量处理文档等。此外,你还可以与 Windows 操作系统更深层次地交互,执行自定义任务和配置。
请注意,与系统底层交互时,要谨慎操作,避免不必要的错误和系统不稳定。在使用这些功能时,最好在受控环境中进行测试。
代码实现
到导入包:
import re,os
import openpyxl
import win32com.client
import shutil
在我自动化写入公式,保存了我的excel表后
wb.save('./周报/已开发票数据.xlsx')
我使用pywin32读取,然后传入一个一模一样的路径
# 打开 Excel 应用程序
excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = False # 设置 Excel 为不可见
print(input_path:=os.path.abspath('./周报/已开发票数据.xlsx'))
workbook = excel.Workbooks.Open(input_path)
output_path=os.path.abspath('./周报/已开发票数据.xlsx')
workbook.SaveAs(output_path)
workbook.Close()
excel.Quit()
这样就另存为成功啦!
若是word的另存为,那么需要进行win32com.client.Dispatch("Excel.Application")替换为win32com.client.Dispatch("Word.Application"),然后再去操作。
(ps,这个库读取文件不支持相对路径.....但是我又不喜欢打绝对路径(太长了),所以我都用os变成了绝对路径然后再读取和保存的)
通用脚本
这种另存为的通用功能肯定要写个小脚本:
import win32com.client
import shutil
import os
input_path = input("请输入要另存为的 Excel 文件路径:")
output_path = input("请输入输出文件的路径:")
temp_path = os.path.abspath("temp.xlsx")
paths=[input_path,output_path,temp_path]
input_path,output_path,temp_path=[os.path.abspath(path) for path in paths]
# 打开 Excel 应用程序
excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = False # 设置 Excel 为不可见
workbook = excel.Workbooks.Open(input_path)
# 如果输入路径和输出路径相同,先另存为到临时文件
if os.path.abspath(input_path) == os.path.abspath(output_path):
workbook.SaveAs(temp_path)
else:
workbook.SaveAs(output_path)
print("文件另存为成功!")
# 关闭 Excel
workbook.Close()
excel.Quit()
# 如果输入路径和输出路径相同,覆盖原文件
if os.path.abspath(input_path) == os.path.abspath(output_path):
shutil.move(temp_path, input_path)
我们想对源文件进行另存为然后覆盖,就把输入路径和输出路径都写一样就行,相对路径就行。
或者存不一样的位置可以这样写:
当然,上面的路径也可以写相对路径,存在不同的位置要写绝对路径。
文件复制
前面的示例是专门针对 Excel 文件的。如果想创建一个通用的文件另存为脚本,可以使用 Python 的文件操作,不必依赖特定的库(如 pywin32
)。这种方法适用于所有文件类型,包括 Excel、Word、PowerPoint、文本文件、CSV 等。
上面是另存为excel表的函数,当然,只是想要一模一样的文件,复制就行,下面是通用的文件复制代码:
import shutil
# 获取输入文件路径
input_path = input("请输入要另存为的文件路径:")
# 获取输出文件路径
output_path = input("请输入输出文件的路径:")
# 检查文件是否存在
if not os.path.exists(input_path):
print("输入文件不存在,请检查路径!")
else:
try:
# 使用 shutil.copy2 可以保留原始文件的元数据
shutil.copy2(input_path, output_path)
print("文件另存为成功!")
except Exception as e:
print(f"发生错误:{e}")
这个脚本使用 shutil.copy2
函数复制文件,并保留原始文件的元数据(例如修改时间)。这个方法适用于所有文件类型,并且不依赖特定的文件格式。
只需运行此脚本,然后按照提示输入要另存为的文件路径和输出文件的路径即可。它会将输入文件复制到指定的输出路径,适用于所有常见的文件类型。
下面是gpt对于两张方法的总结和对比:
使用 shutil.copy2
方法和 win32com.client
方法另存为文件之间的主要区别在于处理文件的方式和适用范围。
1. 适用范围
shutil.copy2
:这个方法是通用的文件复制操作,适用于所有文件类型。它不关心文件的内容或格式,只是简单地将文件从一个位置复制到另一个位置。win32com.client
:这个方法是通过 Windows COM 接口与特定应用程序(如 Excel、Word 等)交互。它可以处理特定文件类型的特殊特性,例如 Excel 公式、Word 样式等。
2. 文件内容处理
shutil.copy2
:此方法不会更改文件内容。它将原始文件的所有内容和元数据(如修改时间)复制到新位置。win32com.client
:当与 Office 应用程序交互时,此方法可以处理文件的特殊特性。例如,当另存为 Excel 文件时,可以选择保存格式、处理公式等。
3. 依赖关系
shutil.copy2
:不依赖特定的操作系统或应用程序。只需标准的 Python 库即可。win32com.client
:依赖于 Windows 操作系统和特定的应用程序(如 Excel、Word)。必须在安装了这些应用程序的 Windows 计算机上运行。
总结
- 如果你只需要简单地复制文件,并不关心文件的特殊内容或特性,
shutil.copy2
是一个通用且简单的解决方案。 - 如果你需要处理特定文件类型的特殊特性(如 Excel 的公式计算),并且确保文件在特定应用程序(如 Excel)中的兼容性,那么
win32com.client
方法可能更合适。
通常情况下,对于一般的文件复制或另存为操作,shutil.copy2
方法应该就足够了。对于特定的 Office 文件操作,使用 win32com.client
可能会提供更多控制和灵活性。