pythonlibreoffice-calcuno

Changing row-height and column-width in LibreOffice Calc using Python3


I want to write a LibreOffice Calc document from within a Python3 program. Using pyoo I can do almost everything I want, including formatting and merging cells. But I cannot adjust row heights and column widths.

I found Change the column width and row height very helpful, and have been experimenting with it, but I can't seem to get quite the result I want. My present test file, based on the answer mentioned above, looks like this:

#! /usr/bin/python3

import os, pyoo, time, uno

s = '-'
while s != 'Y':
    s = input("Have you remembered to start Calc? ").upper()

os.popen("soffice --accept=\"socket,host=localhost,port=2002;urp;\" --norestore --nologo --nodefault")
time.sleep(2)
desktop = pyoo.Desktop('localhost', 2002)
doc = desktop.create_spreadsheet()

class ofic:
    sheet_idx = 0
    row_num = 0
    sheet = None

o = ofic()

uno_localContext = uno.getComponentContext()
uno_resolver = uno_localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", uno_localContext )
uno_ctx = uno_resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )
uno_smgr = uno_ctx.ServiceManager
uno_desktop = uno_smgr.createInstanceWithContext( "com.sun.star.frame.Desktop", uno_ctx)
uno_model = uno_desktop.getCurrentComponent()
uno_controller = uno_model.getCurrentController()
uno_sheet_count = 0

doc.sheets.create("Page {}".format(1), index=o.sheet_idx)
o.sheet = doc.sheets[o.sheet_idx]
o.sheet[0, 0].value = "The quick brown fox jumps over the lazy dog"
o.sheet[1, 1].value = o.sheet_idx

uno_controller.setActiveSheet(uno_model.Sheets.getByIndex(uno_sheet_count))
uno_sheet_count += 1
uno_active_sheet = uno_model.CurrentController.ActiveSheet
uno_columns = uno_active_sheet.getColumns()
uno_column = uno_columns.getByName("B")
uno_column.Width = 1000

The main problem with the above is that I have 2 Calc documents on the screen, one of which is created before the Python program gets going; the other is created from Python with a pyoo function. The first document gets the column width change, and the second receives the text input etc. I want just the second document, and of course I want the column width change applied to it.

I am sure the answer must be fairly straightforward, but after hours of experimentation I still can't find it. Could someone point me in the right direction, please?


Solution

  • Your code alternates between pyoo and straight Python-UNO, so it's no wonder that it's giving messy results. Pick one or the other. Personally, I use straight Python-UNO and don't see the benefit of adding the extra pyoo library.

    the other is created from Python with a pyoo function

    Do you mean this line of code from your question, and is this the "second document" that you want the column change applied to?

    doc = desktop.create_spreadsheet()
    

    If so, then get objects from that document instead of whichever window the desktop happens to have selected.

    controller = doc.getCurrentController()
    sheets = doc.getSheets()
    

    Or perhaps you want the other document, the one that didn't get created from Python. In that case, grab a reference to that document before creating the second one.

    first_doc = uno_desktop.getCurrentComponent()
    second_doc = desktop.create_spreadsheet()
    controller = first_doc.getCurrentController()
    sheets = first_doc.getSheets()
    

    If you don't have a reference to the document, you can find it by iterating through the open windows.

    oComponents = desktop.getComponents()
    oDocs = oComponents.createEnumeration()
    

    Finally, how to resize a column. The link in your question is for Excel and VBA (both from Microsoft), so I'm not sure why you think that would be relevant. Here is a Python-UNO example of resizing columns.

    oColumns = oSheet.getColumns()
    oColumn = oColumns.getByName("A")
    oColumn.Width = 7000
    oColumn = oColumns.getByName("B")
    oColumn.OptimalWidth = True