Python Openpyxl -修改excel文件及其值

mwkjh3gx  于 2022-12-02  发布在  Python
关注(0)|答案(1)|浏览(238)

我得到一个导出的Excel文件,其中显示了ProductItems、位置和一些销售数字。
现在,问题是ProductItems和Locations都在一列中,稍微缩进,如下所示:

ProductItem_1
   Location_a | Quantity  | Price
   Location_b | Quantity  | Price
   Location_c | Quantity  | Price
   (110 locations total)
ProductItem_2
   Location_a | Quantity  | Price
   Location_b | Quantity  | Price
   Location_c | Quantity  | Price
ProductItem_1
   Location_a | Quantity  | Price
   Location_b | Quantity  | Price
   Location_c | Quantity  | Price

....等等...例如150个产品项目x 110个位置...
我的想法是在左边插入一个Column,它会是空的,然后把ProductItem的名称复制到每一行,就像这样:

ProductItem_1 | Location_a | QuantityVal  | PriceVal
ProductItem_1 | Location_b | QuantityVal  | PriceVal
ProductItem_1 | Location_c | QuantityVal  | PriceVal
ProductItem_2 | Location_a | QuantityVal  | PriceVal
ProductItem_2 | Location_b | QuantityVal  | PriceVal
ProductItem_2 | Location_c | QuantityVal  | PriceVal
ProductItem_3 | Location_a | QuantityVal  | PriceVal
ProductItem_3 | Location_b | QuantityVal  | PriceVal
ProductItem_3 | Location_c | QuantityVal  | PriceVal

我该怎么做呢?我附上了一个Excel文件的截图......有什么想法如何用Python中的Openpyxl来解决这个问题吗?谢谢

期望的结果如下所示:

k3bvogb1

k3bvogb11#

本示例根据之前的图像生成所需的格式,并包括原始工作表中的第1 - 4行(未更改)。
基本上,该代码从第5行开始遍历各行,该行是列B、C、D和E中数据的标题行。它将从A到E的每个范围移动1,以便列A为空,并将该行的列A中的值设置为先前在单元格A6 help中的值(在变量'colA_val'中)。

    • 对于第5行**;标题移至C、D、E和F列。单元格A5的值设置为'colA_val',但由于此时该单元格为空,因此该单元格保持为空。单元格B5设置了外框,但没有文本。
    • 对于第6行**;该行最终不再需要,将被删除。代码利用此机会将变量'colA_val'更新为列A中的值,该值将成为在列A中为其余行输入的文本。此外,由于行数据将移动1列,因此将收集现有列宽,以便将这些列宽重新应用于新列中的数据。最后,删除第6行。
    • 后续行**;将列B-E中的数据移动到C-F,并将"colA_val"值输入空的列A单元格。

以下步骤是可选的
1.数据移动1列后,使用循环应用1列宽,这样标题保持与以前相同的宽度。A列的宽度略有减小,因为B列中的文本宽度较大。
1.标题行中的单元格B5添加了外框。该单元格不包含文本,因为问题中未指定。
...

from openpyxl import load_workbook
 from openpyxl.utils import get_column_letter
 from openpyxl.styles import Border, Side

 filename = "foo.xlsx"

 # Open workbook and select sheet
 wb = load_workbook(filename)
 ws = wb.active

 ### Loop the
 colA_val = '' # Hold the text value to enter in to Col A
 col_width = {} # This dict holds the column dimenions so the col widths can be readjusted
 for row in ws.iter_rows(min_row=5, max_row=ws.max_row-1):
     cur_row =row[0].row
     ### Row 6 is not needed any more, use this for a one time collection of info like
     ### the text to enter into column A, dimensions of the columns to reset after
     ### inserting the extra column and to delete row 6
     if cur_row == 6:
         for x in range(ws.max_column-1):
             col_width[row[x].column] = ws.column_dimensions[row[x].column_letter].width
         colA_val = row[0].value
         ws.delete_rows(cur_row)

     ws.move_range(f'A{cur_row}:E{cur_row}', cols=1)
     ws.cell(row=cur_row, column=1).value = colA_val

 ### Reset the column widths using the sizes saved in the col_width dictionary
 for c, d in col_width.items():
     ### Adjust Column A to be a little smaller than before
     if c == 1:
         ws.column_dimensions['A'].width = d - 10
     ### Set the columns to the same width as before
     ws.column_dimensions[get_column_letter(c + 1)].width = d

 ### Add Border to header section cell B5
 thin_border = Border(left=Side(style='medium'),
                      right=Side(style='medium'),
                      top=Side(style='medium'),
                      bottom=Side(style='medium'))
 ws.cell(row=5, column=2).border = thin_border

 wb.save('out_' + filename)

相关问题