46668

[code]

    import openpyxl as opx
    from openpyxl.styles import Border, Side
    
    wb = opx.Workbook()
    ws = wb.active
    
    side_medium = Side(border_style='medium', color='ff000000')
    side_dotted = Side(border_style='dotted', color='ff000000')
    side_thin = Side(border_style='thin', color='ff000000')
    
    cl = ws.cell(2,2)
    cl.border = cl.border + Border(top=side_medium, left=side_dotted, right=side_dotted, bottom=side_medium)
    cl.border = cl.border + Border(left=side_thin)
    
    wb.save(r'C:\Users\....\test.xlsx')
    
[/code]

上記コードが期待通りに動きません。  
１回目の"cl.border= " で、cell(2,2) の４辺はそれぞれ期待した罫線になりますが、  
２回目の"cl.border= " では、左辺が thin に上書きされるはずが、dotted のままです。  
２回目の上書きを期待通りに反映させるにはどうすればいいのでしょうか。


CC BY-SA 4.0
2018-07-17T01:11:10.677
46660
2018-07-17T03:55:04.223
2018-07-17T02:12:18.390
19110
10536
question
python openpyxl
Border で上書きしても反映されない？


デバッガで動作を追ってみました。

Borderの`+`演算で、各Sideオブジェクトの値をマージする際に、  
左側(`cl.border`)、右側(`Border(left=side_thin)`)の対応するSideオブジェクトを比較するのですが、  
両方に`boder_style`に値が設定されている場合、左側(`cl.border`)が採用されるようです。

[code]

    cl.border + Border(left=side_thin) # 両方オペランドのSideにsytleがある場合、左を採用
    
[/code]

そのため、左右入れ替えると意図通りになります。

[code]

    Border(left=side_thin) + cl.border
    
[/code]

ただし、`cl.border`は、`StyleProxy`型になっているため、  
そのまま`+`するとエラーとなりますので、`copy`して`Border`型に変換してから  
`+`すると上手く行くと思います。

[code]

    from copy import copy
    # ...略...
    cl.border = Border(left=side_thin) + copy(cl.border)
    
[/code]


CC BY-SA 4.0
2018-07-17T03:47:11.947
46668
2018-07-17T03:55:04.223
2018-07-17T03:55:04.223
46660
answer