You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

子类化Pandas与Openpyxl读取Excel跳过删除线行报错求助

pandas升级后自定义Excel读取器报错的修复方案

问题背景

需要解析并合并数百个Excel表格,要求跳过带有删除线格式的条目。此前基于@Henry Yik提供的子类化_OpenpyxlReader和CustomExcelFile的代码稳定运行一年以上,但10月初pandas库更新后运行报错:TypeError: CustomReader.get_sheet_data() takes 3 positional arguments but 4 were given。尝试修改CustomReader类及恢复旧环境均未解决,当前临时方案是使用pandas=1.4.1的独立conda环境,现寻求适配新版库的修复方案。

原代码

import pandas as pd
from pandas.io.excel._openpyxl import _OpenpyxlReader
from pandas._typing import Scalar
from typing import List
from pandas.io.excel._odfreader import _ODFReader
from pandas.io.excel._xlrd import _XlrdReader

class CustomReader(_OpenpyxlReader):
    def get_sheet_data(self, sheet, convert_float: bool) -> List[List[Scalar]]:
        data = []
        for row in sheet.rows:
            first = row[1] # 仅检查该单元格的删除线格式
            if first.value is not None and first.font.strike: continue
            else:
                data.append([self._convert_cell(cell, convert_float) for cell in row])
        return data

class CustomExcelFile(pd.ExcelFile):
    _engines = {"xlrd": _XlrdReader, "openpyxl": CustomReader, "odf": _ODFReader}

报错栈信息

excel = CustomExcelFile(r"excel_file_name.xlsx", engine="openpyxl")
df = excel.parse()

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [12], line 17
     15     file.decrypt(decrypted)   
     16     excel = CustomExcelFile(decrypted, engine = "openpyxl")
---> 17     data = excel.parse(usecols="A:M", index = 0, header = 0)


File /home/dev/anaconda3/envs/lwo_datasci/lib/python3.10/site-packages/pandas/io/excel/_base.py:1734, in ExcelFile.parse(self, sheet_name, header, names, index_col, usecols, squeeze, converters, true_values, false_values, skiprows, nrows, na_values, parse_dates, date_parser, thousands, comment, skipfooter, convert_float, mangle_dupe_cols, **kwds)
   1700 def parse(
   1701     self,
   1702     sheet_name: str | int | list[int] | list[str] | None = 0,
   (...)
   1721     **kwds,
   1722 ) -> DataFrame | dict[str, DataFrame] | dict[int, DataFrame]:
   1723     """
   1724     Parse specified sheet(s) into a DataFrame.
   1725 
   (...)
   1732         DataFrame from the passed in Excel file.
   1733     """
-> 1734     return self._reader.parse(
   1735         sheet_name=sheet_name,
   1736         header=header,
   1737         names=names,
   1738         index_col=index_col,
   1739         usecols=usecols,
   1740         squeeze=squeeze,
   1741         converters=converters,
   1742         true_values=true_values,
   1743         false_values=false_values,
   1744         skiprows=skiprows,
   1745         nrows=nrows,
   1746         na_values=na_values,
   1747         parse_dates=parse_dates,
   1748         date_parser=date_parser,
   1749         thousands=thousands,
   1750         comment=comment,
   1751         skipfooter=skipfooter,
   1752         convert_float=convert_float,
   1753         mangle_dupe_cols=mangle_dupe_cols,
   1754         **kwds,
   1755     )

File /home/dev/anaconda3/envs/lwo_datasci/lib/python3.10/site-packages/pandas/io/excel/_base.py:765, in BaseExcelReader.parse(self, sheet_name, header, names, index_col, usecols, squeeze, dtype, true_values, false_values, skiprows, nrows, na_values, verbose, parse_dates, date_parser, thousands, decimal, comment, skipfooter, convert_float, mangle_dupe_cols, **kwds)
    762     sheet = self.get_sheet_by_index(asheetname)
    764 file_rows_needed = self._calc_rows(header, index_col, skiprows, nrows)
---> 765 data = self.get_sheet_data(sheet, convert_float, file_rows_needed)
    766 if hasattr(sheet, "close"):
    767     # pyxlsb opens two TemporaryFiles
    768     sheet.close()

TypeError: CustomReader.get_sheet_data() takes 3 positional arguments but 4 were given
> TypeError: CustomReader.get_sheet_data() takes 3 positional arguments
> but 4 were given

修复方案

新版本pandas对get_sheet_data方法新增了file_rows_needed参数,导致自定义方法的签名与父类不匹配。只需修改CustomReader的get_sheet_data方法,添加该参数即可(无需在逻辑中使用):

修改后的代码

import pandas as pd
from pandas.io.excel._openpyxl import _OpenpyxlReader
from pandas._typing import Scalar
from typing import List
from pandas.io.excel._odfreader import _ODFReader
from pandas.io.excel._xlrd import _XlrdReader

class CustomReader(_OpenpyxlReader):
    # 新增file_rows_needed参数,保持与父类方法签名一致
    def get_sheet_data(self, sheet, convert_float: bool, file_rows_needed) -> List[List[Scalar]]:
        data = []
        for row in sheet.rows:
            first = row[1] # 仅检查该单元格的删除线格式
            if first.value is not None and first.font.strike: 
                continue
            data.append([self._convert_cell(cell, convert_float) for cell in row])
        return data

class CustomExcelFile(pd.ExcelFile):
    _engines = {"xlrd": _XlrdReader, "openpyxl": CustomReader, "odf": _ODFReader}

说明

  • 新版本pandas的BaseExcelReader类中,get_sheet_data方法新增file_rows_needed参数用于优化行数读取逻辑
  • 自定义方法必须保持与父类一致的参数列表,否则会触发参数不匹配的TypeError
  • 新增的参数无需在业务逻辑中使用,仅需在方法签名中声明即可,完全不影响原有的删除线判断逻辑

内容的提问来源于stack exchange,提问作者Kaschmir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 20:05:23