使用python在不改变原有excel的格式下,修改指定单元格格式

需求

有一个账单,需要生成一个副本,但是需要将交易员列隐藏,不能改变原有的格式

xlsx的文件容易实现,使用openpyxl实现

xls的文件使用xlrd+xlutil实现

参考了https://segmentfault.com/q/1010000008270267

python 复制代码
class GenCopyReport(object):
    """生成账单备份,删除交易员列
    """
    def __init__(self, filename, broker_code) -> None:
        self.filename = filename
        self.broker_code = broker_code
        self.file_type = filename.split(".")[-1]

    def remove_col(self, content, sheet_name, col_name, skiprows):
        """删除指定sheet页指定列

        :param content: 二进制文件
        :param sheet_name: sheet 页名
        :param col_name: 列名
        :param skiprows: 列名所在行
        :raises ValueError: 异常
        :return: bytes | None
        """
        # 判断文件格式是 .xls 还是 .xlsx
        if self.file_type == "xls":
            # 处理 .xls 文件
            return self.remove_col_xls(content, sheet_name, col_name, skiprows)
        elif self.file_type == "xlsx":
            # 处理 .xlsx 文件
            return self.remove_col_xlsx(content, sheet_name, col_name, skiprows)
        else:
            raise ValueError("Unsupported file format")

    def copy2(self, wb):
        w = XLWTWriter()
        process(XLRDReader(wb, 'unknown.xls'), w)
        return w.output[0][1], w.style_list
    def remove_col_xls(self, content, sheet_name, col_name, skiprows):
        """支持xls后缀的处理方法

        :param content: 二进制
        :param sheet_name: sheet页名
        :param col_name: 列名
        :param skiprows: 列名所在行号
        :return: bytes | None
        """
        # 打开 Excel 文件,保留格式信息
        workbook = open_workbook(file_contents=content, formatting_info=True, on_demand=True)

        # 选择指定的 sheet
        sheet = workbook.sheet_by_name(sheet_name)

        # 找到需要删除的列索引
        for col_idx in range(sheet.ncols):
            if sheet.cell_value(skiprows-1, col_idx) == col_name:
                trader_col = col_idx
                break
        else:
            trader_col = None

        # 如果找到了需要删除的列,则删除该列
        if trader_col is not None:
            # 创建一个可编辑的 workbook 副本,并保留原文件的格式属性
            wb, s = self.copy2(workbook)
            wbs = wb.get_sheet(sheet_name)
            # styles = s[sheet.cell_xf_index(row_idx, trader_col)]

            # 删除指定列
            for row_idx in range(sheet.nrows):
                if row_idx == skiprows-1:
                    wbs.write(row_idx, trader_col, "备注", s[sheet.cell_xf_index(row_idx, trader_col)])
                else:
                    wbs.write(row_idx, trader_col, '', s[sheet.cell_xf_index(row_idx, trader_col)])

            # 保存修改后的 Excel 文件
            output_buffer = io.BytesIO()
            wb.save(output_buffer)
            return output_buffer.getvalue()
        else:
            return None

    def remove_col_xlsx(self, content, sheet_name, col_name, skiprows):
        """支持xlsx后缀的处理方法

        :param content: 二进制
        :param sheet_name: sheet页
        :param col_name: 列名
        :param skiprows: 列名所在行
        :return: bytes | None   如果没找到指定列,则返回None
        """
        # 从文件内容打开 Excel 工作簿
        input_buffer = io.BytesIO(content)
        wb = load_workbook(filename=input_buffer)

        # 选择指定的 sheet
        ws = wb[sheet_name]

        # 找到需要删除的列索引
        for col_idx, cell in enumerate(ws[skiprows], start=1):
            if cell.value == col_name:
                break
        else:
            return None
        # 删除指定列
        for row in range(1, ws.max_row + 1):
            cell = ws.cell(row=row, column=col_idx)
            if cell.coordinate in ws.merged_cells:
                # 如果是合并单元格,则跳过
                continue
            if row == skiprows:
                cell.value = "备注"
            else:
                cell.value = ""
            # ws.cell(row=row, column=col_idx, value="")

        # 将修改后的工作簿保存到二进制 buffer 中
        output_buffer = io.BytesIO()
        wb.save(output_buffer)
        return output_buffer.getvalue()

    
相关推荐
鸡鸭扣1 小时前
Docker:3、在VSCode上安装并运行python程序或JavaScript程序
运维·vscode·python·docker·容器·js
paterWang2 小时前
基于 Python 和 OpenCV 的酒店客房入侵检测系统设计与实现
开发语言·python·opencv
东方佑2 小时前
使用Python和OpenCV实现图像像素压缩与解压
开发语言·python·opencv
我真不会起名字啊3 小时前
“深入浅出”系列之杂谈篇:(3)Qt5和Qt6该学哪个?
开发语言·qt
神秘_博士3 小时前
自制AirTag,支持安卓/鸿蒙/PC/Home Assistant,无需拥有iPhone
arm开发·python·物联网·flutter·docker·gitee
laimaxgg3 小时前
Qt常用控件之单选按钮QRadioButton
开发语言·c++·qt·ui·qt5
水瓶丫头站住3 小时前
Qt的QStackedWidget样式设置
开发语言·qt
Moutai码农4 小时前
机器学习-生命周期
人工智能·python·机器学习·数据挖掘
小钊(求职中)4 小时前
Java开发实习面试笔试题(含答案)
java·开发语言·spring boot·spring·面试·tomcat·maven
小白教程5 小时前
python学习笔记,python处理 Excel、Word、PPT 以及邮件自动化办公
python·python学习·python安装