所以我有excel文件,每个文件都有几张,我正在编写脚本,如果它们存在于文件中,它将从选定的工作表中收集数据并将其合并到一个大页面中。通常它正在工作,迭代文件,如果需要,它会找到包含数据的单元格范围并将其附加到数据框。我现在需要做的是将标题行(列名称)添加到Dataframe,但在表单中是多行标题。
为了使它在数据帧中看起来相同,我需要将顶部标题行中的单元格取消合并,并将值从第一个单元格复制到其余部分,并在之前合并的范围内。“
我正在使用OpenPyXL访问Excel工作表。我的函数接收工作表作为唯一参数。它看起来像这样:
def checkForMergedCells(sheet):
merged = ws.merged_cell_ranges
for mergedCell in merged:
mc_start, mc_stop = str(mergedCell).split(':')
cp_value = sheet[mc_start]
sheet.unmerge_cells(mergedCell)
cell_range = sheet[mergedCell]
for cell in cell_range:
cell.value = cp_value
问题是cell_range返回一个元组,最终会收到错误信息:
AttributeError:'tuple'对象没有属性'value' 下面你可以看到调试期间的screencap,它显示了每个变量中传递的值。
答案 0 :(得分:3)
通过索引访问通常会返回一个元组元组,除非您尝试获取单个单元格或行。要进行程序化访问,您应该使用iter_cols()
或utils
您可能希望花一些时间查看from openpyxl.utils import range_boundaries
for group in ws.merged_cell_ranges:
min_col, min_row, max_col, max_row = range_boundaries(group)
top_left_cell_value = ws.cell(row=min_row, column=min_col).value
for row in ws.iter_rows(min_col=min_col, min_row=min_row, max_col=max_col, max_row=max_row):
for cell in row:
cell.value = top_left_cell_value
模块。
$source_path = "/var/www/ci/htdocs/assets/images/";
echo str_replace(FCPATH, base_url(), $source_path);
答案 1 :(得分:1)
http://thequickblog.com/merge-unmerge-cells-openpyxl-in-python/中的以下代码对我有用。
import openpyxl
from openpyxl.utils import range_boundaries
wbook=openpyxl.load_workbook("openpyxl_merge_unmerge.xlsx")
sheet=wbook["unmerge_sample"]
for cell_group in sheet.merged_cells.ranges:
min_col, min_row, max_col, max_row = range_boundaries(str(cell_group))
top_left_cell_value = sheet.cell(row=min_row, column=min_col).value
sheet.unmerge_cells(str(cell_group))
for row in sheet.iter_rows(min_col=min_col, min_row=min_row, max_col=max_col, max_row=max_row):
for cell in row:
cell.value = top_left_cell_value
wbook.save("openpyxl_merge_unmerge.xlsx")
exit()
答案 2 :(得分:0)
在执行此操作之前,我遇到了错误和弃用警告:
from openpyxl.utils import range_boundaries
for group in sheet.merged_cells.ranges: # merged_cell_ranges deprecated
display(range_boundaries(group._get_range_string())) # expects a string instead of an object
min_col, min_row, max_col, max_row = range_boundaries(group._get_range_string())
top_left_cell_value = sheet.cell(row=min_row, column=min_col).value
for row in sheet.iter_rows(min_col=min_col, min_row=min_row, max_col=max_col, max_row=max_row):
for cell in row:
cell.value = top_left_cell_value
答案 3 :(得分:0)
以上答案均无效。 所以我详细说明了这一点,对其进行了测试,它对我有用。
from openpyxl.utils import range_boundaries
wb = load_workbook('Example.xlsx')
sheets = wb.sheetnames ##['Sheet1', 'Sheet2']
for i,sheet in enumerate(sheets):
ws = wb[sheets[i]]
# you need a separate list to iterate on (see explanation #2 below)
mergedcells =[]
for group in ws.merged_cells.ranges:
mergedcells.append(group)
for group in mergedcells:
min_col, min_row, max_col, max_row = group.bounds
top_left_cell_value = ws.cell(row=min_row, column=min_col).value
ws.unmerge_cells(str(group)) # you need to unmerge before writing (see explanation #1 below)
for irow in range(min_row, max_row+1):
for jcol in range(min_col, max_col+1):
ws.cell(row = irow, column = jcol, value = top_left_cell_value)
@ДмитроОлександрович几乎是正确的,但是我不得不更改一些内容以修正他的答案:
您将遇到一个AttributeError: 'MergedCell' object attribute 'value' is read-only
错误,因为在更改其值之前需要取消合并的单元格。 (请参见此处:https://bitbucket.org/openpyxl/openpyxl/issues/1228/unmerged-cells-are-still-considered-merged)
您无法直接在ws.merged_cells.ranges上进行迭代,因为在python中的“范围”列表对象中进行迭代并对其进行更改(例如,使用unmerge_cells
函数或pop
函数)将只更改一半的对象(请参见此处:https://bitbucket.org/openpyxl/openpyxl/issues/1085/unmerge-of-wsmerged_cell_ranges-works-but)。您需要创建一个不同的列表并对其进行迭代。