[英]Python Openpyxl - Modify excel file and its value
我得到一個導出的 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 個 ProductItems x 110 個位置...
我的想法是在左邊插入一個列,它會是空的,然后將 ProductItem name 的名稱復制到每一行,如下所示:
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 解決這個問題嗎? 謝謝
此示例根據您之前的圖像生成請求的格式,並包括原始工作表中未更改的第 1 -4 行。
基本上,代碼循環遍歷第 5 行中的行,即 header 行中 B 列、C、D 和 E 中的數據。它將每個范圍從 A 到 E 移動 1,以便 A 列為空,並設置使用變量“colA_val”將該行的 A 列中的值更改為最新確定的“ProductItems”的值。
“ProductItems”由變量“num_indent”設置的單元格文本中的前導空格確定。 從圖片來看有1個前導空間。 如果有更明確的方法來確定“ProductItems”行,則可以更改此部分。
以下步驟可選
...
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
from openpyxl.styles import Border, Side
filename = "openpyxl2.xlsx"
# Open workbook and select sheet
wb = load_workbook(filename)
ws = wb.active
### Loop the cells
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
num_indent = 1 # How many leading spaces for the 'ProductItems' cell
for row in ws.iter_rows(min_row=5, max_row=ws.max_row):
cur_row =row[0].row
row_colA_value = row[0].value
### If this is a row with data
if row_colA_value is not None:
### Determine if 'ProductItems' row from the leading spaces, set by 'num_indent'
leading_spaces = len(row_colA_value) - len(row_colA_value.lstrip(' '))
### Is current row a ProductItems row, if so get details and delete row
if leading_spaces == num_indent:
### One off row 5 header adjustment and column widths collection
if not col_width:
### Adjust header row 5 one column across
ws.move_range(f'A{cur_row - 1}:E{cur_row - 1}', cols=1)
### Get column dimensions
for x in range(ws.max_column-1):
col_width[row[x].column] = ws.column_dimensions[row[x].column_letter].width
### Get next ProductItem name
colA_val = row_colA_value.lstrip()
### Delete the row the ProductItem was on
ws.delete_rows(cur_row)
### move name, units, sales etc cells 1 column across
ws.move_range(f'A{cur_row}:E{cur_row}', cols=1)
### Enter the ProductItem name into cell in column A
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 Text and Border to header section cell B5
ws.cell(row=5, column=2).value = 'Enter text here'
med_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 = med_border
wb.save('out_' + filename)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.