xlwings-utils 25.0.4__py3-none-any.whl → 25.0.5.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.

@@ -5,7 +5,7 @@
5
5
  # /_/\_\|_| \_/\_/ |_||_| |_| \__, ||___/ _____ \__,_| \__||_||_||___/
6
6
  # |___/ |_____|
7
7
 
8
- __version__ = "25.0.4"
8
+ __version__ = "25.0.5"
9
9
 
10
10
 
11
11
  import dropbox
@@ -13,6 +13,7 @@ from pathlib import Path
13
13
  import os
14
14
  import sys
15
15
  import math
16
+ import base64
16
17
 
17
18
  dbx = None
18
19
  Pythonista = sys.platform == "ios"
@@ -678,7 +679,64 @@ class block:
678
679
  """
679
680
  return self.vlookup(s, row_from=row_from, row_to=row_to, column1=column1, column2=column2, default=default)
680
681
 
682
+ def decode_to_files(self):
683
+ """
684
+ decode the block with encoded file(s) to individual local files
685
+ """
686
+
687
+ row=1
688
+ while row<=self.number_of_rows:
689
+ if self[row,1] and self[row,1].startswith('<file=') and self[row,1].endswith('>'):
690
+ filename=self[row,1][6:-1]
691
+ collect=[]
692
+ row+=1
693
+ print(f"{filename=}")
694
+
695
+ while self[row,1]!='</file>':
696
+ print(f"{self[row,1]=}")
697
+
698
+ if self[row,1]:
699
+ collect.append(self[row,1])
700
+ row+=1
701
+ print(f"{collect=}")
702
+ decoded=base64.b64decode(''.join(collect))
703
+ open(filename,'wb').write(decoded)
704
+ row+=1
705
+
706
+ @classmethod
707
+ def encode_files(cls, *files):
708
+ """
709
+ make a block with the given files encoded
710
+
711
+ Parameters
712
+ ----------
713
+ files : file names (str)
714
+ files to be encoded
715
+
716
+ Returns
717
+ -------
718
+ block with encoded files : block
719
+ not minimized!
720
+ """
681
721
 
722
+ bl =cls(number_of_rows=50000, number_of_columns=1)
723
+
724
+ n = 5000 # block size
725
+ row = 1
726
+ for file in files:
727
+ bl[row, 1] = f"<file={file}>"
728
+ row += 1
729
+ b64 = base64.b64encode(open(file, "rb").read()).decode("utf-8")
730
+ while b64:
731
+ b64_n = b64[:n]
732
+ bl[row, 1] = b64_n
733
+ row += 1
734
+ b64 = b64[n:]
735
+ bl[row, 1] = f"</file>"
736
+ row+=1
737
+ return bl
738
+
739
+
682
740
  class Capture:
683
741
  """
684
742
  specifies how to capture stdout
@@ -784,7 +842,21 @@ class Capture:
784
842
  @include_print.setter
785
843
  def include_print(self, value):
786
844
  self._include_print = value
845
+
787
846
 
847
+ def trigger(sheet):
848
+ """
849
+ triggers the macro on sheet
788
850
 
851
+ Parameters
852
+ ----------
853
+ sheet : sheet
854
+ sheet to use
855
+
856
+ """
857
+
858
+ sheet["A1"].value = "=NOW()"
859
+
860
+
789
861
  if __name__ == "__main__":
790
862
  ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xlwings_utils
3
- Version: 25.0.4
3
+ Version: 25.0.5.post0
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
@@ -19,7 +19,7 @@ This module provides some useful functions to be used in xlwings (lite).
19
19
 
20
20
  ## Installation
21
21
 
22
- Just add `xlwings-utils` and `ssl` to the *requirements.txt* tab.
22
+ Just add `xlwings-utils` and `ssl` (even if `dropbox` is not used) to the *requirements.txt* tab.
23
23
 
24
24
  In the script, add
25
25
 
@@ -49,7 +49,7 @@ If an application runs under xlwings, `xwu.xlwings` will be True. False, if not.
49
49
 
50
50
  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.
51
51
 
52
- It is only possible, as of now, to use full-access Dropbox apps.
52
+ Currently, it is only possible to use full-access Dropbox apps.
53
53
 
54
54
  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. Instructions on how to get these variables can be found here.
55
55
 
@@ -86,7 +86,7 @@ xwu.write_dropbox('/downloads/file1.gif')
86
86
  ## Block support
87
87
 
88
88
  The module contains a useful 2-dimensional data structure: *block*.
89
- This can be useful to manipulate a range without accessing the range directly, which is expensive in terms of memory and execution time.
89
+ This can be useful for manipulating a range without accessing it directly, which is expensive in terms of memory and execution time.
90
90
  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.
91
91
  So, `my_block(lol)[row, col]` is roughly equivalent to `lol[row-1][col-1]`
92
92
 
@@ -136,7 +136,7 @@ for row in range(1, 10001):
136
136
  this_block[row,2]= ...
137
137
  if ...: # end condition
138
138
  break
139
- sheet.range(10,1).value = this_block.minimized().value
139
+ sheet.range((10,1)).value = this_block.minimized().value
140
140
  ```
141
141
 
142
142
  In this case, only the really processed rows are copied to the sheet.
@@ -195,11 +195,11 @@ We then read the following rows (using hlookups) and access the required values.
195
195
 
196
196
  ### Filling a block from other sources
197
197
 
198
- The advantage of using a block instead of accessing these sources is that they are one-based, just like in Excel.
198
+ The advantage of using a block instead of accessing these sources is that they are one-based, just like in Excel.
199
199
 
200
200
  It is possible to make a block from an xlrd worksheet with `block.from_xlrd_sheet`.
201
201
 
202
- It is possible to make a block from a pandas dataframe with `block.from_dataframe`. Ensure that, if the dataframe is created by reading from an Excel sheet, headers=None is specified, e.g., `df = pd.read_excel(filename, header=None)`.
202
+ It is possible to create a block from a Pandas DataFrame using `block.from_dataframe`. Ensure that, if the dataframe is created by reading from an Excel sheet, headers=None is specified, e.g., `df = pd.read_excel(filename, header=None)`.
203
203
 
204
204
  It is possible to make a block from an openpyxl worksheet with `block.from_openpyxl_sheet`.
205
205
 
@@ -235,9 +235,9 @@ capture = xwu.Capture(include_print=True)
235
235
 
236
236
  the stdout output is captured and printed.
237
237
 
238
- Capturing van be enabled and disabled at any time with `capture.enbaled = True` and `capture.enabled = False`.
238
+ Capturing can be enabled and disabled at any time with `capture.enabled = True` and `capture.enabled = False`.
239
239
 
240
- And including print likewise with `capture.include_print`.
240
+ And include print, likewise, with `capture.include_print`.
241
241
 
242
242
  Alternatively, a context manager is provided:
243
243
 
@@ -250,7 +250,7 @@ with capture:
250
250
  ```
251
251
  Note that stopping the capture, leaves the captured output in place, so it can be extended later.
252
252
 
253
- In either case, the captured output can be then copied to a sheet, like
253
+ In either case, the captured output can then be copied to a sheet, like
254
254
 
255
255
  ```
256
256
  sheet.range(4,5).value = capture.value
@@ -263,10 +263,93 @@ The capture buffer can also be retrieved as a string with `capture.str` and `cap
263
263
 
264
264
  Clearing the captured stdout buffer can be done at any time with `capture.clear()`.
265
265
 
266
+ ## Functionality for accessing local files via VBA
267
+
268
+ Currently, *xlwings Lite* does not provide access to the local file system. Therefore, xlwings_utils offers some functionality to trigger a VBA script as well as functionality to encode a file in the pyodide file system to a VBA sheet and to trigger writing the encoded file(s) to the local file system.
269
+
270
+ Note that the sheet must have a worksheet named `VBA`, and the VBA code will normally reside there.
271
+
272
+ There are three Python functions defined:
273
+
274
+ * `trigger_VBA()`
275
+ fires a VBA script, provided a VBA function is defined on the sheet, like:
276
+
277
+ ```
278
+ Sub Worksheet_Calculate()
279
+ If Me.Range("A1").Formula = "=NOW()" Then
280
+ Me.Range("A1").Value = Null
281
+ REM Code to run
282
+ End If
283
+ End Sub
284
+ ```
285
+ * `init_transfer_files()`
286
+ This should be called prior to any `transfer_file` call. It just removes all encoded files from the VBA sheet (if any)
287
+
288
+ * `transfer_file()`
289
+ Can be used to encode a file on the pyodide file system to the VBA sheet. Multiple files are allowed. The file name will be encoded on the sheet as well.
290
+
291
+ The VBA code below can be used to decode encoded file(s) and write to the local file system.
292
+
293
+ ```
294
+ Sub WriteFiles()
295
+
296
+ Dim vArr() As Byte
297
+ Dim S As String
298
+ Dim Column As Integer
299
+ Dim Row As Integer
300
+ Dim ws As Worksheet
301
+ Dim Count As Integer
302
+ Dim FileNames As String
303
+
304
+ Column = 1
305
+ Row = 1
306
+
307
+ ThisDir = ThisWorkbook.Path
308
+ Set ws = Me
309
+ Count = 0
310
+ While Row < 30000
311
+ Line = ws.Cells(Row, Column)
312
+ If InStr(Line, "<file=") = 1 And Right(Line, 1) = ">" Then
313
+ If Count <> 0 Then
314
+ FileNames = FileNames & ", "
315
+ End If
316
+ Count = Count + 1
317
+ FileNameOnly = Mid(Line, 7, Len(Line) - 7)
318
+ Filename = ThisDir & "/" & FileNameOnly
319
+ FileNames = FileNames & FileNameOnly
320
+
321
+ Row = Row + 1
322
+ S = ""
323
+ While ws.Cells(Row, Column) <> "</file>"
324
+ S = S & ws.Cells(Row, Column)
325
+ Row = Row + 1
326
+ Wend
327
+
328
+ vArr = Base64ToArray(S)
329
+
330
+ Open Filename For Binary Access Write As #1
331
+ WritePos = 1
332
+ Put #1, WritePos, vArr
333
+ Close #1
334
+ End If
335
+
336
+ Row = Row + 1
337
+
338
+ Wend
339
+ If Cells(4, 2) = "y" Then
340
+ ws.Range("A10:A1000000").Clear
341
+ End If
342
+
343
+ If Count = 0 Then
344
+ MsgBox "No files written"
345
+ Else
346
+ MsgBox "Successfully written " & Str(Count) & " file(s): " & FileNames
347
+ End If
348
+ ```
266
349
 
267
350
  ## Contact info
268
351
 
269
- You can contact Ruud van der Ham, the core developer, via ruud@salabim.org .
352
+ You can contact Ruud van der Ham, the core developer, at ruud@salabim.org.
270
353
 
271
354
  ## Badges
272
355
 
@@ -0,0 +1,6 @@
1
+ xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
2
+ xlwings_utils/xlwings_utils.py,sha256=KP4RPmEyajLF2pn9IS3QEQyYC_xBn1yNoWzdh3cqqSo,25238
3
+ xlwings_utils-25.0.5.post0.dist-info/METADATA,sha256=1amSYUkgWF76__slfIRyOpR-J-VbHjeoqmZxipWK21Q,13036
4
+ xlwings_utils-25.0.5.post0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
+ xlwings_utils-25.0.5.post0.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
6
+ xlwings_utils-25.0.5.post0.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
2
- xlwings_utils/xlwings_utils.py,sha256=LF7niTS7WnNSoJunwuhF5OYP7yVsLK70Zt59lY0SbMs,23376
3
- xlwings_utils-25.0.4.dist-info/METADATA,sha256=4pWOuXUtYWkBq4rEEDxIkmITWVECrMzh-PxdlpQ-SXc,10286
4
- xlwings_utils-25.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
- xlwings_utils-25.0.4.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
6
- xlwings_utils-25.0.4.dist-info/RECORD,,