fastpyxl 1.0.0__tar.gz

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.
Files changed (208) hide show
  1. fastpyxl-1.0.0/LICENCE.rst +23 -0
  2. fastpyxl-1.0.0/PKG-INFO +73 -0
  3. fastpyxl-1.0.0/README.rst +50 -0
  4. fastpyxl-1.0.0/fastpyxl/__init__.py +19 -0
  5. fastpyxl-1.0.0/fastpyxl/_constants.py +13 -0
  6. fastpyxl-1.0.0/fastpyxl/cell/__init__.py +4 -0
  7. fastpyxl-1.0.0/fastpyxl/cell/_writer.py +136 -0
  8. fastpyxl-1.0.0/fastpyxl/cell/cell.py +341 -0
  9. fastpyxl-1.0.0/fastpyxl/cell/read_only.py +134 -0
  10. fastpyxl-1.0.0/fastpyxl/cell/rich_text.py +204 -0
  11. fastpyxl-1.0.0/fastpyxl/cell/text.py +319 -0
  12. fastpyxl-1.0.0/fastpyxl/chart/_3d.py +163 -0
  13. fastpyxl-1.0.0/fastpyxl/chart/__init__.py +19 -0
  14. fastpyxl-1.0.0/fastpyxl/chart/_chart.py +222 -0
  15. fastpyxl-1.0.0/fastpyxl/chart/area_chart.py +94 -0
  16. fastpyxl-1.0.0/fastpyxl/chart/axis.py +500 -0
  17. fastpyxl-1.0.0/fastpyxl/chart/bar_chart.py +160 -0
  18. fastpyxl-1.0.0/fastpyxl/chart/bubble_chart.py +95 -0
  19. fastpyxl-1.0.0/fastpyxl/chart/chartspace.py +277 -0
  20. fastpyxl-1.0.0/fastpyxl/chart/data_source.py +258 -0
  21. fastpyxl-1.0.0/fastpyxl/chart/descriptors.py +49 -0
  22. fastpyxl-1.0.0/fastpyxl/chart/error_bar.py +104 -0
  23. fastpyxl-1.0.0/fastpyxl/chart/label.py +140 -0
  24. fastpyxl-1.0.0/fastpyxl/chart/layout.py +132 -0
  25. fastpyxl-1.0.0/fastpyxl/chart/legend.py +87 -0
  26. fastpyxl-1.0.0/fastpyxl/chart/line_chart.py +156 -0
  27. fastpyxl-1.0.0/fastpyxl/chart/marker.py +138 -0
  28. fastpyxl-1.0.0/fastpyxl/chart/picture.py +61 -0
  29. fastpyxl-1.0.0/fastpyxl/chart/pie_chart.py +208 -0
  30. fastpyxl-1.0.0/fastpyxl/chart/pivot.py +67 -0
  31. fastpyxl-1.0.0/fastpyxl/chart/plotarea.py +202 -0
  32. fastpyxl-1.0.0/fastpyxl/chart/print_settings.py +57 -0
  33. fastpyxl-1.0.0/fastpyxl/chart/radar_chart.py +63 -0
  34. fastpyxl-1.0.0/fastpyxl/chart/reader.py +32 -0
  35. fastpyxl-1.0.0/fastpyxl/chart/reference.py +124 -0
  36. fastpyxl-1.0.0/fastpyxl/chart/scatter_chart.py +63 -0
  37. fastpyxl-1.0.0/fastpyxl/chart/series.py +269 -0
  38. fastpyxl-1.0.0/fastpyxl/chart/series_factory.py +40 -0
  39. fastpyxl-1.0.0/fastpyxl/chart/shapes.py +162 -0
  40. fastpyxl-1.0.0/fastpyxl/chart/stock_chart.py +53 -0
  41. fastpyxl-1.0.0/fastpyxl/chart/surface_chart.py +102 -0
  42. fastpyxl-1.0.0/fastpyxl/chart/text.py +69 -0
  43. fastpyxl-1.0.0/fastpyxl/chart/title.py +79 -0
  44. fastpyxl-1.0.0/fastpyxl/chart/trendline.py +132 -0
  45. fastpyxl-1.0.0/fastpyxl/chart/updown_bars.py +36 -0
  46. fastpyxl-1.0.0/fastpyxl/chartsheet/__init__.py +3 -0
  47. fastpyxl-1.0.0/fastpyxl/chartsheet/chartsheet.py +108 -0
  48. fastpyxl-1.0.0/fastpyxl/chartsheet/custom.py +69 -0
  49. fastpyxl-1.0.0/fastpyxl/chartsheet/properties.py +23 -0
  50. fastpyxl-1.0.0/fastpyxl/chartsheet/protection.py +46 -0
  51. fastpyxl-1.0.0/fastpyxl/chartsheet/publish.py +76 -0
  52. fastpyxl-1.0.0/fastpyxl/chartsheet/relation.py +94 -0
  53. fastpyxl-1.0.0/fastpyxl/chartsheet/views.py +46 -0
  54. fastpyxl-1.0.0/fastpyxl/comments/__init__.py +4 -0
  55. fastpyxl-1.0.0/fastpyxl/comments/author.py +18 -0
  56. fastpyxl-1.0.0/fastpyxl/comments/comment_sheet.py +254 -0
  57. fastpyxl-1.0.0/fastpyxl/comments/comments.py +62 -0
  58. fastpyxl-1.0.0/fastpyxl/comments/shape_writer.py +112 -0
  59. fastpyxl-1.0.0/fastpyxl/compat/__init__.py +54 -0
  60. fastpyxl-1.0.0/fastpyxl/compat/abc.py +12 -0
  61. fastpyxl-1.0.0/fastpyxl/compat/numbers.py +43 -0
  62. fastpyxl-1.0.0/fastpyxl/compat/product.py +21 -0
  63. fastpyxl-1.0.0/fastpyxl/compat/singleton.py +40 -0
  64. fastpyxl-1.0.0/fastpyxl/compat/strings.py +25 -0
  65. fastpyxl-1.0.0/fastpyxl/descriptors/__init__.py +75 -0
  66. fastpyxl-1.0.0/fastpyxl/descriptors/base.py +260 -0
  67. fastpyxl-1.0.0/fastpyxl/descriptors/container.py +44 -0
  68. fastpyxl-1.0.0/fastpyxl/descriptors/excel.py +116 -0
  69. fastpyxl-1.0.0/fastpyxl/descriptors/namespace.py +12 -0
  70. fastpyxl-1.0.0/fastpyxl/descriptors/nested.py +107 -0
  71. fastpyxl-1.0.0/fastpyxl/descriptors/sequence.py +131 -0
  72. fastpyxl-1.0.0/fastpyxl/descriptors/serialisable.py +213 -0
  73. fastpyxl-1.0.0/fastpyxl/descriptors/slots.py +22 -0
  74. fastpyxl-1.0.0/fastpyxl/drawing/__init__.py +4 -0
  75. fastpyxl-1.0.0/fastpyxl/drawing/colors.py +608 -0
  76. fastpyxl-1.0.0/fastpyxl/drawing/connector.py +147 -0
  77. fastpyxl-1.0.0/fastpyxl/drawing/drawing.py +99 -0
  78. fastpyxl-1.0.0/fastpyxl/drawing/effect.py +399 -0
  79. fastpyxl-1.0.0/fastpyxl/drawing/fill.py +404 -0
  80. fastpyxl-1.0.0/fastpyxl/drawing/geometry.py +685 -0
  81. fastpyxl-1.0.0/fastpyxl/drawing/graphic.py +169 -0
  82. fastpyxl-1.0.0/fastpyxl/drawing/image.py +68 -0
  83. fastpyxl-1.0.0/fastpyxl/drawing/line.py +237 -0
  84. fastpyxl-1.0.0/fastpyxl/drawing/picture.py +139 -0
  85. fastpyxl-1.0.0/fastpyxl/drawing/properties.py +185 -0
  86. fastpyxl-1.0.0/fastpyxl/drawing/relation.py +17 -0
  87. fastpyxl-1.0.0/fastpyxl/drawing/spreadsheet_drawing.py +391 -0
  88. fastpyxl-1.0.0/fastpyxl/drawing/text.py +977 -0
  89. fastpyxl-1.0.0/fastpyxl/drawing/xdr.py +22 -0
  90. fastpyxl-1.0.0/fastpyxl/formatting/__init__.py +3 -0
  91. fastpyxl-1.0.0/fastpyxl/formatting/formatting.py +99 -0
  92. fastpyxl-1.0.0/fastpyxl/formatting/rule.py +297 -0
  93. fastpyxl-1.0.0/fastpyxl/formula/__init__.py +3 -0
  94. fastpyxl-1.0.0/fastpyxl/formula/tokenizer.py +448 -0
  95. fastpyxl-1.0.0/fastpyxl/formula/translate.py +166 -0
  96. fastpyxl-1.0.0/fastpyxl/packaging/__init__.py +3 -0
  97. fastpyxl-1.0.0/fastpyxl/packaging/core.py +162 -0
  98. fastpyxl-1.0.0/fastpyxl/packaging/custom.py +307 -0
  99. fastpyxl-1.0.0/fastpyxl/packaging/extended.py +178 -0
  100. fastpyxl-1.0.0/fastpyxl/packaging/interface.py +62 -0
  101. fastpyxl-1.0.0/fastpyxl/packaging/manifest.py +222 -0
  102. fastpyxl-1.0.0/fastpyxl/packaging/relationship.py +158 -0
  103. fastpyxl-1.0.0/fastpyxl/packaging/workbook.py +222 -0
  104. fastpyxl-1.0.0/fastpyxl/pivot/__init__.py +1 -0
  105. fastpyxl-1.0.0/fastpyxl/pivot/cache.py +976 -0
  106. fastpyxl-1.0.0/fastpyxl/pivot/fields.py +342 -0
  107. fastpyxl-1.0.0/fastpyxl/pivot/record.py +106 -0
  108. fastpyxl-1.0.0/fastpyxl/pivot/table.py +1380 -0
  109. fastpyxl-1.0.0/fastpyxl/reader/__init__.py +1 -0
  110. fastpyxl-1.0.0/fastpyxl/reader/drawings.py +74 -0
  111. fastpyxl-1.0.0/fastpyxl/reader/excel.py +355 -0
  112. fastpyxl-1.0.0/fastpyxl/reader/strings.py +44 -0
  113. fastpyxl-1.0.0/fastpyxl/reader/workbook.py +133 -0
  114. fastpyxl-1.0.0/fastpyxl/styles/__init__.py +11 -0
  115. fastpyxl-1.0.0/fastpyxl/styles/alignment.py +125 -0
  116. fastpyxl-1.0.0/fastpyxl/styles/borders.py +147 -0
  117. fastpyxl-1.0.0/fastpyxl/styles/builtins.py +1397 -0
  118. fastpyxl-1.0.0/fastpyxl/styles/cell_style.py +222 -0
  119. fastpyxl-1.0.0/fastpyxl/styles/colors.py +228 -0
  120. fastpyxl-1.0.0/fastpyxl/styles/differential.py +95 -0
  121. fastpyxl-1.0.0/fastpyxl/styles/fills.py +283 -0
  122. fastpyxl-1.0.0/fastpyxl/styles/fonts.py +205 -0
  123. fastpyxl-1.0.0/fastpyxl/styles/named_styles.py +272 -0
  124. fastpyxl-1.0.0/fastpyxl/styles/numbers.py +200 -0
  125. fastpyxl-1.0.0/fastpyxl/styles/protection.py +17 -0
  126. fastpyxl-1.0.0/fastpyxl/styles/proxy.py +62 -0
  127. fastpyxl-1.0.0/fastpyxl/styles/styleable.py +294 -0
  128. fastpyxl-1.0.0/fastpyxl/styles/stylesheet.py +276 -0
  129. fastpyxl-1.0.0/fastpyxl/styles/table.py +129 -0
  130. fastpyxl-1.0.0/fastpyxl/typed_serialisable/__init__.py +11 -0
  131. fastpyxl-1.0.0/fastpyxl/typed_serialisable/base.py +420 -0
  132. fastpyxl-1.0.0/fastpyxl/typed_serialisable/compat.py +9 -0
  133. fastpyxl-1.0.0/fastpyxl/typed_serialisable/errors.py +14 -0
  134. fastpyxl-1.0.0/fastpyxl/typed_serialisable/field_info.py +45 -0
  135. fastpyxl-1.0.0/fastpyxl/typed_serialisable/fields.py +253 -0
  136. fastpyxl-1.0.0/fastpyxl/typed_serialisable/parse.py +30 -0
  137. fastpyxl-1.0.0/fastpyxl/typed_serialisable/render.py +25 -0
  138. fastpyxl-1.0.0/fastpyxl/utils/__init__.py +17 -0
  139. fastpyxl-1.0.0/fastpyxl/utils/bound_dictionary.py +26 -0
  140. fastpyxl-1.0.0/fastpyxl/utils/cell.py +251 -0
  141. fastpyxl-1.0.0/fastpyxl/utils/dataframe.py +84 -0
  142. fastpyxl-1.0.0/fastpyxl/utils/datetime.py +141 -0
  143. fastpyxl-1.0.0/fastpyxl/utils/escape.py +43 -0
  144. fastpyxl-1.0.0/fastpyxl/utils/exceptions.py +34 -0
  145. fastpyxl-1.0.0/fastpyxl/utils/formulas.py +24 -0
  146. fastpyxl-1.0.0/fastpyxl/utils/indexed_list.py +54 -0
  147. fastpyxl-1.0.0/fastpyxl/utils/inference.py +59 -0
  148. fastpyxl-1.0.0/fastpyxl/utils/protection.py +22 -0
  149. fastpyxl-1.0.0/fastpyxl/utils/units.py +108 -0
  150. fastpyxl-1.0.0/fastpyxl/workbook/__init__.py +4 -0
  151. fastpyxl-1.0.0/fastpyxl/workbook/_writer.py +196 -0
  152. fastpyxl-1.0.0/fastpyxl/workbook/child.py +186 -0
  153. fastpyxl-1.0.0/fastpyxl/workbook/defined_name.py +200 -0
  154. fastpyxl-1.0.0/fastpyxl/workbook/external_link/__init__.py +3 -0
  155. fastpyxl-1.0.0/fastpyxl/workbook/external_link/external.py +193 -0
  156. fastpyxl-1.0.0/fastpyxl/workbook/external_reference.py +14 -0
  157. fastpyxl-1.0.0/fastpyxl/workbook/function_group.py +31 -0
  158. fastpyxl-1.0.0/fastpyxl/workbook/properties.py +167 -0
  159. fastpyxl-1.0.0/fastpyxl/workbook/protection.py +160 -0
  160. fastpyxl-1.0.0/fastpyxl/workbook/smart_tags.py +62 -0
  161. fastpyxl-1.0.0/fastpyxl/workbook/views.py +167 -0
  162. fastpyxl-1.0.0/fastpyxl/workbook/web.py +113 -0
  163. fastpyxl-1.0.0/fastpyxl/workbook/workbook.py +498 -0
  164. fastpyxl-1.0.0/fastpyxl/worksheet/__init__.py +1 -0
  165. fastpyxl-1.0.0/fastpyxl/worksheet/_read_only.py +196 -0
  166. fastpyxl-1.0.0/fastpyxl/worksheet/_reader.py +488 -0
  167. fastpyxl-1.0.0/fastpyxl/worksheet/_write_only.py +165 -0
  168. fastpyxl-1.0.0/fastpyxl/worksheet/_writer.py +390 -0
  169. fastpyxl-1.0.0/fastpyxl/worksheet/cell_range.py +544 -0
  170. fastpyxl-1.0.0/fastpyxl/worksheet/cell_watch.py +31 -0
  171. fastpyxl-1.0.0/fastpyxl/worksheet/controls.py +100 -0
  172. fastpyxl-1.0.0/fastpyxl/worksheet/copier.py +84 -0
  173. fastpyxl-1.0.0/fastpyxl/worksheet/custom.py +31 -0
  174. fastpyxl-1.0.0/fastpyxl/worksheet/datavalidation.py +212 -0
  175. fastpyxl-1.0.0/fastpyxl/worksheet/dimensions.py +310 -0
  176. fastpyxl-1.0.0/fastpyxl/worksheet/drawing.py +15 -0
  177. fastpyxl-1.0.0/fastpyxl/worksheet/errors.py +87 -0
  178. fastpyxl-1.0.0/fastpyxl/worksheet/filters.py +422 -0
  179. fastpyxl-1.0.0/fastpyxl/worksheet/formula.py +53 -0
  180. fastpyxl-1.0.0/fastpyxl/worksheet/header_footer.py +270 -0
  181. fastpyxl-1.0.0/fastpyxl/worksheet/hyperlink.py +43 -0
  182. fastpyxl-1.0.0/fastpyxl/worksheet/merge.py +148 -0
  183. fastpyxl-1.0.0/fastpyxl/worksheet/ole.py +157 -0
  184. fastpyxl-1.0.0/fastpyxl/worksheet/page.py +170 -0
  185. fastpyxl-1.0.0/fastpyxl/worksheet/pagebreak.py +81 -0
  186. fastpyxl-1.0.0/fastpyxl/worksheet/picture.py +9 -0
  187. fastpyxl-1.0.0/fastpyxl/worksheet/print_settings.py +184 -0
  188. fastpyxl-1.0.0/fastpyxl/worksheet/properties.py +104 -0
  189. fastpyxl-1.0.0/fastpyxl/worksheet/protection.py +117 -0
  190. fastpyxl-1.0.0/fastpyxl/worksheet/related.py +16 -0
  191. fastpyxl-1.0.0/fastpyxl/worksheet/scenario.py +101 -0
  192. fastpyxl-1.0.0/fastpyxl/worksheet/smart_tag.py +82 -0
  193. fastpyxl-1.0.0/fastpyxl/worksheet/table.py +364 -0
  194. fastpyxl-1.0.0/fastpyxl/worksheet/views.py +142 -0
  195. fastpyxl-1.0.0/fastpyxl/worksheet/worksheet.py +957 -0
  196. fastpyxl-1.0.0/fastpyxl/writer/__init__.py +1 -0
  197. fastpyxl-1.0.0/fastpyxl/writer/excel.py +297 -0
  198. fastpyxl-1.0.0/fastpyxl/writer/theme.py +291 -0
  199. fastpyxl-1.0.0/fastpyxl/xml/__init__.py +42 -0
  200. fastpyxl-1.0.0/fastpyxl/xml/constants.py +129 -0
  201. fastpyxl-1.0.0/fastpyxl/xml/functions.py +111 -0
  202. fastpyxl-1.0.0/fastpyxl.egg-info/PKG-INFO +73 -0
  203. fastpyxl-1.0.0/fastpyxl.egg-info/SOURCES.txt +206 -0
  204. fastpyxl-1.0.0/fastpyxl.egg-info/dependency_links.txt +1 -0
  205. fastpyxl-1.0.0/fastpyxl.egg-info/requires.txt +1 -0
  206. fastpyxl-1.0.0/fastpyxl.egg-info/top_level.txt +1 -0
  207. fastpyxl-1.0.0/pyproject.toml +174 -0
  208. fastpyxl-1.0.0/setup.cfg +4 -0
