格式化单元格时如何有效地访问openPyXL中的单个单元格(更好的运行时)

时间:2020-01-27 19:14:20

标签: python border openpyxl

我目前正在从事将Excel文件转换为AODA兼容且格式更好的版本的项目。

其中一项功能是在桌子上设置边框。它当前访问单个单元格,确定角和页眉以应用粗边框,并且内部的任何内容都较薄。

我已经附加了代码,但是对于包含大约355K单元的工作表,此代码的运行时间为45秒。有点慢。我怎样才能更快呢?

... other functions

def setBorder(sh, sheetRange, emptyRowList):
    cellRange = getNewSheetRange(False, sheetRange, emptyRowList)
    print("cR: ", cellRange)
    rows = sh[cellRange]

    # gets the header row
    DataRow = getRow(sheetRange['beginData'])
    HeaderRow = getRow(sheetRange['beginHeader'])

    # formats headers with thick borders
    headerRow = DataRow - HeaderRow
    print("hR:", headerRow)

    borderHeight = 25

    hair = Side(border_style='hair', color='d3d3d3')
    thick = Side(border_style='thick', color='a9a9a9')
    alignV = Alignment(vertical='center')
    # alignH = Alignment(horizontal='center')
    align = Alignment(vertical='center', horizontal='center')

    maxRow = len(rows)  # index of the last row
    # print("MaxRow", maxRow)
    for row, cells in enumerate(rows, 1):
        # print("PosRow, cells: ", row, cells)
        maxCol = len(cells)  # index of the last cell
        # print("MaxCol", maxCol)
        for col, cell in enumerate(cells, 1):
            # print("PosCol, cell: ",  col, cell)

            sh.row_dimensions[cell.row].height = borderHeight
            cell.alignment = alignV

            if col != 1:
                cell.alignment = align

            border = Border(
                left=hair,
                right=hair,
                top=hair,
                bottom=hair
            )

            # applies thick border on corners
            if col == 1:
                border.left = thick
            if col == maxCol:
                border.right = thick
            if row == 1:
                border.top = thick
            if row == maxRow:
                border.bottom = thick
            # applies thick border on header rows
            if row == headerRow:
                border.top = thick
                border.bottom = thick
                cell.font = Font(bold=True)

            cell.border = border

    sh.row_dimensions[sh.max_row + 1].height = borderHeight


def convertSheet(sh, sheetRange):
    mergedRangeList = sh.merged_cells.ranges  # detect all merge cells and get the merge range
    mergeCount = len(mergedRangeList)  # count number of merged cells

    # store the mergeRangeList before it gets unmerged
    newMergedRangeList = []

    # un-merges merged cells
    counter = mergeCount
    while counter > 0:
        newMergedRangeList.append(mergedRangeList[counter - 1])
        sh.unmerge_cells(str(mergedRangeList[counter - 1]))
        counter -= 1

    # returns list of empty rows while writing "No Data" and "End of Column" appropriately
    emptyRowList = checkEmptyRows(sh, sheetRange)

    # deletes empty rows from emptyRowList
    deleteEmptyRows(sh, emptyRowList)

    # sets the border around Data Segment
    borderTop = getRow(sheetRange['beginHeader'])
    borderBottom = getRow(sheetRange['endData'])
    print("Border T/B: ", borderTop, borderBottom)

    # copies merged cell value across the range
    populateGroups(sh, newMergedRangeList, mergeCount, emptyRowList, borderTop, borderBottom)

    # inserts Screen Reader messages
    insertScreenReader(sh, sheetRange)

    # formats table into a Table format with the correct header
    convertTable(sh, sheetRange, emptyRowList)

    # formats whole table with borders
    start = timeit.default_timer()
    setBorder(sh, sheetRange, emptyRowList)
    stop = timeit.default_timer()
    print('Time: ', stop - start)

... main

0 个答案:

没有答案