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

    
相关推荐
databook11 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar13 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户83562907805113 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_13 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机20 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机21 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机21 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机21 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i21 小时前
drf初步梳理
python·django
每日AI新事件21 小时前
python的异步函数
python