@@ -0,0 +1,23 @@
1
+ This software is under the MIT Licence
2
+ ======================================
3
+
4
+ Copyright (c) 2010 fastpyxl
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a
7
+ copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included
15
+ in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,73 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastpyxl
3
+ Version: 1.0.0
4
+ Summary: A high-performance Python library to read/write Excel 2010 xlsx/xlsm files
5
+ Author-email: See AUTHORS <charlie.clark@clark-consulting.eu>
6
+ License-Expression: MIT
7
+ Project-URL: Documentation, https://fastpyxl.readthedocs.io/en/stable/
8
+ Project-URL: Source, https://github.com/fastpyxl/fastpyxl
9
+ Project-URL: Tracker, https://github.com/fastpyxl/fastpyxl/issues
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Operating System :: MacOS :: MacOS X
12
+ Classifier: Operating System :: Microsoft :: Windows
13
+ Classifier: Operating System :: POSIX
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/x-rst
20
+ License-File: LICENCE.rst
21
+ Requires-Dist: et_xmlfile
22
+ Dynamic: license-file
23
+
24
+ Introduction
25
+ ------------
26
+
27
+ fastpyxl is a high-performance Python library to read/write Excel 2010
28
+ xlsx/xlsm/xltx/xltm files. It is a fork of `openpyxl <https://pypi.org/project/openpyxl/>`_,
29
+ focused on optimized performance for large-scale Excel processing.
30
+
31
+ All kudos to the PHPExcel team and the openpyxl developers whose work this
32
+ project builds upon.
33
+
34
+
35
+ Security
36
+ --------
37
+
38
+ By default fastpyxl does not guard against quadratic blowup or billion laughs
39
+ xml attacks. To guard against these attacks install defusedxml.
40
+
41
+
42
+ Sample code::
43
+
44
+ from fastpyxl import Workbook
45
+ wb = Workbook()
46
+
47
+ # grab the active worksheet
48
+ ws = wb.active
49
+
50
+ # Data can be assigned directly to cells
51
+ ws['A1'] = 42
52
+
53
+ # Rows can also be appended
54
+ ws.append([1, 2, 3])
55
+
56
+ # Python types will automatically be converted
57
+ import datetime
58
+ ws['A2'] = datetime.datetime.now()
59
+
60
+ # Save the file
61
+ wb.save("sample.xlsx")
62
+
63
+
64
+ Documentation
65
+ -------------
66
+
67
+ The documentation is at: https://fastpyxl.readthedocs.io
68
+
69
+ * installation methods
70
+ * code examples
71
+ * instructions for contributing
72
+
73
+ Release notes: https://fastpyxl.readthedocs.io/en/stable/changes.html
@@ -0,0 +1,50 @@
1
+ Introduction
2
+ ------------
3
+
4
+ fastpyxl is a high-performance Python library to read/write Excel 2010
5
+ xlsx/xlsm/xltx/xltm files. It is a fork of `openpyxl <https://pypi.org/project/openpyxl/>`_,
6
+ focused on optimized performance for large-scale Excel processing.
7
+
8
+ All kudos to the PHPExcel team and the openpyxl developers whose work this
9
+ project builds upon.
10
+
11
+
12
+ Security
13
+ --------
14
+
15
+ By default fastpyxl does not guard against quadratic blowup or billion laughs
16
+ xml attacks. To guard against these attacks install defusedxml.
17
+
18
+
19
+ Sample code::
20
+
21
+ from fastpyxl import Workbook
22
+ wb = Workbook()
23
+
24
+ # grab the active worksheet
25
+ ws = wb.active
26
+
27
+ # Data can be assigned directly to cells
28
+ ws['A1'] = 42
29
+
30
+ # Rows can also be appended
31
+ ws.append([1, 2, 3])
32
+
33
+ # Python types will automatically be converted
34
+ import datetime
35
+ ws['A2'] = datetime.datetime.now()
36
+
37
+ # Save the file
38
+ wb.save("sample.xlsx")
39
+
40
+
41
+ Documentation
42
+ -------------
43
+
44
+ The documentation is at: https://fastpyxl.readthedocs.io
45
+
46
+ * installation methods
47
+ * code examples
48
+ * instructions for contributing
49
+
50
+ Release notes: https://fastpyxl.readthedocs.io/en/stable/changes.html
@@ -0,0 +1,19 @@
1
+ # Copyright (c) 2010-2024 fastpyxl
2
+
3
+ DEBUG = False
4
+
5
+ from fastpyxl.compat.numbers import NUMPY
6
+ from fastpyxl.xml import DEFUSEDXML, LXML
7
+ from fastpyxl.workbook import Workbook
8
+ from fastpyxl.reader.excel import load_workbook as open
9
+ from fastpyxl.reader.excel import load_workbook
10
+ import fastpyxl._constants as constants
11
+
12
+ # Expose constants especially the version number
13
+
14
+ __author__ = constants.__author__
15
+ __author_email__ = constants.__author_email__
16
+ __license__ = constants.__license__
17
+ __maintainer_email__ = constants.__maintainer_email__
18
+ __url__ = constants.__url__
19
+ __version__ = constants.__version__
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2010-2024 fastpyxl
2
+
3
+ """
4
+ Package metadata
5
+ """
6
+
7
+ __author__ = "See AUTHORS"
8
+ __author_email__ = "charlie.clark@clark-consulting.eu"
9
+ __license__ = "MIT"
10
+ __maintainer_email__ = "fastpyxl-users@googlegroups.com"
11
+ __url__ = "https://fastpyxl.readthedocs.io"
12
+ __version__ = "1.0.0"
13
+ __python__ = "3.8"
@@ -0,0 +1,4 @@
1
+ # Copyright (c) 2010-2024 fastpyxl
2
+
3
+ from .cell import Cell, WriteOnlyCell, MergedCell
4
+ from .read_only import ReadOnlyCell
@@ -0,0 +1,136 @@
1
+ # Copyright (c) 2010-2024 fastpyxl
2
+
3
+ from fastpyxl.compat import safe_string
4
+ from fastpyxl.xml.functions import Element, SubElement, whitespace, XML_NS
5
+ from fastpyxl import LXML
6
+ from fastpyxl.utils.datetime import to_excel, to_ISO8601
7
+ from datetime import timedelta
8
+
9
+ from fastpyxl.worksheet.formula import DataTableFormula, ArrayFormula
10
+ from fastpyxl.cell.rich_text import CellRichText
11
+
12
+ def _set_attributes(cell, styled=None):
13
+ """
14
+ Set coordinate and datatype
15
+ """
16
+ coordinate = cell.coordinate
17
+ attrs = {'r': coordinate}
18
+ if styled:
19
+ attrs['s'] = f"{cell.style_id}"
20
+
21
+ if cell.data_type == "s":
22
+ attrs['t'] = "inlineStr"
23
+ elif cell.data_type != 'f':
24
+ attrs['t'] = cell.data_type
25
+
26
+ value = cell._value
27
+
28
+ if cell.data_type == "d":
29
+ if hasattr(value, "tzinfo") and value.tzinfo is not None:
30
+ raise TypeError("Excel does not support timezones in datetimes. "
31
+ "The tzinfo in the datetime/time object must be set to None.")
32
+
33
+ if cell.parent.parent.iso_dates and not isinstance(value, timedelta):
34
+ value = to_ISO8601(value)
35
+ else:
36
+ attrs['t'] = "n"
37
+ value = to_excel(value, cell.parent.parent.epoch)
38
+
39
+ if cell.hyperlink:
40
+ cell.parent._hyperlinks.append(cell.hyperlink)
41
+
42
+ return value, attrs
43
+
44
+
45
+ def etree_write_cell(xf, worksheet, cell, styled=None):
46
+
47
+ value, attributes = _set_attributes(cell, styled)
48
+
49
+ el = Element("c", attributes)
50
+ if value is None or value == "":
51
+ xf.write(el)
52
+ return
53
+
54
+ if cell.data_type == 'f':
55
+ attrib = {}
56
+
57
+ if isinstance(value, ArrayFormula):
58
+ attrib = dict(value)
59
+ value = value.text
60
+
61
+ elif isinstance(value, DataTableFormula):
62
+ attrib = dict(value)
63
+ value = None
64
+
65
+ formula = SubElement(el, 'f', attrib)
66
+ if value is not None and not attrib.get('t') == "dataTable":
67
+ formula.text = value[1:]
68
+ value = None
69
+
70
+ if cell.data_type == 's':
71
+ if isinstance(value, CellRichText):
72
+ el.append(value.to_tree())
73
+ else:
74
+ inline_string = Element("is")
75
+ text = Element('t')
76
+ text.text = value
77
+ whitespace(text)
78
+ inline_string.append(text)
79
+ el.append(inline_string)
80
+
81
+ else:
82
+ cell_content = SubElement(el, 'v')
83
+ if value is not None:
84
+ cell_content.text = safe_string(value)
85
+
86
+ xf.write(el)
87
+
88
+
89
+ def lxml_write_cell(xf, worksheet, cell, styled=False):
90
+ value, attributes = _set_attributes(cell, styled)
91
+
92
+ if value == '' or value is None:
93
+ with xf.element("c", attributes):
94
+ return
95
+
96
+ with xf.element('c', attributes):
97
+ if cell.data_type == 'f':
98
+ attrib = {}
99
+
100
+ if isinstance(value, ArrayFormula):
101
+ attrib = dict(value)
102
+ value = value.text
103
+
104
+ elif isinstance(value, DataTableFormula):
105
+ attrib = dict(value)
106
+ value = None
107
+
108
+ with xf.element('f', attrib):
109
+ if value is not None and not attrib.get('t') == "dataTable":
110
+ xf.write(value[1:])
111
+ value = None
112
+
113
+ if cell.data_type == 's':
114
+ if isinstance(value, CellRichText):
115
+ el = value.to_tree()
116
+ xf.write(el)
117
+ else:
118
+ with xf.element("is"):
119
+ if isinstance(value, str):
120
+ attrs = {}
121
+ if value != value.strip():
122
+ attrs["{%s}space" % XML_NS] = "preserve"
123
+ el = Element("t", attrs) # lxml can't handle xml-ns
124
+ el.text = value
125
+ xf.write(el)
126
+
127
+ else:
128
+ with xf.element("v"):
129
+ if value is not None:
130
+ xf.write(safe_string(value))
131
+
132
+
133
+ if LXML:
134
+ write_cell = lxml_write_cell
135
+ else:
136
+ write_cell = etree_write_cell
@@ -0,0 +1,341 @@
1
+ # Copyright (c) 2010-2024 fastpyxl
2
+
3
+ """Manage individual cells in a spreadsheet.
4
+
5
+ The Cell class is required to know its value and type, display options,
6
+ and any other features of an Excel cell. Utilities for referencing
7
+ cells using Excel's 'A1' column/row nomenclature are also provided.
8
+
9
+ """
10
+
11
+ __docformat__ = "restructuredtext en"
12
+
13
+ # Python stdlib imports
14
+ from copy import copy
15
+ import datetime
16
+ import re
17
+ from typing import cast
18
+
19
+
20
+ from fastpyxl.compat import (
21
+ NUMERIC_TYPES,
22
+ )
23
+
24
+ from fastpyxl.utils.exceptions import IllegalCharacterError
25
+
26
+ from fastpyxl.utils import get_column_letter
27
+ from fastpyxl.styles import numbers, is_date_format, is_timedelta_format
28
+ from fastpyxl.styles.styleable import StyleableObject
29
+ from fastpyxl.worksheet.hyperlink import Hyperlink
30
+ from fastpyxl.worksheet.formula import DataTableFormula, ArrayFormula
31
+ from fastpyxl.cell.rich_text import CellRichText
32
+
33
+ # constants
34
+
35
+ TIME_TYPES = (datetime.datetime, datetime.date, datetime.time, datetime.timedelta)
36
+ TIME_FORMATS = {
37
+ datetime.datetime:numbers.FORMAT_DATE_DATETIME,
38
+ datetime.date:numbers.FORMAT_DATE_YYYYMMDD2,
39
+ datetime.time:numbers.FORMAT_DATE_TIME6,
40
+ datetime.timedelta:numbers.FORMAT_DATE_TIMEDELTA,
41
+ }
42
+
43
+ STRING_TYPES = (str, bytes, CellRichText)
44
+ KNOWN_TYPES = NUMERIC_TYPES + TIME_TYPES + STRING_TYPES + (bool, type(None))
45
+
46
+ ILLEGAL_CHARACTERS_RE = re.compile(r'[\000-\010]|[\013-\014]|[\016-\037]')
47
+ ERROR_CODES = ('#NULL!', '#DIV/0!', '#VALUE!', '#REF!', '#NAME?', '#NUM!',
48
+ '#N/A')
49
+
50
+ TYPE_STRING = 's'
51
+ TYPE_FORMULA = 'f'
52
+ TYPE_NUMERIC = 'n'
53
+ TYPE_BOOL = 'b'
54
+ TYPE_NULL = 'n'
55
+ TYPE_INLINE = 'inlineStr'
56
+ TYPE_ERROR = 'e'
57
+ TYPE_FORMULA_CACHE_STRING = 'str'
58
+
59
+ VALID_TYPES = (TYPE_STRING, TYPE_FORMULA, TYPE_NUMERIC, TYPE_BOOL,
60
+ TYPE_NULL, TYPE_INLINE, TYPE_ERROR, TYPE_FORMULA_CACHE_STRING)
61
+
62
+
63
+ _TYPES = {int:'n', float:'n', str:'s', bool:'b'}
64
+
65
+
66
+ def get_type(t, value):
67
+ if isinstance(value, NUMERIC_TYPES):
68
+ dt = 'n'
69
+ elif isinstance(value, STRING_TYPES):
70
+ dt = 's'
71
+ elif isinstance(value, TIME_TYPES):
72
+ dt = 'd'
73
+ elif isinstance(value, (DataTableFormula, ArrayFormula)):
74
+ dt = 'f'
75
+ else:
76
+ return
77
+ _TYPES[t] = dt
78
+ return dt
79
+
80
+
81
+ def get_time_format(t):
82
+ value = TIME_FORMATS.get(t)
83
+ if value:
84
+ return value
85
+ for base in t.mro()[1:]:
86
+ value = TIME_FORMATS.get(base)
87
+ if value:
88
+ TIME_FORMATS[t] = value
89
+ return value
90
+ raise ValueError("Could not get time format for {0!r}".format(value))
91
+
92
+
93
+ class Cell(StyleableObject):
94
+ """Describes cell associated properties.
95
+
96
+ Properties of interest include style, type, value, and address.
97
+
98
+ """
99
+ __slots__ = (
100
+ 'row',
101
+ 'column',
102
+ '_value',
103
+ 'data_type',
104
+ 'parent',
105
+ '_hyperlink',
106
+ '_comment',
107
+ )
108
+
109
+ def __init__(self, worksheet, row=None, column=None, value=None, style_array=None):
110
+ super().__init__(worksheet, style_array)
111
+ self.row = row
112
+ """Row number of this cell (1-based)"""
113
+ self.column = column
114
+ """Column number of this cell (1-based)"""
115
+ # _value is the stored value, while value is the displayed value
116
+ self._value = None
117
+ self._hyperlink = None
118
+ self.data_type = 'n'
119
+ if value is not None:
120
+ self.value = value
121
+ self._comment = None
122
+
123
+
124
+ @property
125
+ def coordinate(self):
126
+ """This cell's coordinate (ex. 'A5')"""
127
+ col = get_column_letter(self.column)
128
+ return f"{col}{self.row}"
129
+
130
+
131
+ @property
132
+ def col_idx(self):
133
+ """The numerical index of the column"""
134
+ return self.column
135
+
136
+
137
+ @property
138
+ def column_letter(self):
139
+ return get_column_letter(self.column)
140
+
141
+
142
+ @property
143
+ def encoding(self):
144
+ return self.parent.encoding
145
+
146
+ @property
147
+ def base_date(self):
148
+ return self.parent.parent.epoch
149
+
150
+
151
+ def __repr__(self):
152
+ return "<Cell {0!r}.{1}>".format(self.parent.title, self.coordinate)
153
+
154
+ def check_string(self, value):
155
+ """Check string coding, length, and line break character"""
156
+ if value is None:
157
+ return
158
+ # convert to str string
159
+ if not isinstance(value, str):
160
+ value = str(value, self.encoding)
161
+ value = str(value)
162
+ # string must never be longer than 32,767 characters
163
+ # truncate if necessary
164
+ value = value[:32767]
165
+ if next(ILLEGAL_CHARACTERS_RE.finditer(value), None):
166
+ raise IllegalCharacterError(f"{value} cannot be used in worksheets.")
167
+ return value
168
+
169
+ def check_error(self, value):
170
+ """Tries to convert Error" else N/A"""
171
+ try:
172
+ return str(value)
173
+ except UnicodeDecodeError:
174
+ return u'#N/A'
175
+
176
+
177
+ def _bind_value(self, value):
178
+ """Given a value, infer the correct data type"""
179
+
180
+ self.data_type = "n"
181
+ if isinstance(value, datetime.timedelta):
182
+ self._value = value.total_seconds() / 86400.0
183
+ self.data_type = "n"
184
+ self.number_format = numbers.FORMAT_DATE_TIMEDELTA
185
+ return
186
+
187
+ t = type(value)
188
+ try:
189
+ dt = _TYPES[t]
190
+ except KeyError:
191
+ dt = get_type(t, value)
192
+
193
+ if dt is None and value is not None:
194
+ raise ValueError("Cannot convert {0!r} to Excel".format(value))
195
+
196
+ if dt:
197
+ self.data_type = dt
198
+
199
+ if dt == 'd':
200
+ if not is_date_format(self.number_format):
201
+ self.number_format = get_time_format(t)
202
+
203
+ elif dt == "s" and not isinstance(value, CellRichText):
204
+ value = self.check_string(value)
205
+ if len(value) > 1 and value.startswith("="):
206
+ self.data_type = 'f'
207
+ elif value in ERROR_CODES:
208
+ self.data_type = 'e'
209
+
210
+ self._value = value
211
+
212
+
213
+ @property
214
+ def value(self):
215
+ """Get or set the value held in the cell.
216
+
217
+ :type: depends on the value (string, float, int or
218
+ :class:`datetime.datetime`)
219
+ """
220
+ return self._value
221
+
222
+ @value.setter
223
+ def value(self, value):
224
+ """Set the value and infer type and display options."""
225
+ self._bind_value(value)
226
+
227
+ @property
228
+ def internal_value(self):
229
+ """Always returns the value for excel."""
230
+ return self._value
231
+
232
+ @property
233
+ def hyperlink(self):
234
+ """Return the hyperlink target or an empty string"""
235
+ return self._hyperlink
236
+
237
+
238
+ @hyperlink.setter
239
+ def hyperlink(self, val):
240
+ """Set value and display for hyperlinks in a cell.
241
+ Automatically sets the `value` of the cell with link text,
242
+ but you can modify it afterwards by setting the `value`
243
+ property, and the hyperlink will remain.
244
+ Hyperlink is removed if set to ``None``."""
245
+ if val is None:
246
+ self._hyperlink = None
247
+ else:
248
+ if not isinstance(val, Hyperlink):
249
+ val = Hyperlink(ref="", target=val)
250
+ val.ref = self.coordinate
251
+ self._hyperlink = val
252
+ if self._value is None:
253
+ self.value = val.target or val.location
254
+
255
+
256
+ @property
257
+ def is_date(self):
258
+ """True if the value is formatted as a date
259
+
260
+ :type: bool
261
+ """
262
+ return self.data_type == 'd' or (
263
+ self.data_type == 'n'
264
+ and is_date_format(self.number_format)
265
+ and not is_timedelta_format(self.number_format)
266
+ )
267
+
268
+
269
+ def offset(self, row=0, column=0):
270
+ """Returns a cell location relative to this cell.
271
+
272
+ :param row: number of rows to offset
273
+ :type row: int
274
+
275
+ :param column: number of columns to offset
276
+ :type column: int
277
+
278
+ :rtype: :class:`fastpyxl.cell.Cell`
279
+ """
280
+ offset_column = cast(int, self.column) + column
281
+ offset_row = cast(int, self.row) + row
282
+ return self.parent.cell(column=offset_column, row=offset_row)
283
+
284
+
285
+ @property
286
+ def comment(self):
287
+ """ Returns the comment associated with this cell
288
+
289
+ :type: :class:`fastpyxl.comments.Comment`
290
+ """
291
+ return self._comment
292
+
293
+
294
+ @comment.setter
295
+ def comment(self, value):
296
+ """
297
+ Assign a comment to a cell
298
+ """
299
+
300
+ if value is not None:
301
+ if value.parent:
302
+ value = copy(value)
303
+ value.bind(self)
304
+ elif value is None and self._comment:
305
+ self._comment.unbind()
306
+ self._comment = value
307
+
308
+
309
+ class MergedCell(StyleableObject):
310
+
311
+ """
312
+ Describes the properties of a cell in a merged cell and helps to
313
+ display the borders of the merged cell.
314
+
315
+ The value of a MergedCell is always None.
316
+ """
317
+
318
+ __slots__ = ('row', 'column')
319
+
320
+ _value = None
321
+ data_type = "n"
322
+ comment = None
323
+ hyperlink = None
324
+
325
+
326
+ def __init__(self, worksheet, row=None, column=None):
327
+ super().__init__(worksheet)
328
+ self.row = row
329
+ self.column = column
330
+
331
+
332
+ def __repr__(self):
333
+ return "<MergedCell {0!r}.{1}>".format(self.parent.title, self.coordinate)
334
+
335
+ coordinate = Cell.coordinate
336
+ _comment = comment
337
+ value = _value
338
+
339
+
340
+ def WriteOnlyCell(ws=None, value=None):
341
+ return Cell(worksheet=ws, column=1, row=1, value=value)