xlwings-utils 0.0.6__py3-none-any.whl → 0.0.7.post0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of xlwings-utils might be problematic. Click here for more details.
- xlwings_utils/xlwings_utils.py +109 -92
- xlwings_utils-0.0.7.post0.dist-info/METADATA +156 -0
- xlwings_utils-0.0.7.post0.dist-info/RECORD +6 -0
- {xlwings_utils-0.0.6.dist-info → xlwings_utils-0.0.7.post0.dist-info}/WHEEL +1 -1
- xlwings_utils-0.0.6.dist-info/METADATA +0 -52
- xlwings_utils-0.0.6.dist-info/RECORD +0 -6
- {xlwings_utils-0.0.6.dist-info → xlwings_utils-0.0.7.post0.dist-info}/top_level.txt +0 -0
xlwings_utils/xlwings_utils.py
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# /_/\_\|_| \_/\_/ |_||_| |_| \__, ||___/ _____ \__,_| \__||_||_||___/
|
|
6
6
|
# |___/ |_____|
|
|
7
7
|
|
|
8
|
-
__version__ = "0.0.
|
|
8
|
+
__version__ = "0.0.7"
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
import dropbox
|
|
@@ -13,7 +13,8 @@ from pathlib import Path
|
|
|
13
13
|
import os
|
|
14
14
|
import sys
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
_org_stdout = sys.stdout
|
|
17
|
+
|
|
17
18
|
dbx = None
|
|
18
19
|
Pythonista = sys.platform == "ios"
|
|
19
20
|
|
|
@@ -217,7 +218,7 @@ def list_local(path, recursive=False, show_files=True, show_folders=False):
|
|
|
217
218
|
show_folders : bool
|
|
218
219
|
if True, show folder entries
|
|
219
220
|
if False (default), do not show folder entries
|
|
220
|
-
|
|
221
|
+
|
|
221
222
|
Returns
|
|
222
223
|
-------
|
|
223
224
|
files, relative to path : list
|
|
@@ -268,55 +269,48 @@ class block:
|
|
|
268
269
|
block
|
|
269
270
|
"""
|
|
270
271
|
|
|
271
|
-
def __init__(self, number_of_rows, number_of_columns):
|
|
272
|
+
def __init__(self, value=None, *, number_of_rows=None, number_of_columns=None, column_like=False):
|
|
272
273
|
self.dict = {}
|
|
273
|
-
self.
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
This parameter is not used for proper 2 dimensional list of lists or scalars
|
|
292
|
-
|
|
293
|
-
Returns
|
|
294
|
-
-------
|
|
295
|
-
block
|
|
296
|
-
|
|
297
|
-
Note
|
|
298
|
-
----
|
|
299
|
-
number_of_rows and number_of_columns will be retrieved from list_of_lists dimension
|
|
300
|
-
"""
|
|
301
|
-
if not isinstance(list_of_lists, list):
|
|
302
|
-
list_of_lists = [[list_of_lists]]
|
|
303
|
-
if not isinstance(list_of_lists[0], list):
|
|
304
|
-
if column_like:
|
|
305
|
-
list_of_lists = [[value] for value in list_of_lists]
|
|
306
|
-
else:
|
|
307
|
-
list_of_lists = [list_of_lists]
|
|
274
|
+
self.column_like = column_like
|
|
275
|
+
if value is None:
|
|
276
|
+
if number_of_rows is None:
|
|
277
|
+
number_of_rows = 1
|
|
278
|
+
if number_of_columns is None:
|
|
279
|
+
number_of_columns = 1
|
|
280
|
+
self.number_of_rows = number_of_rows
|
|
281
|
+
self.number_of_columns = number_of_columns
|
|
282
|
+
|
|
283
|
+
else:
|
|
284
|
+
if isinstance(value, block):
|
|
285
|
+
value = value.value
|
|
286
|
+
self.value = value
|
|
287
|
+
if number_of_rows is not None:
|
|
288
|
+
self.number_of_rows = number_of_rows
|
|
289
|
+
if number_of_columns is not None:
|
|
290
|
+
self.number_of_columns = number_of_columns
|
|
308
291
|
|
|
309
|
-
|
|
292
|
+
@property
|
|
293
|
+
def value(self):
|
|
294
|
+
return [[self.dict.get((row, column)) for column in range(1, self.number_of_columns + 1)] for row in range(1, self.number_of_rows + 1)]
|
|
295
|
+
|
|
296
|
+
@value.setter
|
|
297
|
+
def value(self, value):
|
|
298
|
+
if not isinstance(value, list):
|
|
299
|
+
value = [[value]]
|
|
300
|
+
if not isinstance(value[0], list):
|
|
301
|
+
if self.column_like:
|
|
302
|
+
value = [[item] for item in value]
|
|
303
|
+
else:
|
|
304
|
+
value = [value]
|
|
310
305
|
|
|
311
|
-
self.number_of_rows = len(
|
|
306
|
+
self.number_of_rows = len(value)
|
|
312
307
|
self._number_of_columns = 0
|
|
313
308
|
|
|
314
|
-
for row, row_contents in enumerate(
|
|
315
|
-
for column,
|
|
316
|
-
if
|
|
317
|
-
self.dict[row, column] =
|
|
309
|
+
for row, row_contents in enumerate(value, 1):
|
|
310
|
+
for column, item in enumerate(row_contents, 1):
|
|
311
|
+
if item is not None:
|
|
312
|
+
self.dict[row, column] = item
|
|
318
313
|
self._number_of_columns = max(self.number_of_columns, column)
|
|
319
|
-
return self
|
|
320
314
|
|
|
321
315
|
def __setitem__(self, row_column, value):
|
|
322
316
|
row, column = row_column
|
|
@@ -334,13 +328,8 @@ class block:
|
|
|
334
328
|
raise IndexError(f"column must be between 1 and {self.number_of_columns} not {column}")
|
|
335
329
|
return self.dict.get((row, column))
|
|
336
330
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
return [[self.dict.get((row, column)) for column in range(1, self.number_of_columns + 1)] for row in range(1, self.number_of_rows + 1)]
|
|
340
|
-
|
|
341
|
-
@property
|
|
342
|
-
def as_minimal_list_of_lists(self):
|
|
343
|
-
return [[self.dict.get((row, column)) for column in range(1, self.maximum_column + 1)] for row in range(1, self.maximum_row + 1)]
|
|
331
|
+
def minimized(self):
|
|
332
|
+
return block(self, number_of_rows=self.highest_used_row_number, number_of_columns=self.highest_used_column_number)
|
|
344
333
|
|
|
345
334
|
@property
|
|
346
335
|
def number_of_rows(self):
|
|
@@ -369,31 +358,39 @@ class block:
|
|
|
369
358
|
del self.dict[row, column]
|
|
370
359
|
|
|
371
360
|
@property
|
|
372
|
-
def
|
|
361
|
+
def highest_used_row_number(self):
|
|
373
362
|
if self.dict:
|
|
374
363
|
return max(row for (row, column) in self.dict)
|
|
375
364
|
else:
|
|
376
365
|
return 1
|
|
377
366
|
|
|
378
367
|
@property
|
|
379
|
-
def
|
|
368
|
+
def highest_used_column_number(self):
|
|
380
369
|
if self.dict:
|
|
381
370
|
return max(column for (row, column) in self.dict)
|
|
382
371
|
else:
|
|
383
372
|
return 1
|
|
384
373
|
|
|
385
374
|
def __repr__(self):
|
|
386
|
-
return f"block
|
|
375
|
+
return f"block({self.value})"
|
|
387
376
|
|
|
388
377
|
|
|
389
|
-
def clear_captured_stdout():
|
|
378
|
+
def clear_captured_stdout(clear=True):
|
|
390
379
|
"""
|
|
391
380
|
empties the captured stdout
|
|
381
|
+
|
|
382
|
+
Parameters
|
|
383
|
+
----------
|
|
384
|
+
clear : bool
|
|
385
|
+
if True (default), the capture buffer is emptied
|
|
386
|
+
|
|
387
|
+
if False: no action
|
|
392
388
|
"""
|
|
393
|
-
|
|
389
|
+
if clear:
|
|
390
|
+
_buffer.clear()
|
|
394
391
|
|
|
395
392
|
|
|
396
|
-
def captured_stdout_as_str():
|
|
393
|
+
def captured_stdout_as_str(clear=True):
|
|
397
394
|
"""
|
|
398
395
|
returns the captured stdout as a string
|
|
399
396
|
|
|
@@ -402,64 +399,84 @@ def captured_stdout_as_str():
|
|
|
402
399
|
captured stdout : list
|
|
403
400
|
each line is an element of the list
|
|
404
401
|
"""
|
|
405
|
-
|
|
406
|
-
|
|
402
|
+
result = "".join(_buffer)
|
|
403
|
+
clear_captured_stdout(clear)
|
|
404
|
+
return result
|
|
407
405
|
|
|
408
406
|
|
|
409
|
-
def
|
|
407
|
+
def captured_stdout_as_value(clear=True):
|
|
410
408
|
"""
|
|
411
409
|
returns the captured stdout as a list of lists
|
|
412
410
|
|
|
413
411
|
Returns
|
|
414
412
|
-------
|
|
415
|
-
captured stdout : list
|
|
413
|
+
captured stdout : list of lists
|
|
416
414
|
each line is an element of the list
|
|
417
415
|
|
|
418
416
|
Note
|
|
419
417
|
----
|
|
420
418
|
This can be used directly to fill a xlwings range
|
|
421
419
|
"""
|
|
422
|
-
return [[line] for line in captured_stdout_as_str().splitlines()]
|
|
420
|
+
return [[line] for line in captured_stdout_as_str(clear).splitlines()]
|
|
421
|
+
|
|
423
422
|
|
|
423
|
+
class handle_capture_stdout:
|
|
424
|
+
def __init__(self):
|
|
425
|
+
pass
|
|
424
426
|
|
|
425
|
-
|
|
427
|
+
def isatty(self):
|
|
428
|
+
return False
|
|
429
|
+
|
|
430
|
+
def write(self, data):
|
|
431
|
+
if _do_capture:
|
|
432
|
+
_buffer.append(data)
|
|
433
|
+
if _do_print:
|
|
434
|
+
_org_stdout.write(data)
|
|
435
|
+
|
|
436
|
+
def flush(self):
|
|
437
|
+
if _do_print:
|
|
438
|
+
_org_stdout.flush()
|
|
439
|
+
if _do_capture:
|
|
440
|
+
_buffer.append("\n")
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
def reset():
|
|
444
|
+
global _buffer
|
|
445
|
+
global _do_print
|
|
446
|
+
global _do_capture
|
|
447
|
+
_buffer = []
|
|
448
|
+
_do_print = True
|
|
449
|
+
_do_capture = False
|
|
450
|
+
sys.stdout = handle_capture_stdout()
|
|
451
|
+
|
|
452
|
+
reset()
|
|
453
|
+
|
|
454
|
+
def capture_stdout(do_print=True, do_capture=True, clear=True):
|
|
455
|
+
global _do_print
|
|
456
|
+
global _do_capture
|
|
426
457
|
"""
|
|
427
458
|
start capture stdout
|
|
428
459
|
|
|
429
460
|
Parameters
|
|
430
461
|
----------
|
|
431
|
-
|
|
432
|
-
if True (default), the output is also printed out as normal
|
|
462
|
+
do_print : bool
|
|
463
|
+
if True (default), the output is (also) printed out as normal
|
|
433
464
|
|
|
434
465
|
if False, no output is printed
|
|
435
466
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
This function is normally used as a context manager, like ::
|
|
467
|
+
do_capture : bool
|
|
468
|
+
if True (default), the output is (also) captured to a buffer
|
|
439
469
|
|
|
440
|
-
|
|
441
|
-
...
|
|
442
|
-
"""
|
|
443
|
-
|
|
444
|
-
def __init__(self, include_print: bool = True):
|
|
445
|
-
self.stdout = sys.stdout
|
|
446
|
-
self.include_print = include_print
|
|
447
|
-
|
|
448
|
-
def __enter__(self):
|
|
449
|
-
sys.stdout = self
|
|
450
|
-
|
|
451
|
-
def __exit__(self, exc_type, exc_value, tb):
|
|
452
|
-
sys.stdout = self.stdout
|
|
470
|
+
if False, no output is captured
|
|
453
471
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
_captured_stdout.append("\n")
|
|
472
|
+
clear : bool
|
|
473
|
+
if True (default), the capture buffer is emptied
|
|
474
|
+
"""
|
|
475
|
+
if not (do_print or do_capture):
|
|
476
|
+
raise ValueError("at least one of do_print and do_capture should be True")
|
|
477
|
+
clear_captured_stdout(clear)
|
|
478
|
+
_do_print = do_print
|
|
479
|
+
_do_capture = do_capture
|
|
463
480
|
|
|
464
481
|
|
|
465
482
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: xlwings_utils
|
|
3
|
+
Version: 0.0.7.post0
|
|
4
|
+
Summary: xlwings_utils
|
|
5
|
+
Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/salabim/xlwings_utils
|
|
7
|
+
Project-URL: Repository, https://github.com/salabim/xlwings_utils
|
|
8
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
9
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: dropbox
|
|
13
|
+
Requires-Dist: ssl
|
|
14
|
+
|
|
15
|
+
<img src="https://www.salabim.org/xlwings_utils_logo2.png">
|
|
16
|
+
|
|
17
|
+
## Introduction
|
|
18
|
+
|
|
19
|
+
This module provides some useful functions to be used in xlwings (lite).
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
Just add xlwings-utils to the *requirements.txt* tab.
|
|
24
|
+
|
|
25
|
+
In the script, add
|
|
26
|
+
|
|
27
|
+
```ìmport xlwings_utils as xwu```
|
|
28
|
+
|
|
29
|
+
> [!NOTE]
|
|
30
|
+
>
|
|
31
|
+
> The GitHub repository can be found on https://github.com/salabim/xlwings_utils .
|
|
32
|
+
|
|
33
|
+
## Dropbox support
|
|
34
|
+
|
|
35
|
+
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.
|
|
36
|
+
|
|
37
|
+
It is only possible, as of now, to use full-access Dropbox apps.
|
|
38
|
+
|
|
39
|
+
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.
|
|
40
|
+
|
|
41
|
+
Then, it is possible to list all files in a specified folder with the function `list_dropbox`.
|
|
42
|
+
It is also possible to get the folders and to access all underlying folders.
|
|
43
|
+
|
|
44
|
+
The function `read_dropbox` can be used to read a Dropbox file's contents (bytes).
|
|
45
|
+
|
|
46
|
+
The function `write_dropbox` can be used to write contents (bytes) to a Dropbox file.
|
|
47
|
+
|
|
48
|
+
The functions `list_local`, `read_local` and `write_local` offer similar functionality for the local file system (on pyodide).
|
|
49
|
+
|
|
50
|
+
So, a way to access a file on the system's drive (mapped to Dropbox) as a local file is:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
contents = xlwings_utils.read_dropbox('/downloads/file1.xls')
|
|
54
|
+
xlwings_utils.write_local('file1.xlsx')
|
|
55
|
+
df = pandas.read_excel"file1.xlsx")
|
|
56
|
+
...
|
|
57
|
+
```
|
|
58
|
+
And the other direction:
|
|
59
|
+
```
|
|
60
|
+
contents = xlwings_utils.read_local('file1.gif')
|
|
61
|
+
xlwings_utils.write_dropbox('/downloads/file1.gif')
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Block support
|
|
65
|
+
|
|
66
|
+
The module contains a useful 2-dimensional data structure: *block*.
|
|
67
|
+
This can be useful to manipulate a range without accessing the range directly, which is expensive in terms of memory and execution time.
|
|
68
|
+
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.
|
|
69
|
+
So, `my_block(lol)[row, col]` is roughly equivalent to `lol[row-1][col-1]`
|
|
70
|
+
|
|
71
|
+
A block stores the values internally as a dictionary and will only convert these to a list of lists when using `block.value`.
|
|
72
|
+
|
|
73
|
+
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
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
my_block = xwu.block.from_value(range.value)
|
|
77
|
+
```
|
|
78
|
+
The dimensions (number of rows and number of columns) are automatically set.
|
|
79
|
+
|
|
80
|
+
Setting of an individual item (one-based, like range) can be done like
|
|
81
|
+
```
|
|
82
|
+
my_block[row, column] = x
|
|
83
|
+
```
|
|
84
|
+
And, likewise, reading an individual item can be done like
|
|
85
|
+
```
|
|
86
|
+
x = my_block[row, column]
|
|
87
|
+
```
|
|
88
|
+
It is not allowed t,o read or write outside the block dimensions.
|
|
89
|
+
|
|
90
|
+
It is also possible to define an empty block, like
|
|
91
|
+
```
|
|
92
|
+
block = xlwings_utils.block(number_of_rows, number_columns)
|
|
93
|
+
```
|
|
94
|
+
The dimensions can be queried or redefined with `block.number_of_rows` and
|
|
95
|
+
`block.number_of_columns`.
|
|
96
|
+
|
|
97
|
+
To assign a block to range, use
|
|
98
|
+
```
|
|
99
|
+
range.value = block.value
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The property `block.highest_used_row_number` returns the row number of the highest non-None cell.
|
|
103
|
+
|
|
104
|
+
The property `block.highest_used_column_number` returns the column_number of the highest non-None cell.
|
|
105
|
+
|
|
106
|
+
The method `block.minimized()` returns a block that has the dimensions of (highest_used_row_number, highest_used_column_number).
|
|
107
|
+
|
|
108
|
+
Particularly if we process an unknown number of lines, we can do something like:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
this_block = xwu.block(number_of_rows=10000, number_of_columns=2)
|
|
112
|
+
for row in range(1, 10001):
|
|
113
|
+
this_block[row,1]= ...
|
|
114
|
+
this_block[row,2]= ...
|
|
115
|
+
if ...: # end condition
|
|
116
|
+
break
|
|
117
|
+
sheet.range(10,1).value = this_block.minimized().value
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
In this case, only the really processed rows are copied to the sheet.
|
|
121
|
+
|
|
122
|
+
## Capture stdout support
|
|
123
|
+
|
|
124
|
+
The module has support for capturing stdout and -later- using showing the captured output on a sheet.
|
|
125
|
+
|
|
126
|
+
To do that:
|
|
127
|
+
|
|
128
|
+
```makes it possible to capture stdout writes, which
|
|
129
|
+
with xwu.capture_stdout():
|
|
130
|
+
...
|
|
131
|
+
```
|
|
132
|
+
and then the captured output can be copied to the screen, like
|
|
133
|
+
|
|
134
|
+
```can then be copied to a worksheet in a later stage.
|
|
135
|
+
sheet.range(4,5).value = xwu.captured_stdout_as_value()
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Clearing the captured stdout buffer can be done with `xwu.clear_captured_std_out`.
|
|
139
|
+
|
|
140
|
+
Normally, stdout will also be sent to the xlwings lite UI panel. This can be suppressed with
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
with xwu.capture_stdout(include_print=False):
|
|
144
|
+
...
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Contact info
|
|
148
|
+
|
|
149
|
+
You can contact Ruud van der Ham, the core developer, via ruud@salabim.org .
|
|
150
|
+
|
|
151
|
+
## Badges
|
|
152
|
+
|
|
153
|
+
  
|
|
154
|
+
 
|
|
155
|
+

|
|
156
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
|
|
2
|
+
xlwings_utils/xlwings_utils.py,sha256=J-OBksRT1nBZZLmo4qYcFa1iNLQvH0wGjnBSEIuz-Y0,13237
|
|
3
|
+
xlwings_utils-0.0.7.post0.dist-info/METADATA,sha256=mdTOcI24b_DCtg_FnumaXzAcmamKTx6nDH0cuBWyoAo,5695
|
|
4
|
+
xlwings_utils-0.0.7.post0.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
|
|
5
|
+
xlwings_utils-0.0.7.post0.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
|
|
6
|
+
xlwings_utils-0.0.7.post0.dist-info/RECORD,,
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: xlwings_utils
|
|
3
|
-
Version: 0.0.6
|
|
4
|
-
Summary: xlwings_utils
|
|
5
|
-
Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
|
|
6
|
-
Project-URL: Homepage, https://github.com/salabim/xlwings_utils
|
|
7
|
-
Project-URL: Repository, https://github.com/salabim/xlwings_utils
|
|
8
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
9
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
10
|
-
Requires-Python: >=3.9
|
|
11
|
-
Description-Content-Type: text/markdown
|
|
12
|
-
Requires-Dist: dropbox
|
|
13
|
-
Requires-Dist: ssl
|
|
14
|
-
|
|
15
|
-
<img src="https://www.salabim.org/xlwings_utils_logo1.png">
|
|
16
|
-
|
|
17
|
-
## Introduction
|
|
18
|
-
|
|
19
|
-
This module provides some useful functions to be used in xlwings lite.
|
|
20
|
-
|
|
21
|
-
The xlwings lite system does not provide access to the local file system. With this
|
|
22
|
-
module, files can be copied between dropbox and the local pyodide file systen. And
|
|
23
|
-
therefore, it is possible to indirectly use the local file system.
|
|
24
|
-
|
|
25
|
-
The module contains support for a useful 2 dimensional data structure: block.
|
|
26
|
-
Thjs can be useful to manipulate a range without accessing the range directly,
|
|
27
|
-
which is expensive in terms of memory and execution time.
|
|
28
|
-
|
|
29
|
-
On top of that, this module makes it possible to capture stdout writes, which
|
|
30
|
-
can then be copied to a worksheet in a later stage.
|
|
31
|
-
|
|
32
|
-
## Installation
|
|
33
|
-
|
|
34
|
-
Just add xlwings-utils to the requirement tab. It might be required to add ssl.
|
|
35
|
-
|
|
36
|
-
## Dropbox support
|
|
37
|
-
|
|
38
|
-
xlwings_lite only works with full access dropbox apps.
|
|
39
|
-
|
|
40
|
-
In order to use dropbox functionality, is is necessary to initialize the module with credentials.
|
|
41
|
-
|
|
42
|
-
```xwu.dropbox_init()```
|
|
43
|
-
If called without parameters, the refresh_token is
|
|
44
|
-
|
|
45
|
-
## Capture stdout support
|
|
46
|
-
|
|
47
|
-
Badges
|
|
48
|
-
|
|
49
|
-
  
|
|
50
|
-
 
|
|
51
|
-

|
|
52
|
-
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
|
|
2
|
-
xlwings_utils/xlwings_utils.py,sha256=yvWW2yRjkHvF5814ptlbGxT5tpRRg-wH1yCDO-5qIe8,12866
|
|
3
|
-
xlwings_utils-0.0.6.dist-info/METADATA,sha256=0fJEsPdOJ1uoHQnAeGzB5dPm-qKD9F_1CGfP9h1Oc4s,2083
|
|
4
|
-
xlwings_utils-0.0.6.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
|
5
|
-
xlwings_utils-0.0.6.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
|
|
6
|
-
xlwings_utils-0.0.6.dist-info/RECORD,,
|
|
File without changes
|