xlwings-utils 25.0.0.post2__py3-none-any.whl → 25.0.0.post4__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 +98 -80
- {xlwings_utils-25.0.0.post2.dist-info → xlwings_utils-25.0.0.post4.dist-info}/METADATA +89 -38
- xlwings_utils-25.0.0.post4.dist-info/RECORD +6 -0
- {xlwings_utils-25.0.0.post2.dist-info → xlwings_utils-25.0.0.post4.dist-info}/WHEEL +1 -1
- xlwings_utils-25.0.0.post2.dist-info/RECORD +0 -6
- {xlwings_utils-25.0.0.post2.dist-info → xlwings_utils-25.0.0.post4.dist-info}/top_level.txt +0 -0
xlwings_utils/xlwings_utils.py
CHANGED
|
@@ -289,16 +289,30 @@ class block:
|
|
|
289
289
|
self.number_of_columns = number_of_columns
|
|
290
290
|
|
|
291
291
|
@classmethod
|
|
292
|
-
def from_xlrd_sheet(cls,sheet, number_of_rows=None, number_of_columns=None):
|
|
292
|
+
def from_xlrd_sheet(cls, sheet, number_of_rows=None, number_of_columns=None):
|
|
293
293
|
v = [sheet.row_values(row_idx)[0 : sheet.ncols] for row_idx in range(0, sheet.nrows)]
|
|
294
294
|
return cls(v, number_of_rows=number_of_rows, number_of_columns=number_of_columns)
|
|
295
295
|
|
|
296
|
+
@classmethod
|
|
297
|
+
def from_openpyxl_sheet(cls, sheet, number_of_rows=None, number_of_columns=None):
|
|
298
|
+
v = [[cell.value for cell in row] for row in sheet.iter_rows()]
|
|
299
|
+
return cls(v, number_of_rows=number_of_rows, number_of_columns=number_of_columns)
|
|
300
|
+
|
|
301
|
+
@classmethod
|
|
302
|
+
def from_file(cls, filename, number_of_rows=None, number_of_columns=None):
|
|
303
|
+
with open(filename, "r") as f:
|
|
304
|
+
v = [[line if line else None] for line in f.read().splitlines()]
|
|
305
|
+
return cls(v, number_of_rows=number_of_rows, number_of_columns=number_of_columns)
|
|
296
306
|
|
|
297
307
|
@classmethod
|
|
298
|
-
def from_dataframe(cls,df, number_of_rows=None, number_of_columns=None):
|
|
299
|
-
v=df.values.tolist()
|
|
308
|
+
def from_dataframe(cls, df, number_of_rows=None, number_of_columns=None):
|
|
309
|
+
v = df.values.tolist()
|
|
300
310
|
return cls(v, number_of_rows=number_of_rows, number_of_columns=number_of_columns)
|
|
301
311
|
|
|
312
|
+
def to_openpyxl_sheet(self, sheet):
|
|
313
|
+
for row in self.value:
|
|
314
|
+
sheet.append(row)
|
|
315
|
+
|
|
302
316
|
@property
|
|
303
317
|
def value(self):
|
|
304
318
|
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)]
|
|
@@ -318,7 +332,7 @@ class block:
|
|
|
318
332
|
|
|
319
333
|
for row, row_contents in enumerate(value, 1):
|
|
320
334
|
for column, item in enumerate(row_contents, 1):
|
|
321
|
-
if item and not (isinstance(item,float) and math.isnan(item)):
|
|
335
|
+
if item and not (isinstance(item, float) and math.isnan(item)):
|
|
322
336
|
self.dict[row, column] = item
|
|
323
337
|
self._number_of_columns = max(self.number_of_columns, column)
|
|
324
338
|
|
|
@@ -405,36 +419,36 @@ class block:
|
|
|
405
419
|
def vlookup(self, s, *, row_from=1, row_to=None, column1=1, column2=None):
|
|
406
420
|
"""
|
|
407
421
|
searches in column1 for row between row_from and row_to for s and returns the value found at (that row, column2)
|
|
408
|
-
|
|
422
|
+
|
|
409
423
|
Parameters
|
|
410
424
|
----------
|
|
411
425
|
s : any
|
|
412
426
|
value to seach for
|
|
413
|
-
|
|
427
|
+
|
|
414
428
|
row_from : int
|
|
415
429
|
row to start search (default 1)
|
|
416
|
-
|
|
430
|
+
|
|
417
431
|
should be between 1 and number_of_rows
|
|
418
|
-
|
|
432
|
+
|
|
419
433
|
row_to : int
|
|
420
434
|
row to end search (default number_of_rows)
|
|
421
|
-
|
|
422
|
-
should be between 1 and number_of_rows
|
|
423
|
-
|
|
435
|
+
|
|
436
|
+
should be between 1 and number_of_rows
|
|
437
|
+
|
|
424
438
|
column1 : int
|
|
425
439
|
column to search in (default 1)
|
|
426
|
-
|
|
440
|
+
|
|
427
441
|
should be between 1 and number_of_columns
|
|
428
|
-
|
|
442
|
+
|
|
429
443
|
column2 : int
|
|
430
444
|
column to return looked up value from (default column1 + 1)
|
|
431
|
-
|
|
432
|
-
should be between 1 and number_of_columns
|
|
433
|
-
|
|
445
|
+
|
|
446
|
+
should be between 1 and number_of_columns
|
|
447
|
+
|
|
434
448
|
Returns
|
|
435
449
|
-------
|
|
436
450
|
block[found row number, column2] : any
|
|
437
|
-
|
|
451
|
+
|
|
438
452
|
Note
|
|
439
453
|
----
|
|
440
454
|
If s is not found, a ValueError is raised
|
|
@@ -448,34 +462,34 @@ class block:
|
|
|
448
462
|
def lookup_row(self, s, *, row_from=1, row_to=None, column1=1):
|
|
449
463
|
"""
|
|
450
464
|
searches in column1 for row between row_from and row_to for s and returns that row number
|
|
451
|
-
|
|
465
|
+
|
|
452
466
|
Parameters
|
|
453
467
|
----------
|
|
454
468
|
s : any
|
|
455
469
|
value to seach for
|
|
456
|
-
|
|
470
|
+
|
|
457
471
|
row_from : int
|
|
458
472
|
row to start search (default 1)
|
|
459
|
-
|
|
473
|
+
|
|
460
474
|
should be between 1 and number_of_rows
|
|
461
|
-
|
|
475
|
+
|
|
462
476
|
row_to : int
|
|
463
477
|
row to end search (default number_of_rows)
|
|
464
|
-
|
|
465
|
-
should be between 1 and number_of_rows
|
|
466
|
-
|
|
478
|
+
|
|
479
|
+
should be between 1 and number_of_rows
|
|
480
|
+
|
|
467
481
|
column1 : int
|
|
468
482
|
column to search in (default 1)
|
|
469
|
-
|
|
483
|
+
|
|
470
484
|
should be between 1 and number_of_columns
|
|
471
|
-
|
|
485
|
+
|
|
472
486
|
column2 : int
|
|
473
487
|
column to return looked up value from (default column1 + 1)
|
|
474
|
-
|
|
488
|
+
|
|
475
489
|
Returns
|
|
476
490
|
-------
|
|
477
|
-
row number where block[row nunber, column1] == s : int
|
|
478
|
-
|
|
491
|
+
row number where block[row nunber, column1] == s : int
|
|
492
|
+
|
|
479
493
|
Note
|
|
480
494
|
----
|
|
481
495
|
If s is not found, a ValueError is raised
|
|
@@ -494,41 +508,41 @@ class block:
|
|
|
494
508
|
def hlookup(self, s, *, column_from=1, column_to=None, row1=1, row2=None):
|
|
495
509
|
"""
|
|
496
510
|
searches in row1 for column between column_from and column_to for s and returns the value found at (that column, row2)
|
|
497
|
-
|
|
511
|
+
|
|
498
512
|
Parameters
|
|
499
513
|
----------
|
|
500
514
|
s : any
|
|
501
515
|
value to seach for
|
|
502
|
-
|
|
516
|
+
|
|
503
517
|
column_from : int
|
|
504
518
|
column to start search (default 1)
|
|
505
|
-
|
|
519
|
+
|
|
506
520
|
should be between 1 and number_of_columns
|
|
507
|
-
|
|
521
|
+
|
|
508
522
|
column_to : int
|
|
509
523
|
column to end search (default number_of_columns)
|
|
510
|
-
|
|
511
|
-
should be between 1 and number_of_columns
|
|
512
|
-
|
|
524
|
+
|
|
525
|
+
should be between 1 and number_of_columns
|
|
526
|
+
|
|
513
527
|
row1 : int
|
|
514
528
|
row to search in (default 1)
|
|
515
|
-
|
|
529
|
+
|
|
516
530
|
should be between 1 and number_of_rows
|
|
517
|
-
|
|
531
|
+
|
|
518
532
|
row2 : int
|
|
519
533
|
row to return looked up value from (default row1 + 1)
|
|
520
|
-
|
|
521
|
-
should be between 1 and number_of_rows
|
|
522
|
-
|
|
534
|
+
|
|
535
|
+
should be between 1 and number_of_rows
|
|
536
|
+
|
|
523
537
|
Returns
|
|
524
538
|
-------
|
|
525
539
|
block[row, found column, row2] : any
|
|
526
|
-
|
|
540
|
+
|
|
527
541
|
Note
|
|
528
542
|
----
|
|
529
543
|
If s is not found, a ValueError is raised
|
|
530
544
|
"""
|
|
531
|
-
if
|
|
545
|
+
if row2 is None:
|
|
532
546
|
row2 = row1 + 1
|
|
533
547
|
self._check_row(row2, "row2")
|
|
534
548
|
column = self.lookup_column(s, column_from=column_from, column_to=column_to, row1=row1)
|
|
@@ -537,34 +551,34 @@ class block:
|
|
|
537
551
|
def lookup_column(self, s, *, column_from=1, column_to=None, row1=1):
|
|
538
552
|
"""
|
|
539
553
|
searches in row1 for column between column_from and column_to for s and returns that column number
|
|
540
|
-
|
|
554
|
+
|
|
541
555
|
Parameters
|
|
542
556
|
----------
|
|
543
557
|
s : any
|
|
544
558
|
value to seach for
|
|
545
|
-
|
|
559
|
+
|
|
546
560
|
column_from : int
|
|
547
561
|
column to start search (default 1)
|
|
548
|
-
|
|
562
|
+
|
|
549
563
|
should be between 1 and number_of_columns
|
|
550
|
-
|
|
564
|
+
|
|
551
565
|
column_to : int
|
|
552
566
|
column to end search (default number_of_columns)
|
|
553
|
-
|
|
554
|
-
should be between 1 and number_of_columns
|
|
555
|
-
|
|
567
|
+
|
|
568
|
+
should be between 1 and number_of_columns
|
|
569
|
+
|
|
556
570
|
row1 : int
|
|
557
571
|
row to search in (default 1)
|
|
558
|
-
|
|
572
|
+
|
|
559
573
|
should be between 1 and number_of_rows
|
|
560
|
-
|
|
574
|
+
|
|
561
575
|
row2 : int
|
|
562
576
|
row to return looked up value from (default row1 + 1)
|
|
563
|
-
|
|
577
|
+
|
|
564
578
|
Returns
|
|
565
579
|
-------
|
|
566
|
-
column number where block[row1, column number] == s : int
|
|
567
|
-
|
|
580
|
+
column number where block[row1, column number] == s : int
|
|
581
|
+
|
|
568
582
|
Note
|
|
569
583
|
----
|
|
570
584
|
If s is not found, a ValueError is raised
|
|
@@ -583,46 +597,46 @@ class block:
|
|
|
583
597
|
def lookup(self, s, *, row_from=1, row_to=None, column1=1, column2=None):
|
|
584
598
|
"""
|
|
585
599
|
searches in column1 for row between row_from and row_to for s and returns the value found at (that row, column2)
|
|
586
|
-
|
|
600
|
+
|
|
587
601
|
Parameters
|
|
588
602
|
----------
|
|
589
603
|
s : any
|
|
590
604
|
value to seach for
|
|
591
|
-
|
|
605
|
+
|
|
592
606
|
row_from : int
|
|
593
607
|
row to start search (default 1)
|
|
594
|
-
|
|
608
|
+
|
|
595
609
|
should be between 1 and number_of_rows
|
|
596
|
-
|
|
610
|
+
|
|
597
611
|
row_to : int
|
|
598
612
|
row to end search (default number_of_rows)
|
|
599
|
-
|
|
600
|
-
should be between 1 and number_of_rows
|
|
601
|
-
|
|
613
|
+
|
|
614
|
+
should be between 1 and number_of_rows
|
|
615
|
+
|
|
602
616
|
column1 : int
|
|
603
617
|
column to search in (default 1)
|
|
604
|
-
|
|
618
|
+
|
|
605
619
|
should be between 1 and number_of_columns
|
|
606
|
-
|
|
620
|
+
|
|
607
621
|
column2 : int
|
|
608
622
|
column to return looked up value from (default column1 + 1)
|
|
609
|
-
|
|
610
|
-
should be between 1 and number_of_columns
|
|
611
|
-
|
|
623
|
+
|
|
624
|
+
should be between 1 and number_of_columns
|
|
625
|
+
|
|
612
626
|
Returns
|
|
613
627
|
-------
|
|
614
628
|
block[found row number, column2] : any
|
|
615
|
-
|
|
629
|
+
|
|
616
630
|
Note
|
|
617
631
|
----
|
|
618
632
|
If s is not found, a ValueError is raised
|
|
619
|
-
|
|
633
|
+
|
|
620
634
|
This is exactly the same as vlookup.
|
|
621
635
|
"""
|
|
622
636
|
return self.vlookup(s, row_from=row_from, row_to=row_to, column1=column1, column2=column2)
|
|
623
637
|
|
|
624
638
|
|
|
625
|
-
class
|
|
639
|
+
class Capture:
|
|
626
640
|
"""
|
|
627
641
|
specifies how to capture stdout
|
|
628
642
|
|
|
@@ -647,10 +661,10 @@ class _capture:
|
|
|
647
661
|
self._buffer = []
|
|
648
662
|
|
|
649
663
|
def __enter__(self):
|
|
650
|
-
|
|
664
|
+
self.enabled = True
|
|
651
665
|
|
|
652
666
|
def __exit__(self, exc_type, exc_value, tb):
|
|
653
|
-
|
|
667
|
+
self.enabled = False
|
|
654
668
|
|
|
655
669
|
def write(self, data):
|
|
656
670
|
self._buffer.append(data)
|
|
@@ -662,6 +676,17 @@ class _capture:
|
|
|
662
676
|
self.stdout.flush()
|
|
663
677
|
self._buffer.append("\n")
|
|
664
678
|
|
|
679
|
+
@property
|
|
680
|
+
def enabled(self):
|
|
681
|
+
return sys.out == self
|
|
682
|
+
|
|
683
|
+
@enabled.setter
|
|
684
|
+
def enabled(self, value):
|
|
685
|
+
if value:
|
|
686
|
+
sys.stdout = self
|
|
687
|
+
else:
|
|
688
|
+
sys.stdout = self.stdout
|
|
689
|
+
|
|
665
690
|
@property
|
|
666
691
|
def value(self):
|
|
667
692
|
result = self.value_keep
|
|
@@ -696,13 +721,6 @@ class _capture:
|
|
|
696
721
|
self._include_print = value
|
|
697
722
|
|
|
698
723
|
|
|
699
|
-
def reset():
|
|
700
|
-
capture.include_print = False
|
|
701
|
-
capture.clear()
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
capture = _capture()
|
|
705
|
-
|
|
706
|
-
|
|
707
724
|
if __name__ == "__main__":
|
|
708
725
|
...
|
|
726
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xlwings_utils
|
|
3
|
-
Version: 25.0.0.
|
|
3
|
+
Version: 25.0.0.post4
|
|
4
4
|
Summary: xlwings_utils
|
|
5
5
|
Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/salabim/xlwings_utils
|
|
@@ -30,6 +30,16 @@ In the script, add
|
|
|
30
30
|
>
|
|
31
31
|
> The GitHub repository can be found on https://github.com/salabim/xlwings_utils .
|
|
32
32
|
|
|
33
|
+
General
|
|
34
|
+
|
|
35
|
+
It is recommended to put
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
import xlwings_utils as xwu
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
at the top of a xlwings lite script.
|
|
42
|
+
|
|
33
43
|
## Dropbox support
|
|
34
44
|
|
|
35
45
|
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.
|
|
@@ -50,15 +60,15 @@ The functions `list_local`, `read_local` and `write_local` offer similar functio
|
|
|
50
60
|
So, a way to access a file on the system's drive (mapped to Dropbox) as a local file is:
|
|
51
61
|
|
|
52
62
|
```
|
|
53
|
-
contents =
|
|
54
|
-
|
|
63
|
+
contents = xwu.read_dropbox('/downloads/file1.xls')
|
|
64
|
+
xwu.write_local('file1.xlsx')
|
|
55
65
|
df = pandas.read_excel"file1.xlsx")
|
|
56
66
|
...
|
|
57
67
|
```
|
|
58
68
|
And the other direction:
|
|
59
69
|
```
|
|
60
|
-
contents =
|
|
61
|
-
|
|
70
|
+
contents = xwu.read_local('file1.gif')
|
|
71
|
+
xwu.write_dropbox('/downloads/file1.gif')
|
|
62
72
|
```
|
|
63
73
|
|
|
64
74
|
## Block support
|
|
@@ -89,7 +99,7 @@ It is not allowed t,o read or write outside the block dimensions.
|
|
|
89
99
|
|
|
90
100
|
It is also possible to define an empty block, like
|
|
91
101
|
```
|
|
92
|
-
block =
|
|
102
|
+
block = xwu.block(number_of_rows, number_columns)
|
|
93
103
|
```
|
|
94
104
|
The dimensions can be queried or redefined with `block.number_of_rows` and
|
|
95
105
|
`block.number_of_columns`.
|
|
@@ -119,53 +129,71 @@ sheet.range(10,1).value = this_block.minimized().value
|
|
|
119
129
|
|
|
120
130
|
In this case, only the really processed rows are copied to the sheet.
|
|
121
131
|
|
|
122
|
-
|
|
132
|
+
### Looking up in a block
|
|
123
133
|
|
|
124
|
-
|
|
134
|
+
With blocks, it is easy to use a sheet as an input for a project / scenario.
|
|
125
135
|
|
|
136
|
+
Something like
|
|
137
|
+
<img src="https://www.salabim.org/xlwings_utils/fig01.png">
|
|
126
138
|
|
|
127
|
-
Of course we could access the various input fields with absolute ranges, but if something
|
|
128
|
-
changes later (like adding a row), all references have to be updated.
|
|
139
|
+
Of course, we could access the various input fields with absolute ranges, but if something changes later (like adding a row), all references would have to be updated.
|
|
129
140
|
|
|
130
|
-
If we read the project sheet (partly) into a block, lookup methods are available to access 'fields' easily and future
|
|
141
|
+
If we read the project sheet (partly) into a block, lookup methods are available to access 'fields' easily and future-proof.
|
|
131
142
|
|
|
132
|
-
Let's see how this works with the above sheet. The block (bl) looks like
|
|
143
|
+
Let's see how this works with the above sheet. The corresponding block (bl) looks like
|
|
133
144
|
|
|
134
145
|
```
|
|
135
146
|
| 1 2 3 4 5
|
|
136
147
|
--+-------------------------------------------------------------------------------
|
|
137
148
|
1 | Project Factory1
|
|
138
|
-
2 |
|
|
139
|
-
3 |
|
|
140
|
-
4 |
|
|
141
|
-
5 |
|
|
142
|
-
6 |
|
|
143
|
-
7 |
|
|
144
|
-
8 |
|
|
145
|
-
9 |
|
|
146
|
-
|
|
147
|
-
|
|
149
|
+
2 | Start date 2025-05-17
|
|
150
|
+
3 | End date 2026-02-01
|
|
151
|
+
4 |
|
|
152
|
+
5 | Parts Width Length Height Weight
|
|
153
|
+
6 | A 10 5 5 100
|
|
154
|
+
7 | B 11 5 8 102
|
|
155
|
+
8 | C 12 2 3 91
|
|
156
|
+
9 |
|
|
157
|
+
```
|
|
148
158
|
Now we can do
|
|
149
|
-
project = bl.lookup("Project")
|
|
150
|
-
|
|
159
|
+
```project = bl.lookup("Project")
|
|
160
|
+
project = bl.lookup("Project")
|
|
151
161
|
start_date = bl.lookup("Start date")
|
|
152
162
|
end_date = bl.lookup("End date")
|
|
153
163
|
row1 = bl.lookup_row("Parts")
|
|
154
164
|
parts=[]
|
|
155
165
|
for row2 in range(row1 + 1, bl.highest_used_row_number + 1):
|
|
156
166
|
if not (part_name := bl.hlookup("Part",row1=row1, row2=row2)):
|
|
157
|
-
# stop when
|
|
167
|
+
# stop when a 'blank' part_name is found
|
|
158
168
|
break
|
|
159
169
|
width = bl.hlookup("Width",row1=row1, row2=row2)
|
|
160
170
|
length = bl.hlookup("Length",row1=row1, row2=row2)
|
|
161
171
|
height = bl.hlookup("HeightL",row1=row1, row2=row2)
|
|
162
172
|
weight = bl.hlookup("Weight",row1=row1, row2=row2)
|
|
163
173
|
parts.append(Part(part_name, width, length, height, weight))
|
|
164
|
-
|
|
165
|
-
|
|
174
|
+
```
|
|
175
|
+
First we do a couple of `lookup`s, which are vertical lookups, to scan column 1 for the given labels and return the corresponding values from column 2.
|
|
176
|
+
|
|
177
|
+
Then, there's `lookup_row`, which also scans column1 for the given label (Parts), but returns the corresponding row (5). It is then stored in row1.
|
|
178
|
+
And then we just read the following rows (with `hlookup`) and access the required values.
|
|
179
|
+
|
|
180
|
+
### Filling a block from other sources
|
|
181
|
+
|
|
182
|
+
The advantage of using a block instead of accessing these sources is, that they are one-based, just like in Excel.
|
|
183
|
+
|
|
184
|
+
It is possible to make a block from a xlrd worksheet with `block.from_xlrd_sheet`.
|
|
185
|
+
|
|
186
|
+
It is possible to make a block from a pandas dataframe with `block.from_dataframe`. Make sure that, if the dataframe is created by reading from an Excel sheet, headers=None should be specified, e.g. `df = pd.read_excel(filename, header=None)`.
|
|
187
|
+
|
|
188
|
+
It is possible to make a block from an openpyxl worksheet with `block.from_openpyxl_sheet`.
|
|
189
|
+
|
|
190
|
+
### Writing a block to an openpyxl sheet
|
|
166
191
|
|
|
167
|
-
|
|
168
|
-
|
|
192
|
+
In order to write (append) to an openpyxl sheet, use: block.to_openpyxl_sheet.
|
|
193
|
+
|
|
194
|
+
It is possible to make a block from a text file with `block.from_file`.
|
|
195
|
+
|
|
196
|
+
### Writing a block to an openpyxl sheet
|
|
169
197
|
|
|
170
198
|
## Capture stdout support
|
|
171
199
|
|
|
@@ -173,30 +201,53 @@ The module has support for capturing stdout and -later- using showing the captur
|
|
|
173
201
|
|
|
174
202
|
This is rather important as printing in xlwings lite to the UI pane is rather slow.
|
|
175
203
|
|
|
176
|
-
In order to capture stdout output,
|
|
204
|
+
In order to capture stdout output, it is required to first issue
|
|
177
205
|
|
|
206
|
+
```caoture
|
|
207
|
+
capture = xwu.Capture()
|
|
208
|
+
```
|
|
178
209
|
|
|
210
|
+
By this, capture is automatically enabled and print is disabled. Alternatively, it is possible to use
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
capture = xwu.Capture(enabled=False)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
to disable the capture. And with
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
capture = xwu.Capture(include_print=True)
|
|
179
220
|
```
|
|
180
|
-
|
|
221
|
+
|
|
222
|
+
the stdout output is captured and printed.
|
|
223
|
+
|
|
224
|
+
Capturing van be enabled and disabled at any time with `capture.enbaled = True` and `capture.enabled = False`.
|
|
225
|
+
|
|
226
|
+
And including print likewise with `capture.include_print`.
|
|
227
|
+
|
|
228
|
+
Alternatively, a context manager is provided:
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
with capture:
|
|
181
233
|
"""
|
|
182
234
|
code with print statements
|
|
183
235
|
"""
|
|
184
236
|
```
|
|
237
|
+
Note that stopping the capture, leaves the captured output in place, so it can be extended later.
|
|
185
238
|
|
|
186
|
-
|
|
239
|
+
In either case, the captured output can be then copied to a sheet, like
|
|
187
240
|
|
|
188
241
|
```
|
|
189
|
-
sheet.range(4,5).value =
|
|
242
|
+
sheet.range(4,5).value = capture.value
|
|
190
243
|
```
|
|
191
244
|
Upon reading the value, the capture buffer will be emptied.
|
|
192
245
|
|
|
193
|
-
If you don't want the buffer to be emptied after accessing the value, use `
|
|
194
|
-
|
|
195
|
-
The capture buffer can also be retrieved as a string with `xwu.capture.str` and `xwu.capture.str_keep`.
|
|
246
|
+
If you don't want the buffer to be emptied after accessing the value, use `capture.value_keep`.
|
|
196
247
|
|
|
197
|
-
|
|
248
|
+
The capture buffer can also be retrieved as a string with `capture.str` and `capture.str_keep`.
|
|
198
249
|
|
|
199
|
-
|
|
250
|
+
Clearing the captured stdout buffer can be done at any time with `capture.clear()`.
|
|
200
251
|
|
|
201
252
|
|
|
202
253
|
## Contact info
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
|
|
2
|
+
xlwings_utils/xlwings_utils.py,sha256=j0FNzIJ1eu56uk1m3T739pslbl-gL8duZY0oofXzaC4,20889
|
|
3
|
+
xlwings_utils-25.0.0.post4.dist-info/METADATA,sha256=IhzzvU8yc2eO58cjjgM-nngwqCFXl77TabmB2Mmttxc,9713
|
|
4
|
+
xlwings_utils-25.0.0.post4.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
|
5
|
+
xlwings_utils-25.0.0.post4.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
|
|
6
|
+
xlwings_utils-25.0.0.post4.dist-info/RECORD,,
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
|
|
2
|
-
xlwings_utils/xlwings_utils.py,sha256=bqy2SkFBf2GvHPLcXu1YpyLESiIHkT3rpSemruy5twc,20792
|
|
3
|
-
xlwings_utils-25.0.0.post2.dist-info/METADATA,sha256=PJyv0aEsxLn5v3V8kVtriKjl_2tjwjXXNogHjKNEMt8,8358
|
|
4
|
-
xlwings_utils-25.0.0.post2.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
|
5
|
-
xlwings_utils-25.0.0.post2.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
|
|
6
|
-
xlwings_utils-25.0.0.post2.dist-info/RECORD,,
|
|
File without changes
|