使用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()

    
相关推荐
LOVE️YOU29 分钟前
Python 中 Tuple 为什么有时可 Hash,有时不可 Hash?
开发语言·python·哈希算法
李永奉42 分钟前
C语言-指针函数与函数指针及回调函数的使用
c语言·开发语言
小oo呆42 分钟前
【学习心得】迭代器和可迭代对象
开发语言·python
AC赳赳老秦1 小时前
采集行为合规自检:OpenClaw 自动校验 robots 协议与采集频率,规避违规采集风险
java·开发语言·c++·python·php·deepseek·openclaw
钱栈up1 小时前
mvn compile 卡死在 javac 阶段:一次类型不匹配的排查与修复
java·开发语言
迅猛龙办公室1 小时前
Python输出当前计算机的系统日期和时间
开发语言·前端·python
杨丰玮4181 小时前
C语言基础知识(一)————各类符号的含义与输入输出库(stdio)
c语言·开发语言
程序猿编码2 小时前
工业视觉多任务方案:可编程梯度信息视觉框架,训练评估 + C++ 部署完整实战
开发语言·c++·视觉·推理引擎
XiaoMaqqqq3 小时前
知名的IP驱动产业新场景新工具
网络·python·网络协议·tcp/ip
言乐63 小时前
Python实现语音审核模型
开发语言·python·django·virtualenv·pygame