python openpyxl insert_cols changes merge-cells and styles - python

I tried to insert a column into an excel.
However, the style of cells has been changed
CODE:
import openpyxl
wb = openpyxl.load_workbook('xt3.xlsx')
sheet = wb.worksheets[0]
sheet.insert_cols(0)
[enter image description here][1]wb.save("filename.xlsx")
https://i.stack.imgur.com/hl5QY.png
issues on bitbucket: https://bitbucket.org/openpyxl/openpyxl/issues/1098/bugs-insert_cols-changes-merge-cells-and

After some digging I wrote this code in openpyxl and xlrd/xlwt/xlutils.
Support both xls and xlsx.
Before
After
The key is to use copy and generate coordinate.
Code is here

This code will insert 3 columns; It keeps the background color but not all of the borders.
merged_cells_range = ws.merged_cells.ranges
for merged_cell in merged_cells_range:
merged_cell.shift(3,0)
ws.insert_cols(1,3)

Related

How to read the tab color of a worksheet with openpyxl

I have been writing a script using the openpyxl module for python 3.8.3. In my script I am taking a pre-existing excel workbook with multiple sheets. This sheet is coming from another person, and they want me to only run the script on the tabs that are colored with a specific color. I have been attempting to recognize what worksheets have the specified color by using the tabColor in sheet_properties, but that does not work for me. Any help is appreciated!
Here
def excel_modifications(file_path, storage_path):
initial_wb = load_workbook(file_path, data_only=True, read_only=True)
for ws in initial_wb:
if ws.sheet_properties.tabColor == "11217371":
common_compression(ws, storage_path)
To anyone who is encountering a similar problem to me I found my solution. The parameters within which is used by sheet_properties.tabColor contain both a 'rgb' parameter and a 'theme' parameter. In my case, the workbook tabs from the work book I worked on were colored by theme colors, not a rgb value chosen by the person writing the excel sheet. On my workbook, the writer colored their tab with the Accent 6 in the default theme colors. So for me, the solution was to look for the index of the given sheet_properties.tabColor.theme that is equal to 6, as by starting from zero, the color I was searching for was the 9th index on the list provided by excel.
Here is my working conditional fixing my problem above:
def excel_modifications(file_path, storage_path):
initial_wb = load_workbook(file_path, data_only=True, read_only=True)
for ws in initial_wb:
if ws.sheet_properties.tabColor.theme == 6:
common_compression(ws, storage_path)
Here is a screenshot from the listing discussed of Accents in excel:
Example Accent listing from excel

Inserting multiple images in Excel using OpenPyxel does not work

I'm trying to insert images with OpenPyxl to a Excel file that has already images in it (in different sheets in my case). If I do so, the existing images disappear.
Sample code:
import openpyxl
from openpyxl import load_workbook
wb = openpyxl.Workbook()
ws1 = wb.create_sheet("MySheet1")
img1 = openpyxl.drawing.image.Image('test1.png')
img1.anchor = ws1.cell(row=2, column=2).coordinate
ws1.add_image(img1)
wb.save('test_output.xlsx')
wb = load_workbook(filename='test_output.xlsx')
ws2 = wb.create_sheet("MySheet2")
img2 = openpyxl.drawing.image.Image('test2.png')
img2.anchor = ws2.cell(row=2, column=2).coordinate
ws2.add_image(img2)
wb.save('test_output.xlsx')
Is there anything I do wrong here?
Thanks alot in advance.
Update:
As stated in the comments this should work now:
Up until very recently images in existing files were not preserved.
You need >= 2.5.5 for this.
The doc states for older versions:
openpyxl does currently not read all possible items in an Excel file
so images and charts will be lost from existing files if they are
opened and saved with the same name.
There are several bug issues about this (here, here, here)
One comment in the issues is using win32com as a workaround to copy the sheet with the image to a different file.

How to get the value from merged cells in xlsx file using python?

I am trying to get the value from cell with row = 11 and column B and C. See screenshot for more clarification.
I tried following code using xlrd package but it does not print anything.
import xlrd
path = "C:/myfilepath/data.xlsx"
workbook = xlrd.open_workbook(path)
sheet = workbook.sheet_by_index(0)
sheet.cell_value(10,1)
sheet.cell_value(10,2)
I am not able to output the value from particular merged cells using xlrd package in python.
Above code should print the cell value i.e PCHGFT001KS
I don't know how xlrd works, but I do know how the lovely openpyxl works. You should use openpyxl! it's a robust tool for working with xlsx files. (NOT xls).
import openpyxl
wb = openpyxl.load_workbook(excel)
ws = wb[wb.get_sheet_names()[0]]
print(ws['B11'].value)
Extra:
If you want to unmerge those blocks you can do the following.
for items in ws.merged_cell_ranges:
ws.unmerge_cells(str(items))
wb.save(excel)

Formated column in openpyxls gets hidden. Is this a bug or a feature?

I am using the below code to format a file that was created using the latest version of MS Excel.
from openpyxl import load_workbook
from openpyxl.styles import Font, Fill
wb=load_workbook("test.xlsx")
ws = wb.active
col = ws.column_dimensions['B']
col.font = Font(bold=True)
wb.save("styled.xlsx")
When I run this code, column B which should be formated to bold text, instead gets hidden. This also applies for other styles that I tried. I also tried other columns and other excel files which were generated by pandas using the xlswriter engine.
My last resort was to try various versions of openpyxl, including the latest beta. They all behave in the same way for the above code.
So my question is, am I missing anything? All I want to do is format a column's content to bold text column wise (not cell wise).

Insert Image on Worksheet's Header/Footer using OpenPyXL

I'm creating a small app in Django that produces a Excel report using openpyxl library. Got stuck while trying to insert an image in the header / footer section. The documentation here roughly talks about inserting text (& ampersand codes). Checked the source code, but no help there either.
I see XlsxWriter has this option. Would appreciate if someone could shed me light on how to pass image's name/path in openxlpy or do I need to switch the library?
View.py
def get(self, request):
wb = Workbook()
ws = wb.active
# header & footer
ws.header_footer.center_header.text = '&G'
This is currently not possible in openpyxl, and unlikely ever to be so unless someone else contributes the code. Therefore, you may have to switch to using xlsxwriter.
NB. adding it would also involve preserving images from existing files, which is one of the things that makes this so challenging. We open to add general support for reading images in openpyxl 2.5
In openpyxl you can add an image (inserted into some_cell) to a worksheet by doing the following:
wb = openpyxl.Workbook()
ws = wb.add_worksheet() #or wb.active
your_image = openpyxl.drawing.Image(path_to_image)
your_image.anchor(ws.cell(some_cell))
ws.add_image(your_image)
wb.save(your_filename.xlsx)

Categories