简体   繁体   English

使用 openpyxl 或 xl* 或 xlsxwriter 在工作簿中移动工作表?

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

I've read the docs for, openpyxl , xlwt , xlrd , xlutils , xlsxwriter .我已经阅读了 openpyxl 、 xlwt 、 xlrd 、 xlutils xlsxwriter文档 I don't find a way to move a sheet in an Excel workbook .我找不到在Excel 工作簿中移动工作表的方法。 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.具体来说,我有一个日历, ['JAN','FEB',...,'DEC'] ,我需要根据需要更换月份。

How do you order the sheets in an Excel workbook if you don't move them?如果不移动Excel 工作簿中的工作表,如何排序? 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) ; 我在 SO 上只能找到另一篇文章使用win32comBook.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 ) (灵感来自这篇文章

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.由于我主要处理较新的 Excel 文件xlsx ,因此我将使用 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.最终,第一个问题很容易,一旦我终于找到了一个示例,该示例显示workbook.create_sheet()方法采用可选的index参数在给定的零索引位置插入新工作表。 (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 .原来您可以通过重新排序 Workbook 容器_sheets来移动工作_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.一旦我意识到它做了什么,第一个答案就不难在 openpyxl 文档中找到。 Just a bit surprised more blogs didn't mention moving sheets around.只是有点惊讶更多的博客没有提到移动床单。

Here's what I came up with (using openpyxl)这是我想出的(使用 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)

My answer is for basic moving of sheets.我的答案是床单的基本移动。 I am using move_sheets function in openpyxl我在 openpyxl 中使用 move_sheets function

Say you have sheets named Sheet 1: "abc" and Sheet 2: "xyz" and you want to move xyz from 2nd position to first假设您有名为工作表 1:“abc”和工作表 2:“xyz”的工作表,并且您想将 xyz 从第二个 position 移动到第一个

import openpyxl as xl
wb = xl.load_worksheet("C:\\Users\\Desktop\\testfile.xlsx") #load worksheet using the excel file path, make sure you load the file from correct path
wb.active = 1 #the sheet index starts from 0 , hence 1 will select the second sheet ie xyz
wb.move_sheet(wb.active, offset = -1) #this will offset the current active sheet which is xyz be one position to the left which in our case is 1st position
wb.save(//path where you want to save the file.xlsx)

Complement to xtian solution, with option to move the worksheet from any position to any place forward or backwards. xtian解决方案的补充,可选择将工作表从任何位置向前或向后移动到任何位置。

from pathlib import Path
from openpyxl import load_workbook


def neworder(file, fpos, tpos):
    """Takes a list of ints, and inserts the fpos (from position) int, to tpos (to position)"""
    wb = load_workbook(filename=file)
    shlist = wb.sheetnames  # get current order sheets in workbook
    lst = []
    lpos = (len(shlist) - 1) # last position
    if lpos >= fpos > tpos >= 0:  # move from a high to low position
        for x in range(lpos+1):
            if x == tpos:
                lst.append(fpos)
            elif tpos < x <= fpos:
                lst.append(x-1)
            else:
                lst.append(x)
    if lpos >= tpos > fpos >= 0:  # move from a low to high position
        for x in range(lpos+1):
            if x == tpos:
                lst.append(fpos)
            elif fpos <= x < tpos:
                lst.append(x+1)
            else:
                lst.append(x)
    wb._sheets = [wb._sheets[i] for i in lst]  # get each object instance from  wb._sheets, and replace
    wb.save(filename=file)
    return


filex = Path('C:/file.xlsx')
neworder(filex, 83, 12)  # move worksheet in 83rd position to 12th position

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM