Skip to main content

xlwings_utils

Project description

Introduction

This module provides some useful functions to be used in xlwings (lite).

Installation

Just add xlwings-utils to the requirements.txt tab.

In the script, add

ìmport xlwings_utils as xwu

[!NOTE]

The GitHub repository can be found on https://github.com/salabim/xlwings_utils .

Dropbox support

The xlwings lite system does not provide access to the local file system. With this module, files can be copied between Dropbox and the local pyodide file system, making it possible to indirectly use the local file system.

It is only possible, as of now, to use full-access Dropbox apps.

The easiest way to use the Dropbox functionality is to add the credentials to the environment variables. Add REFRESH_TOKEN, APP_KEY and APP_SECRET with their corresponding values to the environment variables.

Then, it is possible to list all files in a specified folder with the function list_dropbox. It is also possible to get the folders and to access all underlying folders.

The function read_dropbox can be used to read a Dropbox file's contents (bytes).

The function write_dropbox can be used to write contents (bytes) to a Dropbox file.

The functions list_local, read_local and write_local offer similar functionality for the local file system (on pyodide).

So, a way to access a file on the system's drive (mapped to Dropbox) as a local file is:

contents = xlwings_utils.read_dropbox('/downloads/file1.xls')
xlwings_utils.write_local('file1.xlsx')
df = pandas.read_excel"file1.xlsx")
...

And the other direction:

contents = xlwings_utils.read_local('file1.gif')
xlwings_utils.write_dropbox('/downloads/file1.gif')

Block support

The module contains a useful 2-dimensional data structure: block. This can be useful to manipulate a range without accessing the range directly, which is expensive in terms of memory and execution time. The advantage over an ordinary list of lists is that a block is index one-based, in line with range and addressing is done with a row, column tuple. So, my_block(lol)[row, col] is roughly equivalent to lol[row-1][col-1]

A block stores the values internally as a dictionary and will only convert these to a list of lists when using block.value.

Converting the value of a range (usually a list of lists, but can also be a list or scalar) to a block can be done with

my_block = xwu.block.from_value(range.value)

The dimensions (number of rows and number of columns) are automatically set.

Setting of an individual item (one-based, like range) can be done like

my_block[row, column] = x

And, likewise, reading an individual item can be done like

x = my_block[row, column]

It is not allowed t,o read or write outside the block dimensions.

It is also possible to define an empty block, like

block = xlwings_utils.block(number_of_rows, number_columns)

The dimensions can be queried or redefined with block.number_of_rows and block.number_of_columns.

To assign a block to range, use

range.value = block.value

The property block.highest_used_row_number returns the row number of the highest non-None cell.

The property block.highest_used_column_number returns the column_number of the highest non-None cell.

The method block.minimized() returns a block that has the dimensions of (highest_used_row_number, highest_used_column_number).

Particularly if we process an unknown number of lines, we can do something like:

this_block = xwu.block(number_of_rows=10000, number_of_columns=2)
for row in range(1, 10001):
	this_block[row,1]= ...
	this_block[row,2]= ...
	if ...: # end condition
	    break
sheet.range(10,1).value = this_block.minimized().value

In this case, only the really processed rows are copied to the sheet.

With blocks, it is easy to use a sheet as an input for a project / scenario.

Like, something like

Of course we could access the various input fields with absolute ranges, but if something changes later (like adding a row), all references have to be updated.

If we read the project sheet (partly) into a block, lookup methods are available to access 'fields' easily and future proof.

Let's see how this works with the above sheet. The block (bl) looks like

  |   1                2                3                4                5
--+-------------------------------------------------------------------------------     
1 |   Project          Factory1
2 |   Name             Mega1
3 |   Start date       2025-05-17
4 |   End date         2026-02-01
5 | 
6 |   Parts            Width            Length           Height           Weight
7 |   A                10               5                5                100
8 |   B                11               5                8                102
9 |   C                12               2                3                91        
10|   

