如何用Python Click同时读取两个文件?解决BadZipFile报错
问题原因
你遇到的zipfile.BadZipFile错误,是因为用文本模式打开了Excel文件。Excel(.xlsx格式)本质是压缩包结构,click.File()默认以文本模式('r')打开文件,这种模式会修改二进制文件的内容,导致pandas无法识别为有效的zip格式文件。
两种解决方案
方案1:直接传递文件路径(推荐)
放弃使用click.File(),改用click.Path()获取文件路径字符串,pandas的read_csv和read_excel可以直接接收路径参数,这种方式更简洁且不易出错。
完整代码示例:
import click import pandas as pd @click.command() @click.option('--input', type=click.Path(exists=True), required=True, help='CSV文件路径') @click.option('--input1', type=click.Path(exists=True), required=True, help='Excel文件路径') def main(input, input1): # 读取CSV文件 csv_df = pd.read_csv(input) click.echo(f"CSV文件读取成功,共{len(csv_df)}行数据") # 读取Excel文件(需提前安装openpyxl:pip install openpyxl) excel_df = pd.read_excel(input1, engine='openpyxl') click.echo(f"Excel文件读取成功,共{len(excel_df)}行数据") if __name__ == '__main__': main()
方案2:使用文件对象(指定二进制模式)
如果必须用文件对象传递,需要给Excel对应的参数指定二进制打开模式('rb'),避免破坏文件结构。
完整代码示例:
import click import pandas as pd @click.command() @click.option('--input', type=click.File('r'), required=True, help='CSV文件(文本模式)') @click.option('--input1', type=click.File('rb'), required=True, help='Excel文件(二进制模式)') def main(input, input1): # 读取CSV csv_df = pd.read_csv(input) click.echo(f"CSV文件读取成功,共{len(csv_df)}行数据") # 读取Excel excel_df = pd.read_excel(input1, engine='openpyxl') click.echo(f"Excel文件读取成功,共{len(excel_df)}行数据") if __name__ == '__main__': main()
运行命令
保持你原来的命令即可:
python reporting/generate_cli.py --input ./reporting/data/f1.csv --input1 ./reporting/data/f2.xlsx
注意事项
- 确保已安装
openpyxl:执行pip install openpyxl,pandas读取.xlsx格式文件依赖该引擎。 - 使用
click.Path(exists=True)可以提前校验文件是否存在,避免后续读取时报错。
内容的提问来源于stack exchange,提问作者kalin.klinkov
相关产品推荐
相关产品推荐

