在openpyxl中,如何使用格式化,合并单元格,公式和超链接移动或复制单元格区域

时间:2017-07-27 09:53:56

标签: python excel openpyxl

我正在尝试使用Python 2.7 + openpyxl在工作表中移动单元格范围。似乎是一项简单而基本的任务,结果几乎是不可能的。以下是我希望在Excel中查看的内容:

Excel copying pasting

为了使任务更容易,我们假设我只需要将范围从给定单元格移动到数据末尾(到最后一行和一列)。我的第一个想法很简单:

for i, column in enumerate(columns):
    if i >= starting_col:
        for j, cell in enumerate(column):
            if j >= starting_row:
                copy_cell(ws, j+1, i+1, j+1, i+movement)

但是,嘿,如何有效地完全实现copy_cell? 通过反复试验,我设法找到了我需要复制的4件事:

  1. 风格
  2. 超链接
  3. 数字格式
  4. 它没有像我预期的那样工作 - 大多数单元格被正确复制但是超链接似乎不起作用,复制.style属性也不起作用(因此我试图访问有效的_style)和我最糟糕的问题出现了 - 合并的细胞不等。怎么处理他们?我的copy_cell()目前看起来像这样:

    def copy_cell(ws, from_row, from_col, to_row, to_col):
        # first value
        ws.cell(row=to_row, column=to_col).value = ws.cell(row=from_row, column=from_col).value
        # second formatting
        from_style = ws.cell(row=from_row, column=from_col)._style
        ws.cell(row=to_row, column=to_col)._style = from_style
        ws.cell(row=to_row, column=to_col).hyperlink = ws.cell(row=from_row, column=from_col).hyperlink
        ws.cell(row=to_row, column=to_col).number_format = ws.cell(row=from_row, column=from_col).number_format
    

    复制全细胞范围是不是有更好的通用方法?或至少具有所有属性的整个单元格?如果没有,也许有一种有效的方法来移动或复制合并的单元格范围?

1 个答案:

答案 0 :(得分:1)

我已经构建了这种方法来复制单元格而不触及它们的内容:

def move_cell(source_cell, dest_row, dest_col, preserve_original=False):
    """
    :param source_cell: cell to be moved to new coordinates
    :param dest_row: 1-indexed destination row
    :param dest_col: 1-indexed destination column
    :param preserve_original: if True, does a copy instead of a move
    """
    if preserve_original:
        cell_to_move = copy.copy(source_cell)
    else:
        cell_to_move = source_cell

    worksheet = cell_to_move.parent
    source_address = (cell_to_move.row, cell_to_move.col_idx)
    dest_address = (dest_row, dest_col)

    cell_to_move.row = dest_row
    cell_to_move.col_idx = dest_col
    worksheet._cells[dest_address] = cell_to_move
    if not preserve_original:
        del worksheet._cells[source_address]

    return cell_to_move