Now we can do
project  = bl.lookup("Project")
name = bl.lookup("Start date")
start_date = bl.lookup("Start date")
end_date = bl.lookup("End date")
row1 = bl.lookup_row("Parts")
parts=[]
for row2 in range(row1 + 1, bl.highest_used_row_number + 1):
    if not (part_name := bl.hlookup("Part",row1=row1, row2=row2)):
        # stop when reach a 'blank' part_name
        break
    width = bl.hlookup("Width",row1=row1, row2=row2)
    length = bl.hlookup("Length",row1=row1, row2=row2)  
    height = bl.hlookup("HeightL",row1=row1, row2=row2)  
    weight = bl.hlookup("Weight",row1=row1, row2=row2)         
    parts.append(Part(part_name, width, length, height, weight))
       
You see lookup, which is vertical lookup, which just scans column 1 for the given label and then returns the corresponding value from column 2.

Then, there's lookup_row, which also scans column1 for the given label (Parts), but returns the corresponding row (6). Store it in row1.
And then we just read the following rows (with hlookup) and access the required values.

## Capture stdout support

The module has support for capturing stdout and -later- using showing the captured output on a sheet.

This is rather important as printing in xlwings lite to the UI pane is rather slow.

In order to capture stdout output, use


with xwu.capture: """ code with print statements """


and then the captured output can be copied to a sheet, like

sheet.range(4,5).value = xwu.capture.value

Upon reading the value, the capture buffer will be emptied.

If you don't want the buffer to be emptied after accessing the value, use `xwu.capture.value_keep`.

The capture buffer can also be retrieved as a string with `xwu.capture.str` and `xwu.capture.str_keep`.

Clearing the captured stdout buffer can be done at any time with `xwu.capture.clear()`.

Normally, stdout will not be sent to the xlwings lite UI panel when captured with the `xwu.capture` context manager. However, if you specify `xwu.capture.include_print = True`, the output will be sent to the UI panel as well. Note that this setting remains active until a `xwu.capture.include_print = False` is issued.


## Contact info

You can contact Ruud van der Ham, the core developer, via ruud@salabim.org .

## Badges

![PyPI](https://img.shields.io/pypi/v/xlwings-utils) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/xlwings-utils) ![PyPI - Implementation](https://img.shields.io/pypi/implementation/xlwings-utils)
![PyPI - License](https://img.shields.io/pypi/l/xlwings-utils) ![ruff](https://img.shields.io/badge/style-ruff-41B5BE?style=flat) 
![GitHub last commit](https://img.shields.io/github/last-commit/salabim/peek)

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xlwings_utils-25.0.0.post2.tar.gz (12.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xlwings_utils-25.0.0.post2-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

File details

Details for the file xlwings_utils-25.0.0.post2.tar.gz.

File metadata

  • Download URL: xlwings_utils-25.0.0.post2.tar.gz
  • Upload date:
  • Size: 12.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.0

File hashes

Hashes for xlwings_utils-25.0.0.post2.tar.gz
Algorithm Hash digest
SHA256 2dca5766754e76923fd66d7dd2eea227aaecc408cc622f95de10123c5e13cd45
MD5 80d919a82d2c2aea368db4a4ed37c4e1
BLAKE2b-256 5b979f13605ee4b98c57e512af61148949abe58828bbf733b8891b266c7f2f24

See more details on using hashes here.

File details

Details for the file xlwings_utils-25.0.0.post2-py3-none-any.whl.

File metadata

File hashes

Hashes for xlwings_utils-25.0.0.post2-py3-none-any.whl
Algorithm Hash digest
SHA256 594c82604cc7ea5c32409861933a63d621933f89f842fe1a1ae1a7529ee6c9ec
MD5 6bd5456b13b77808f1586903e3bee22b
BLAKE2b-256 595e3b70134b9f5f4de1c95a3c588d0b4f135f1105bfa18bd7505ec442ab16a1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page