Move a worksheet in a workbook using openpyxl or xl* or xlsxwriter?

我是研究僧i 提交于 2020-04-14 07:26:30

问题


I've read the docs for, openpyxl, xlwt, xlrd, xlutils, xlsxwriter. I don't find a way to move a sheet in an Excel workbook. Tests added a worksheet to the ends.

Concretely, I have a calendar of sorts, ['JAN','FEB',...,'DEC'] and I need to replace months as the need arises.

How do you order the sheets in an Excel workbook if you don't move them? Can you insert a sheet after or before a specified sheet?

Only one other post I can find on SO uses win32com and Book.Worksheets.Add(After=Sheet); seems strange none of these modules would have this method.

Default seems to add sheet at end of workbook. I could copy the destination file, until the updated sheet is reached, insert new sheet, and continue original copy to the end. (inspired by this post)


回答1:


I had two problems. The first problem was inserting a sheet at a given position. The second problem was moving a sheet around. Since I mostly deal with the newer Excel file xlsx, then I would be using openpyxl.

Various sources indicate new sheets are added to the end. I expected I would need to do this each time, and then move the sheet. I asked the question "(How to) move a worksheet..." thinking this was would solve both problems.

Ultimately, the first problem was easy once I finally found an example which showed workbook.create_sheet() method takes an optional index argument to insert a new sheet at a given zero-indexed position. (I really have to learn to look at the code, because the answer was here):

 def create_sheet(self, title=None, index=None):
        """Create a worksheet (at an optional index)
        [...]

Next. Turns out you can move a sheet by reordering the Workbook container _sheets. So I made a little helper func to test the idea:

def neworder(shlist, tpos = 3):
    """Takes a list of ints, and inserts the last int, to tpos location (0-index)"""
    lst = []
    lpos = (len(shlist) - 1)
    print("Before:", [x for x in range(len(shlist))])
    # Just a counter
    for x in range(len(shlist)):
        if x > (tpos - 1) and x != tpos:
            lst.append(x-1)
        elif x == tpos:
            lst.append(lpos)
        else:
            lst.append(x)

    return lst

# Get the sheets in workbook
currentorder = wb.sheetnames
# move the last sheet to location `tpos`
myorder = neworder(currentorder)

>>>Before: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]
>>>After : [0, 1, 2, 17, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

# get each object instance from  wb._sheets, and replace
wb._sheets = [wb._sheets[i] for i in myorder]

The first answer was not hard to spot in the openpyxl documentation once I realized what it did. Just a bit surprised more blogs didn't mention moving sheets around.




回答2:


Here's what I came up with (using openpyxl)

def move_sheet(wb, from_loc=None, to_loc=None):
    sheets=wb._sheets

    # if no from_loc given, assume last sheet
    if from_loc is None:
        from_loc = len(sheets) - 1

    #if no to_loc given, assume first
    if to_loc is None:
        to_loc = 0

    sheet = sheets.pop(from_loc)
    sheets.insert(to_loc, sheet)


来源:https://stackoverflow.com/questions/51082458/move-a-worksheet-in-a-workbook-using-openpyxl-or-xl-or-xlsxwriter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!