OK, I got a realtime GUI "proof of concept" working on my Linux workstation.
It uses Python and Libre Office Calc and a web browser.
The spreadsheet is a text document in SYLK format. It is attached as input_file.slk
.
The Python script is attached as SylkRenderer.py
Save these files and open input_file.slk
in a text editor.
In a terminal window launch a headless instance of LibreOffice Calc with this command:
libreoffice --headless --invisible --accept="socket,host=localhost,port=2002;urp;"
In a separate terminal window run the python script:
python SylkRenderer.py
Wait a few seconds and a browser window will open that renders the spreadsheet like this:
A | B | C | D |
---|---|---|---|
1 | 2 | 3 | 6 |
4 | 5 | 6 | |
7 | 8 | 9 | |
18 |
In the text editor make a change to the .slk file. For example, change K9 to K99. Save the file. Wait a few seconds.
The browser window will automatically refresh showing the recalculated spreadsheet.
A | B | C | D |
---|---|---|---|
1 | 2 | 3 | 6 |
4 | 5 | 6 | |
7 | 8 | 99 | |
108 |
Admittedly it's very clunky but I think this is the kind of workflow you wanted, where updating a serialized form of spreadsheet will be rendered in "realtime" in a graphical viewer.
I think what you ultimately want is to integrate the text editor and the viewer into a single application with two display panels.
input_file.slk
:
ID;PCALCOOO32
C;X1;Y1;K1
C;X2;Y1;K2
C;X3;Y1;K3
C;X4;Y1;K6;EA1+B1+C1
C;X1;Y2;K4
C;X2;Y2;K5
C;X3;Y2;K6
C;X1;Y3;K7
C;X2;Y3;K8
C;X3;Y3;K99
C;X3;Y4;K18;ESUM(C1:C3)
E
SylkRenderer.py
:
import os
import time
import uno
import webbrowser
from selenium import webdriver
# Render a SYLK file in a web browser with realtime updating.
# Function to get the last modified timestamp of the SYLK file
def get_file_mod_time(file_path):
"""Returns the last modified timestamp of the file."""
return os.path.getmtime(file_path)
# Function to open SYLK file in LibreOffice Calc and export it to HTML
def open_and_recalculate_in_calc(slk_file_path, output_html_path):
"""Send the SYLK file to LibreOffice Calc and export to HTML."""
# Connect to LibreOffice in headless mode
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localContext
)
context = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
# Get the LibreOffice Desktop (to manage open files)
desktop = context.ServiceManager.createInstanceWithContext(
"com.sun.star.frame.Desktop", context
)
# Open the .slk file
file_url = uno.systemPathToFileUrl(os.path.abspath(slk_file_path))
document = desktop.loadComponentFromURL(file_url, "_blank", 0, ())
# Wait for LibreOffice to finish recalculating
time.sleep(2)
# Save the document as HTML
output_url = uno.systemPathToFileUrl(os.path.abspath(output_html_path))
# Filters used when saving document.
# https://github.com/LibreOffice/core/tree/330df37c7e2af0564bcd2de1f171bed4befcc074/filter/source/config/fragments/filters
filter = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
filter.Name = 'FilterName'
filter.Value = 'HTML (StarCalc)'
filters = (filter,)
# Store the HTML document
document.storeToURL(output_url, filters)
# Close the document
document.close(True)
print(f"Document saved as HTML: {output_html_path}")
# Function to launch Selenium and open the HTML file in the browser
def open_browser_with_html(html_file_path):
"""Open the HTML file in the browser using Selenium."""
# Launch Chrome browser (or another browser if needed)
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=options)
driver.get(f"file:///{os.path.abspath(html_file_path)}")
return driver
# Function to watch the SYLK file for changes and refresh the browser if needed
def watch_and_update(slk_file_path, output_html_path, browser_driver):
"""Watch the SYLK file for changes and update the browser if necessary."""
# Store the initial last modified timestamp of the SYLK file
last_mod_time = get_file_mod_time(slk_file_path)
while True:
# Wait for a short period before checking for changes
time.sleep(2)
# Check if the file last modified time has changed
current_mod_time = get_file_mod_time(slk_file_path)
if current_mod_time != last_mod_time:
print(f"File modified, updating...")
# Update the last modified time
last_mod_time = current_mod_time
# Send the updated SYLK file to LibreOffice Calc and export it
open_and_recalculate_in_calc(slk_file_path, output_html_path)
# Refresh the browser with the new content
browser_driver.refresh()
print("Browser refreshed with updated HTML content.")
# Main function to orchestrate the process
def main(slk_file_path, output_html_path):
# Step 1: Open the SYLK file in LibreOffice Calc and export to HTML
open_and_recalculate_in_calc(slk_file_path, output_html_path)
# Step 2: Open the resulting HTML file in a browser using Selenium
browser_driver = open_browser_with_html(output_html_path)
# Step 3: Monitor the SYLK file for changes and refresh the browser if the file is modified
watch_and_update(slk_file_path, output_html_path, browser_driver)
if __name__ == "__main__":
# Define the paths for the input and output files
slk_file = "input_file.slk" # Path to your SYLK file
html_file = "output_file.html" # Desired output HTML file
# Run the main process
main(slk_file, html_file)