excel 使用openpyxl进行排序

mpgws1up  于 2023-02-10  发布在  其他
关注(0)|答案(5)|浏览(712)

我正在尝试使用openpyxl从最小到最大排序列。我愿意使用其他库来完成这个任务。下面是我现在拥有的代码,但是,没有任何东西被排序。

from openpyxl import load_workbook

wb=load_workbook('NotSorted.xlsx')
ws1=wb.get_sheet_by_name('Mean')

ws1.auto_filter.add_sort_condition('J2:J21')

wb.save('Sorted.xlsx')

任何帮助是非常感谢!

2mbi3lxu

2mbi3lxu1#

您可以使用win32com.client进行排序(随pip install pypiwin32一起安装)。
名为MyWorkbook.xlsx的示例工作簿及其内容(之前和之后):
第一节第一节第一节第一节第一次

import win32com.client

excel = win32com.client.Dispatch("Excel.Application")

wb = excel.Workbooks.Open('MyWorkbook.xlsx')
ws = wb.Worksheets('Sheet1')

ws.Range('A2:A9').Sort(Key1=ws.Range('A1'), Order1=1, Orientation=1)

wb.Save()
excel.Application.Quit()

如果你不想改变原始工作簿,使用SaveAs()或者创建另一个工作簿并复制数据,如下所示:ws_from.Range("A1:AF100").Copy(ws_to.Range("A1:AF100"))(具有适当的范围)。
有关Sort()及其参数的详细信息,请参阅以下文档链接:

ocebsuys

ocebsuys2#

openpyxl documentation明确指出:
这会将相关指令添加到文件中,但实际上既不会过滤也不会排序。
因此,您需要计算新的行序列并显式移动数据(即,将单元格分配到新位置)。

svmlkihl

svmlkihl3#

openpyxl中似乎没有内置的排序函数,但是下面的函数可以根据一些条件对行进行排序:

def sheet_sort_rows(ws, row_start, row_end=0, cols=None, sorter=None, reverse=False):
""" Sorts given rows of the sheet
    row_start   First row to be sorted
    row_end     Last row to be sorted (default last row)
    cols        Columns to be considered in sort
    sorter      Function that accepts a tuple of values and
                returns a sortable key
    reverse     Reverse the sort order
"""

bottom = ws.max_row
if row_end == 0:
    row_end = ws.max_row
right = get_column_letter(ws.max_column)
if cols is None:
    cols = range(1, ws.max_column+1)

array = {}
for row in range(row_start, row_end+1):
    key = []
    for col in cols:
        key.append(ws.cell(row, col).value)
    array[key] = array.get(key, set()).union({row})

order = sorted(array, key=sorter, reverse=reverse)

ws.move_range(f"A{row_start}:{right}{row_end}", bottom)
dest = row_start
for src_key in order:
    for row in array[src_key]:
        src = row + bottom
        dist = dest - src
        ws.move_range(f"A{src}:{right}{src}", dist)
        dest += 1

在工作表中调用它,并从最小值开始排序。默认情况下,它将按顺序对所有列A ... max排序,但这可以通过传递一个"cols"列表来更改。例如,[4,2]将首先对D排序,然后对B排序。
与"sorted()"一样,可以使用"reverse"反转排序顺序。
如果你需要更复杂的排序,提供一个"sorter"函数。这个函数接收一个元组的值(来自"cols"列),并且应该返回一个可排序的键。
它的工作原理是确定每一行所需的最终目标,将它们全部向下移动到当前工作表之下,然后将它们移回所需的目标。
我希望每行中包含所有列,但是修改为移动较小的区域可以通过更改对ws. move_range()的两次调用来完成。
示例:

sheet_sort_rows(ws, 5, 10)  # Sort rows 5-10 using key: A, B, C, ...
sheet_sort_rows(ws, 5, 10, [2, 1])  # Sort rows using B, A
sheet_sort_rows(ws, 5, 10, [2, 1], reverse=True)  # As above in reverse

def sorter(t):
    return t[1] + " " + t[0][::-1]

sheet_sort_rows(ws, 5, 10, sorter=sorter)

最后一个按列B排序,然后按列A反向排序。

voj3qocg

voj3qocg4#

我尝试使用上面的sheet_sort_rows函数,但在array[key] = array.get(key, set()).union({row})上出现异常:列表不可散列(使用Python 3.10和Openpyxl 3.0.9)
作为一种解决方法,我使用键作为一个字符串(所有列值转换为str的concat)。不如最初的想法,并且不能使用排序器函数以默认顺序排序一些列,而以相反的顺序排序其他列。
最好能有原来的工作,但我没有线索(新的Python...)

ybzsozfc

ybzsozfc5#

Pandas似乎是一个很好的中间件

pip安装Pandas

import pandas as pd

df = pd.read_excel('input_file.xlsx')
df_sorted = df.sort_values('column_name_to_be_sorted')
df_sorted.to_excel('output_file.xlsx')

相关问题