简体   繁体   中英

In Python, is there a library to set/update the value of one Excel cell based on its name?

I have an Excel file with several named cells . I want to update these cells with a new value. Instead of using the coordinates: worksheet["D3"] = "New Excel Value" . I would like to set it with its named value: worksheet["cell name"] = "New Excel Value" .

What I have seen is that xlwings has a function to set the cell based on its named value. But xlwings requires Excel to be installed on the machine, which is not the case for our machine. Therefore I am looking at openpyxl. I have seen solutions that work such as 1 and 2 . Both require an extra function with some manual steps to retrieve the single named cell. I expected to see the retrieval in the same way as with normal coordinates with square brackets. Which gives me the feeling that I missed something in the documentation.

Therefore I would like to know, is the best way to set the values of named cells the solution proposed in " Is there a way to save data in named Excel cells using Python? " or does openpyxl offer a function for it?

-- Edit --

The best that I could come up with is the code snippet below. I'll post it here, in case it would help anyone:

    def _set_value_for_excel_named_cell(self, cell_name: str, value: Any) -> None:
    """Sets a value for the Excel cell based on its name."""
    worksheet_title, cell_coordinates = list(
        self._workbook.defined_names[cell_name].destinations
    )[0]
    self._workbook[worksheet_title][cell_coordinates] = value

You can create your own class and use the setitem and getitem methods to create that interface yourself by wrapping openpyxl. Using the resources you've already linked to, I've create a working example to help you get started.

from openpyxl import load_workbook

filename = "test.xlsx"


class XLWrap:
    def __init__(self, wb):
        self.wb = wb

    def __getitem__(self, key):
        # Returns the value for cells given set name
        return [
            self.wb[sheet][cell].value
            for sheet, cell in list(self.wb.defined_names[key].destinations)
        ]

    def __setitem__(self, key, dat):
        # Sets the value for cells in workbook given set name
        cells = self.wb.defined_names[key].destinations
        for sheet, cell in cells:
            ws = self.wb[sheet]
            ws[cell] = dat
        self.save()

    def save(self):
        self.wb.save(filename)


wb = load_workbook(filename)
xlw = XLWrap(wb)
print(xlw["test"])
xlw["test"] = "named_cell_val_after"
print(xlw["test"])

Output:

['named_cell_val_before']
['named_cell_val_after']

The above will not work for a range of cells. It is possible to create a wrapper to handle different types of output for named ranges which are noted in the docs .

they are very loosely defined. They might contain a constant, a formula, a single cell reference, a range of cells or multiple ranges of cells across different worksheets. Or all of the above.

So the relevant implementation will be reliant on how you're using them. For ranges of cells, I have this quick and dirty working example which then quickly falls apart if you have single cell definitions:

def __getitem__(self, key):
    # Returns the value for cells given set name
    sheets = [
        self.wb[sht][rng]
        for sht, rng in list(self.wb.defined_names[key].destinations)
    ]
    values = []
    for sheet in sheets:
        for row in sheet:
            for cell in row:
                values.append(cell.value)
    return values

def __setitem__(self, key, dat):
    # Sets the value for cells in workbook given set name
    sheets = [
        self.wb[sht][rng]
        for sht, rng in list(self.wb.defined_names[key].destinations)
    ]
    for sheet in sheets:
        for row in sheet:
            for cell in row:
                cell.value = dat
    self.save()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM