Python and openpyxl is saving my shared workbook as unshared

Question:

Using Python and openpyxl I have a code that goes into a workbook, adds a bunch of information to some cells every day, and then closes and saves it. My problem is that if this workbook is open the code doesn’t work (obviously).

By making the workbook shared(multiple users can edit at once) I can overcome this problem, however after the code runs once, python saves and then reverts it back to a closed, unshared workbook.
Anyone know if openpyxl can save as shared? I’m not finding anything online.
Pre-emptive thanks for your help.

Asked By: Fernando

||

Answers:

It seems that when openpyxl saves an Excel workbook, the docProps/app.xml file inside is wiped and contains only minimal information.

A quick (and dirty) solution is to use zipfile to get these information and transfer them into the new/saved file.

import zipfile, openpyxl

def shared_pyxl_save(file_path, workbook):
    """
    `file_path`: path to the shared file you want to save
    `workbook`: the object returned by openpyxl.load_workbook()
    """
    zin = zipfile.ZipFile(file_path, 'r')
    buffers = []
    for item in zin.infolist():
        buffers.append((item, zin.read(item.filename)))
    zin.close()

    workbook.save(file_path)

    zout = zipfile.ZipFile(file_path, 'w')
    for item, buffer in buffers:
        zout.writestr(item, buffer)
    zout.close()
Answered By: saexys

here’s my answer post on another page, but this page is the original

well… after playing with it back and forth, for some weird reason zipfile.infolist() does contains the sheet data as well, so here’s my way to fine tune it, using the shared_pyxl_save example the previous gentleman provided

basically instead of letting the old file overriding the sheet’s data, use the old one

def shared_pyxl_save(file_path, workbook):
    """
    `file_path`: path to the shared file you want to save
    `workbook`: the object returned by openpyxl.load_workbook()
    """
    zin = zipfile.ZipFile(file_path, 'r')
    buffers = []
    for item in zin.infolist():
        if "sheet1.xml" not in item.filename:
            buffers.append((item, zin.read(item.filename)))
    zin.close()

    workbook.save(file_path)
    """ loop through again to find the sheet1.xmls and put it into buffer, else will show up error"""
    zin2 = zipfile.ZipFile(file_path, 'r')
    for item in zin2.infolist():
        if "sheet1.xml" in item.filename:
            buffers.append((item, zin2.read(item.filename)))
    zin2.close()
    
    #finally saves the file
    zout = zipfile.ZipFile(file_path, 'w')
    for item, buffer in buffers:
        zout.writestr(item, buffer)
    zout.close()
    workbook.close()
Answered By: ah-shiang han
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.