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)
Related
I'm trying to apply styles to cells in my excel files using the openpyxl library. If I try this (using an existing style and modifying it):
import openpyxl
wkbk = openpyxl.load_workbook('example.xlsx')
views_sheet = wkbk['Sheet']
cell_ = views_sheet.cell(row=4,column=3)
cell_.style = '20 % - Accent1'
bd = openpyxl.styles.Side(color=openpyxl.styles.colors.Color(theme=29))
cell_.border = openpyxl.styles.Border(left=bd, top=bd, right=bd, bottom=bd)
cell_.font = openpyxl.styles.Font(name='Calibri',size=11,bold=False,italic=False,vertAlign=None,underline='none',strike=False)
wkbk.save('example.xlsx')
I open 'example.xlsx' I get that my file is corrupted/needs to be restored. I thought that maybe it isn't possible writing over some existing style, so I created a new named style "highlight" with the associated color:
highlight = openpyxl.styles.NamedStyle(name="highlight")
highlight.fill = openpyxl.styles.PatternFill(bgColor=openpyxl.styles.colors.Color(theme=30),fill_type='shaded',patternType='lightGray')
bd = openpyxl.styles.Side(color=openpyxl.styles.colors.Color(theme=29))
highlight.border = openpyxl.styles.Border(left=bd, top=bd, right=bd, bottom=bd)
highlight.font = openpyxl.styles.Font(name='Calibri',size=11,bold=False,italic=False,vertAlign=None,underline='none',strike=False)
wkbk.add_named_style(highlight)
cell_.style = 'highlight'
But then I keep getting a ValueError indicating that I need to provide a value for parameter 'patternType' of class 'PatternFill'. This clearly does not makes sense.
Maybe I'm doing this wrong (it's hard to follow the documentation; had to look up older analogous implementations/snippets). Would appreciate some help.
Thank you!
I realize this is very late, but I had a similar issue where openpyxl was corrupting my .xlsx files when I tried to write a Pandas dataframe to an Excel workbook. The issue turned out to be that the workbook had some other tabs with formulas in certain cells, and for some reason the formulas get corrupted when openpyxl runs. I don't understand why, but the "fix" is to remove the formulas (so, hardcode anything you can).
I'm trying to automate Excel reports, and I'd prefer users didn't try to rename or reorder the worksheets. While I've had no problems protecting individual cells using xlsxwriter, I've failed to see an option to protect the workbook itself. I'm looking to openpyxl, but the tutorial does not seem to have any effect.
Edit: I'm now using this block of code, but does neither produce an error or protect my workbooks.
from openpyxl import load_workbook
from openpyxl.workbook.protection import WorkbookProtection
workbook = load_workbook(filepath, read_only=False, keep_vba=True)
workbook.security = WorkbookProtection(workbookPassword = 'secret-password', lockStructure = True)
workbook.save(filepath)
By the way, I am dealing with .xlsm files. If there are any solutions or points that I've missed, please let me know.
From this code:
from openpyxl.workbook.protection import WorkbookProtection
myWorkbook.security = WorkbookProtection(workBookPassword = 'super-secret-password', lockStructure = True)
myWorkbook.save(filepath)
Change:
WorkbookProtection(workBookPassword = 'super-secret-password', lockStructure = True)
to:
WorkbookProtection(workbookPassword = 'super-secret-password', lockStructure = True)
workBookPassword should be workbookPassword
Tested on Python32 3.8 and OpenPyXL version 3.0.2
Xlsxwriter has the option to protect the workbook with the command worksheet.protect() (have a look at the documentation: https://xlsxwriter.readthedocs.io/worksheet.html )
However take into consideration this:
Worksheet level passwords in Excel offer very weak protection. They do
not encrypt your data and are very easy to deactivate. Full workbook
encryption is not supported by XlsxWriter since it requires a
completely different file format and would take several man months to
implement.
Try using xlwings
import xlwings as xw
wb = xw.Book(r'<path_to_.xlsx file>')
wb.save(password='<your_password>', path=r'<path_to_save_.xlsx file>')
You'll probably laugh at me, but I am sitting on this for two weeks. I'm using python with pandas.
All I want to do, is to put a calculated value in a pre-existing excel file to a specific cell without changing the rest of the file. That's it.
Openpyxl makes my file unusable (means, I can not open because it's "corrupted" or something) or it plainly delets the whole content of the file. Xlsxwriter cannot read or modify pre-existing files. So it has to be pandas.
And for some reason I can't use worksheet = writer.sheets['Sheet1'], because that leads to an "unhandled exception".
Guys. Help.
I tried a bunch of packages but (for a lot of reasons) I ended up using xlwings. You can do pretty much anything with it in python that you can do in Excel.
Documentation link
So with xlwings you'd have:
import xlwings as xw
# open app_excel
app_excel = xw.App(visible = False)
# open excel template
wbk = xw.Book( r'stuff.xlsx' )
# write to a cell
wbk.sheets['Sheet1'].range('B5').value = 15
# save in the same place with the same name or not
wbk.save()
wbk.save( r'things.xlsx' )
# kill the app_excel
app_excel.kill()
del app_excel
Let me know how it goes.
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.
I want to insert a Image(object) in MS-Excel Report which i am generating using openpyxl utility. Is there a way to do it using some python utility?
Openpyxl allows you to write images into your Excel files! Here it is in the official documentation.
import openpyxl
wb = openpyxl.Workbook()
ws = wb.worksheets[0]
picture = openpyxl.drawing.Image('/path/to/picture')
picture.anchor(ws.cell('cell to put the image'))
ws.add_image(picture)
wb.save('whatever you want to save the workbook as')
This code of course refers to creating a new workbook and adding the image into it. To add the image to your preexisting workbook you would obviously just load that workbook using load_workbook.