paper-xlsx 0.1.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.
- paper_xlsx-0.1.0/AUTHORS.rst +98 -0
- paper_xlsx-0.1.0/LICENCE.rst +24 -0
- paper_xlsx-0.1.0/MANIFEST.in +7 -0
- paper_xlsx-0.1.0/PKG-INFO +190 -0
- paper_xlsx-0.1.0/README.rst +149 -0
- paper_xlsx-0.1.0/openpyxl/__init__.py +37 -0
- paper_xlsx-0.1.0/openpyxl/_constants.py +13 -0
- paper_xlsx-0.1.0/openpyxl/cell/__init__.py +4 -0
- paper_xlsx-0.1.0/openpyxl/cell/_writer.py +136 -0
- paper_xlsx-0.1.0/openpyxl/cell/cell.py +398 -0
- paper_xlsx-0.1.0/openpyxl/cell/read_only.py +136 -0
- paper_xlsx-0.1.0/openpyxl/cell/rich_text.py +202 -0
- paper_xlsx-0.1.0/openpyxl/cell/text.py +184 -0
- paper_xlsx-0.1.0/openpyxl/chart/_3d.py +105 -0
- paper_xlsx-0.1.0/openpyxl/chart/__init__.py +19 -0
- paper_xlsx-0.1.0/openpyxl/chart/_chart.py +227 -0
- paper_xlsx-0.1.0/openpyxl/chart/area_chart.py +106 -0
- paper_xlsx-0.1.0/openpyxl/chart/axis.py +401 -0
- paper_xlsx-0.1.0/openpyxl/chart/bar_chart.py +144 -0
- paper_xlsx-0.1.0/openpyxl/chart/bubble_chart.py +67 -0
- paper_xlsx-0.1.0/openpyxl/chart/chartspace.py +195 -0
- paper_xlsx-0.1.0/openpyxl/chart/data_source.py +246 -0
- paper_xlsx-0.1.0/openpyxl/chart/descriptors.py +43 -0
- paper_xlsx-0.1.0/openpyxl/chart/error_bar.py +62 -0
- paper_xlsx-0.1.0/openpyxl/chart/label.py +127 -0
- paper_xlsx-0.1.0/openpyxl/chart/layout.py +74 -0
- paper_xlsx-0.1.0/openpyxl/chart/legend.py +75 -0
- paper_xlsx-0.1.0/openpyxl/chart/line_chart.py +129 -0
- paper_xlsx-0.1.0/openpyxl/chart/marker.py +90 -0
- paper_xlsx-0.1.0/openpyxl/chart/picture.py +35 -0
- paper_xlsx-0.1.0/openpyxl/chart/pie_chart.py +177 -0
- paper_xlsx-0.1.0/openpyxl/chart/pivot.py +65 -0
- paper_xlsx-0.1.0/openpyxl/chart/plotarea.py +162 -0
- paper_xlsx-0.1.0/openpyxl/chart/print_settings.py +57 -0
- paper_xlsx-0.1.0/openpyxl/chart/radar_chart.py +55 -0
- paper_xlsx-0.1.0/openpyxl/chart/reader.py +32 -0
- paper_xlsx-0.1.0/openpyxl/chart/reference.py +124 -0
- paper_xlsx-0.1.0/openpyxl/chart/scatter_chart.py +53 -0
- paper_xlsx-0.1.0/openpyxl/chart/series.py +197 -0
- paper_xlsx-0.1.0/openpyxl/chart/series_factory.py +41 -0
- paper_xlsx-0.1.0/openpyxl/chart/shapes.py +89 -0
- paper_xlsx-0.1.0/openpyxl/chart/stock_chart.py +54 -0
- paper_xlsx-0.1.0/openpyxl/chart/surface_chart.py +119 -0
- paper_xlsx-0.1.0/openpyxl/chart/text.py +78 -0
- paper_xlsx-0.1.0/openpyxl/chart/title.py +76 -0
- paper_xlsx-0.1.0/openpyxl/chart/trendline.py +98 -0
- paper_xlsx-0.1.0/openpyxl/chart/updown_bars.py +31 -0
- paper_xlsx-0.1.0/openpyxl/chartsheet/__init__.py +3 -0
- paper_xlsx-0.1.0/openpyxl/chartsheet/chartsheet.py +109 -0
- paper_xlsx-0.1.0/openpyxl/chartsheet/custom.py +61 -0
- paper_xlsx-0.1.0/openpyxl/chartsheet/properties.py +28 -0
- paper_xlsx-0.1.0/openpyxl/chartsheet/protection.py +41 -0
- paper_xlsx-0.1.0/openpyxl/chartsheet/publish.py +58 -0
- paper_xlsx-0.1.0/openpyxl/chartsheet/relation.py +97 -0
- paper_xlsx-0.1.0/openpyxl/chartsheet/views.py +51 -0
- paper_xlsx-0.1.0/openpyxl/comments/__init__.py +4 -0
- paper_xlsx-0.1.0/openpyxl/comments/author.py +21 -0
- paper_xlsx-0.1.0/openpyxl/comments/comment_sheet.py +211 -0
- paper_xlsx-0.1.0/openpyxl/comments/comments.py +62 -0
- paper_xlsx-0.1.0/openpyxl/comments/shape_writer.py +112 -0
- paper_xlsx-0.1.0/openpyxl/compat/__init__.py +54 -0
- paper_xlsx-0.1.0/openpyxl/compat/abc.py +8 -0
- paper_xlsx-0.1.0/openpyxl/compat/numbers.py +43 -0
- paper_xlsx-0.1.0/openpyxl/compat/product.py +17 -0
- paper_xlsx-0.1.0/openpyxl/compat/singleton.py +40 -0
- paper_xlsx-0.1.0/openpyxl/compat/strings.py +25 -0
- paper_xlsx-0.1.0/openpyxl/descriptors/__init__.py +58 -0
- paper_xlsx-0.1.0/openpyxl/descriptors/base.py +272 -0
- paper_xlsx-0.1.0/openpyxl/descriptors/container.py +41 -0
- paper_xlsx-0.1.0/openpyxl/descriptors/excel.py +112 -0
- paper_xlsx-0.1.0/openpyxl/descriptors/namespace.py +12 -0
- paper_xlsx-0.1.0/openpyxl/descriptors/nested.py +129 -0
- paper_xlsx-0.1.0/openpyxl/descriptors/sequence.py +136 -0
- paper_xlsx-0.1.0/openpyxl/descriptors/serialisable.py +240 -0
- paper_xlsx-0.1.0/openpyxl/descriptors/slots.py +18 -0
- paper_xlsx-0.1.0/openpyxl/drawing/__init__.py +4 -0
- paper_xlsx-0.1.0/openpyxl/drawing/colors.py +435 -0
- paper_xlsx-0.1.0/openpyxl/drawing/connector.py +144 -0
- paper_xlsx-0.1.0/openpyxl/drawing/drawing.py +92 -0
- paper_xlsx-0.1.0/openpyxl/drawing/effect.py +407 -0
- paper_xlsx-0.1.0/openpyxl/drawing/fill.py +425 -0
- paper_xlsx-0.1.0/openpyxl/drawing/geometry.py +584 -0
- paper_xlsx-0.1.0/openpyxl/drawing/graphic.py +177 -0
- paper_xlsx-0.1.0/openpyxl/drawing/image.py +65 -0
- paper_xlsx-0.1.0/openpyxl/drawing/line.py +144 -0
- paper_xlsx-0.1.0/openpyxl/drawing/picture.py +144 -0
- paper_xlsx-0.1.0/openpyxl/drawing/properties.py +174 -0
- paper_xlsx-0.1.0/openpyxl/drawing/relation.py +17 -0
- paper_xlsx-0.1.0/openpyxl/drawing/spreadsheet_drawing.py +382 -0
- paper_xlsx-0.1.0/openpyxl/drawing/text.py +717 -0
- paper_xlsx-0.1.0/openpyxl/drawing/xdr.py +33 -0
- paper_xlsx-0.1.0/openpyxl/errors.py +102 -0
- paper_xlsx-0.1.0/openpyxl/formatting/__init__.py +3 -0
- paper_xlsx-0.1.0/openpyxl/formatting/formatting.py +114 -0
- paper_xlsx-0.1.0/openpyxl/formatting/rule.py +291 -0
- paper_xlsx-0.1.0/openpyxl/formula/__init__.py +3 -0
- paper_xlsx-0.1.0/openpyxl/formula/catalog.py +124 -0
- paper_xlsx-0.1.0/openpyxl/formula/lint.py +269 -0
- paper_xlsx-0.1.0/openpyxl/formula/tokenizer.py +446 -0
- paper_xlsx-0.1.0/openpyxl/formula/translate.py +166 -0
- paper_xlsx-0.1.0/openpyxl/oracle.py +1031 -0
- paper_xlsx-0.1.0/openpyxl/package/__init__.py +29 -0
- paper_xlsx-0.1.0/openpyxl/package/cells.py +112 -0
- paper_xlsx-0.1.0/openpyxl/package/diff.py +177 -0
- paper_xlsx-0.1.0/openpyxl/packaging/__init__.py +3 -0
- paper_xlsx-0.1.0/openpyxl/packaging/core.py +115 -0
- paper_xlsx-0.1.0/openpyxl/packaging/custom.py +289 -0
- paper_xlsx-0.1.0/openpyxl/packaging/extended.py +137 -0
- paper_xlsx-0.1.0/openpyxl/packaging/interface.py +56 -0
- paper_xlsx-0.1.0/openpyxl/packaging/manifest.py +194 -0
- paper_xlsx-0.1.0/openpyxl/packaging/relationship.py +158 -0
- paper_xlsx-0.1.0/openpyxl/packaging/workbook.py +185 -0
- paper_xlsx-0.1.0/openpyxl/pivot/__init__.py +1 -0
- paper_xlsx-0.1.0/openpyxl/pivot/cache.py +965 -0
- paper_xlsx-0.1.0/openpyxl/pivot/fields.py +326 -0
- paper_xlsx-0.1.0/openpyxl/pivot/record.py +111 -0
- paper_xlsx-0.1.0/openpyxl/pivot/table.py +1261 -0
- paper_xlsx-0.1.0/openpyxl/preserve/__init__.py +50 -0
- paper_xlsx-0.1.0/openpyxl/preserve/chartpatch.py +544 -0
- paper_xlsx-0.1.0/openpyxl/preserve/comments.py +125 -0
- paper_xlsx-0.1.0/openpyxl/preserve/crosscheck.py +159 -0
- paper_xlsx-0.1.0/openpyxl/preserve/crosspart.py +668 -0
- paper_xlsx-0.1.0/openpyxl/preserve/diffreport.py +145 -0
- paper_xlsx-0.1.0/openpyxl/preserve/drawings.py +413 -0
- paper_xlsx-0.1.0/openpyxl/preserve/emit.py +165 -0
- paper_xlsx-0.1.0/openpyxl/preserve/hygiene.py +382 -0
- paper_xlsx-0.1.0/openpyxl/preserve/inventory.py +192 -0
- paper_xlsx-0.1.0/openpyxl/preserve/ledger.py +1145 -0
- paper_xlsx-0.1.0/openpyxl/preserve/lifecycle.py +257 -0
- paper_xlsx-0.1.0/openpyxl/preserve/locate.py +198 -0
- paper_xlsx-0.1.0/openpyxl/preserve/modelmap.py +126 -0
- paper_xlsx-0.1.0/openpyxl/preserve/perception.py +415 -0
- paper_xlsx-0.1.0/openpyxl/preserve/receipts.py +108 -0
- paper_xlsx-0.1.0/openpyxl/preserve/regions.py +306 -0
- paper_xlsx-0.1.0/openpyxl/preserve/rewrite.py +324 -0
- paper_xlsx-0.1.0/openpyxl/preserve/saver.py +1128 -0
- paper_xlsx-0.1.0/openpyxl/preserve/splice.py +528 -0
- paper_xlsx-0.1.0/openpyxl/preserve/structural.py +616 -0
- paper_xlsx-0.1.0/openpyxl/preserve/styletrans.py +138 -0
- paper_xlsx-0.1.0/openpyxl/preserve/styleverbs.py +108 -0
- paper_xlsx-0.1.0/openpyxl/preserve/tables.py +424 -0
- paper_xlsx-0.1.0/openpyxl/preserve/x14.py +248 -0
- paper_xlsx-0.1.0/openpyxl/preserve/xmlscan.py +514 -0
- paper_xlsx-0.1.0/openpyxl/preserve/zipio.py +219 -0
- paper_xlsx-0.1.0/openpyxl/reader/__init__.py +1 -0
- paper_xlsx-0.1.0/openpyxl/reader/drawings.py +76 -0
- paper_xlsx-0.1.0/openpyxl/reader/excel.py +528 -0
- paper_xlsx-0.1.0/openpyxl/reader/strings.py +44 -0
- paper_xlsx-0.1.0/openpyxl/reader/workbook.py +133 -0
- paper_xlsx-0.1.0/openpyxl/styles/__init__.py +11 -0
- paper_xlsx-0.1.0/openpyxl/styles/alignment.py +62 -0
- paper_xlsx-0.1.0/openpyxl/styles/borders.py +103 -0
- paper_xlsx-0.1.0/openpyxl/styles/builtins.py +1397 -0
- paper_xlsx-0.1.0/openpyxl/styles/cell_style.py +206 -0
- paper_xlsx-0.1.0/openpyxl/styles/colors.py +172 -0
- paper_xlsx-0.1.0/openpyxl/styles/differential.py +95 -0
- paper_xlsx-0.1.0/openpyxl/styles/fills.py +224 -0
- paper_xlsx-0.1.0/openpyxl/styles/fonts.py +113 -0
- paper_xlsx-0.1.0/openpyxl/styles/named_styles.py +282 -0
- paper_xlsx-0.1.0/openpyxl/styles/numbers.py +200 -0
- paper_xlsx-0.1.0/openpyxl/styles/protection.py +17 -0
- paper_xlsx-0.1.0/openpyxl/styles/proxy.py +62 -0
- paper_xlsx-0.1.0/openpyxl/styles/styleable.py +156 -0
- paper_xlsx-0.1.0/openpyxl/styles/stylesheet.py +274 -0
- paper_xlsx-0.1.0/openpyxl/styles/table.py +94 -0
- paper_xlsx-0.1.0/openpyxl/utils/__init__.py +17 -0
- paper_xlsx-0.1.0/openpyxl/utils/bound_dictionary.py +26 -0
- paper_xlsx-0.1.0/openpyxl/utils/cell.py +240 -0
- paper_xlsx-0.1.0/openpyxl/utils/dataframe.py +87 -0
- paper_xlsx-0.1.0/openpyxl/utils/datetime.py +140 -0
- paper_xlsx-0.1.0/openpyxl/utils/escape.py +43 -0
- paper_xlsx-0.1.0/openpyxl/utils/exceptions.py +34 -0
- paper_xlsx-0.1.0/openpyxl/utils/formulas.py +24 -0
- paper_xlsx-0.1.0/openpyxl/utils/indexed_list.py +49 -0
- paper_xlsx-0.1.0/openpyxl/utils/inference.py +60 -0
- paper_xlsx-0.1.0/openpyxl/utils/protection.py +22 -0
- paper_xlsx-0.1.0/openpyxl/utils/units.py +108 -0
- paper_xlsx-0.1.0/openpyxl/workbook/__init__.py +4 -0
- paper_xlsx-0.1.0/openpyxl/workbook/_writer.py +197 -0
- paper_xlsx-0.1.0/openpyxl/workbook/child.py +168 -0
- paper_xlsx-0.1.0/openpyxl/workbook/defined_name.py +189 -0
- paper_xlsx-0.1.0/openpyxl/workbook/external_link/__init__.py +3 -0
- paper_xlsx-0.1.0/openpyxl/workbook/external_link/external.py +190 -0
- paper_xlsx-0.1.0/openpyxl/workbook/external_reference.py +18 -0
- paper_xlsx-0.1.0/openpyxl/workbook/function_group.py +36 -0
- paper_xlsx-0.1.0/openpyxl/workbook/properties.py +151 -0
- paper_xlsx-0.1.0/openpyxl/workbook/protection.py +163 -0
- paper_xlsx-0.1.0/openpyxl/workbook/smart_tags.py +56 -0
- paper_xlsx-0.1.0/openpyxl/workbook/views.py +155 -0
- paper_xlsx-0.1.0/openpyxl/workbook/web.py +98 -0
- paper_xlsx-0.1.0/openpyxl/workbook/workbook.py +921 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/__init__.py +1 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/_read_only.py +190 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/_reader.py +480 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/_write_only.py +159 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/_writer.py +390 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/cell_range.py +512 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/cell_watch.py +34 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/controls.py +107 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/copier.py +70 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/custom.py +35 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/datavalidation.py +202 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/dimensions.py +306 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/drawing.py +14 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/errors.py +93 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/filters.py +486 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/formula.py +51 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/header_footer.py +270 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/hyperlink.py +46 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/merge.py +141 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/ole.py +133 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/page.py +174 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/pagebreak.py +94 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/picture.py +8 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/print_settings.py +184 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/properties.py +97 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/protection.py +120 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/related.py +17 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/scenario.py +105 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/smart_tag.py +78 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/table.py +385 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/views.py +155 -0
- paper_xlsx-0.1.0/openpyxl/worksheet/worksheet.py +1021 -0
- paper_xlsx-0.1.0/openpyxl/writer/__init__.py +1 -0
- paper_xlsx-0.1.0/openpyxl/writer/excel.py +330 -0
- paper_xlsx-0.1.0/openpyxl/writer/theme.py +291 -0
- paper_xlsx-0.1.0/openpyxl/xml/__init__.py +42 -0
- paper_xlsx-0.1.0/openpyxl/xml/constants.py +129 -0
- paper_xlsx-0.1.0/openpyxl/xml/functions.py +87 -0
- paper_xlsx-0.1.0/paper_xlsx.egg-info/PKG-INFO +190 -0
- paper_xlsx-0.1.0/paper_xlsx.egg-info/SOURCES.txt +236 -0
- paper_xlsx-0.1.0/paper_xlsx.egg-info/dependency_links.txt +1 -0
- paper_xlsx-0.1.0/paper_xlsx.egg-info/requires.txt +1 -0
- paper_xlsx-0.1.0/paper_xlsx.egg-info/top_level.txt +1 -0
- paper_xlsx-0.1.0/pyproject.toml +3 -0
- paper_xlsx-0.1.0/setup.cfg +10 -0
- paper_xlsx-0.1.0/setup.py +104 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
This project was started by Eric Gazoni. In 2013 Charlie Clark became
|
|
2
|
+
co-maintainer of the project.
|
|
3
|
+
|
|
4
|
+
It was initially *heavily* inspired by the PHPExcel library:
|
|
5
|
+
http://www.phpexcel.net/
|
|
6
|
+
|
|
7
|
+
Thanks to all those who participate in the project (in alphabetical order):
|
|
8
|
+
|
|
9
|
+
* aceMueller
|
|
10
|
+
* Adam Lofts
|
|
11
|
+
* Adam Morris
|
|
12
|
+
* Alessandro Cucci
|
|
13
|
+
* Alex Gronholm
|
|
14
|
+
* Alexander Ley
|
|
15
|
+
* Alexandre Fayolle
|
|
16
|
+
* Amin Mirzaee
|
|
17
|
+
* Anders Chrigstrom
|
|
18
|
+
* Anthony Hayward
|
|
19
|
+
* Bernt R. Brenna
|
|
20
|
+
* Brent Hoover
|
|
21
|
+
* Brice Gelineau
|
|
22
|
+
* ccoacley
|
|
23
|
+
* Chi Ho Kwok
|
|
24
|
+
* Cory Kramer
|
|
25
|
+
* Day Barr
|
|
26
|
+
* Detlef Lannert
|
|
27
|
+
* Dieter Vandenbussche
|
|
28
|
+
* Dmitriy Chernyshov
|
|
29
|
+
* Dominik Geldmacher
|
|
30
|
+
* Don Freeman
|
|
31
|
+
* Eirikur Fannar Torfason
|
|
32
|
+
* Elias Rabel
|
|
33
|
+
* Eric Chlebek
|
|
34
|
+
* Eric Gazoni
|
|
35
|
+
* Eric Hurkman
|
|
36
|
+
* Etienne Desautels
|
|
37
|
+
* Felipe Ochoa
|
|
38
|
+
* Felix Siebeneicker
|
|
39
|
+
* Fumito Hamamura
|
|
40
|
+
* Gabi Nagy
|
|
41
|
+
* Gar Thompson
|
|
42
|
+
* Gerald Van Huffelen
|
|
43
|
+
* Greg Lehmann
|
|
44
|
+
* Heikki Junes
|
|
45
|
+
* Israel Barth Rubio
|
|
46
|
+
* Jacob Middag
|
|
47
|
+
* James Smagala
|
|
48
|
+
* JarekPS
|
|
49
|
+
* Jean Pierre Huart
|
|
50
|
+
* Jeff Holman
|
|
51
|
+
* John Woltman IV
|
|
52
|
+
* Jonathan Peirce
|
|
53
|
+
* Joseph Tate
|
|
54
|
+
* Josh Haywood
|
|
55
|
+
* Jun Omae
|
|
56
|
+
* Kay Webber
|
|
57
|
+
* Khchine Hamza
|
|
58
|
+
* Klaus Bremer
|
|
59
|
+
* Koert van der Veer
|
|
60
|
+
* Laurent Laporte
|
|
61
|
+
* Laurent Vasseur
|
|
62
|
+
* Liam Sanders
|
|
63
|
+
* Maarten De Paepe
|
|
64
|
+
* Magnus Schieder
|
|
65
|
+
* Mark Gemmill
|
|
66
|
+
* Marko Loparic
|
|
67
|
+
* Masato Yoshida
|
|
68
|
+
* Max Bolingbroke
|
|
69
|
+
* Nicholas Laver
|
|
70
|
+
* Nis Martensen
|
|
71
|
+
* Paul Joyce
|
|
72
|
+
* Paul Van Der Linden
|
|
73
|
+
* Philip Roche
|
|
74
|
+
* Primoz Godec
|
|
75
|
+
* ramn_se
|
|
76
|
+
* René Neumann
|
|
77
|
+
* Rick Rankin
|
|
78
|
+
* Samuel Loretan
|
|
79
|
+
* Sergey Pikhovkin
|
|
80
|
+
* Shekhar Gyanwali
|
|
81
|
+
* Shibukawa Yoshiki
|
|
82
|
+
* Stefan Behnel
|
|
83
|
+
* Stephane Bard
|
|
84
|
+
* Stephen Rauch
|
|
85
|
+
* Sven Burk
|
|
86
|
+
* Ted Pollari
|
|
87
|
+
* Thomas Nygards
|
|
88
|
+
* Victor Korobkovsky
|
|
89
|
+
* Waldemar Osuch
|
|
90
|
+
* Wojciech Rola
|
|
91
|
+
* Wolfgane Scherer
|
|
92
|
+
* Yaroslav Halchenko
|
|
93
|
+
* Yash Jhunjhunwala
|
|
94
|
+
* Yingjie Lan
|
|
95
|
+
* Leetao
|
|
96
|
+
|
|
97
|
+
Project logo designed by Eric Gazoni, font by claudeserieux
|
|
98
|
+
(http://www.dafont.com/profile.php?user=337503)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
This software is under the MIT Licence
|
|
2
|
+
======================================
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2010 openpyxl
|
|
5
|
+
Portions Copyright (c) 2026 Paper Instruments, Inc.
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
|
8
|
+
copy of this software and associated documentation files (the
|
|
9
|
+
"Software"), to deal in the Software without restriction, including
|
|
10
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
11
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
12
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
13
|
+
the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included
|
|
16
|
+
in all copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
19
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
20
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
21
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
22
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
23
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
24
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: paper-xlsx
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python library to read/write Excel 2010 xlsx/xlsm files
|
|
5
|
+
Home-page: https://github.com/The-LLM-Data-Company/paper-xlsx
|
|
6
|
+
Author: See AUTHORS; Paper Instruments, Inc.
|
|
7
|
+
Author-email: charlie.clark@clark-consulting.eu
|
|
8
|
+
Maintainer: Paper Instruments, Inc.
|
|
9
|
+
License: MIT
|
|
10
|
+
Project-URL: Documentation, https://openpyxl.readthedocs.io/en/stable/
|
|
11
|
+
Project-URL: Source, https://github.com/The-LLM-Data-Company/paper-xlsx
|
|
12
|
+
Project-URL: Tracker, https://github.com/The-LLM-Data-Company/paper-xlsx/issues
|
|
13
|
+
Project-URL: Upstream, https://foss.heptapod.net/openpyxl/openpyxl
|
|
14
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
15
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
16
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
17
|
+
Classifier: Operating System :: POSIX
|
|
18
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
19
|
+
Classifier: Programming Language :: Python
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
License-File: LICENCE.rst
|
|
28
|
+
Requires-Dist: et_xmlfile
|
|
29
|
+
Dynamic: author
|
|
30
|
+
Dynamic: author-email
|
|
31
|
+
Dynamic: classifier
|
|
32
|
+
Dynamic: description
|
|
33
|
+
Dynamic: home-page
|
|
34
|
+
Dynamic: license
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
Dynamic: maintainer
|
|
37
|
+
Dynamic: project-url
|
|
38
|
+
Dynamic: requires-dist
|
|
39
|
+
Dynamic: requires-python
|
|
40
|
+
Dynamic: summary
|
|
41
|
+
|
|
42
|
+
paper-xlsx
|
|
43
|
+
==========
|
|
44
|
+
|
|
45
|
+
``paper-xlsx`` is an agent-first Python library for safely inspecting and
|
|
46
|
+
editing existing Excel (``.xlsx``) files. It is a strict-superset hard fork of
|
|
47
|
+
``openpyxl`` 3.1.5 and a drop-in replacement. The distribution is renamed; the
|
|
48
|
+
import name stays ``openpyxl``, so existing code keeps working unchanged.
|
|
49
|
+
|
|
50
|
+
Why it exists
|
|
51
|
+
-------------
|
|
52
|
+
|
|
53
|
+
openpyxl is excellent at *creating* a workbook from scratch. The harder problem
|
|
54
|
+
is changing a real workbook without dropping charts or leaving formulas pointed
|
|
55
|
+
at the wrong cells. That is **silent corruption**: a file that opens fine and is
|
|
56
|
+
quietly wrong, often with numbers that still look plausible.
|
|
57
|
+
|
|
58
|
+
An agent cannot eyeball the result. It needs the workbook's structure and every
|
|
59
|
+
edit outcome as typed, machine-readable data, and it needs the library to refuse
|
|
60
|
+
rather than guess.
|
|
61
|
+
|
|
62
|
+
Safety contract
|
|
63
|
+
---------------
|
|
64
|
+
|
|
65
|
+
Preserve mode applies the shared rule: every operation either does exactly what
|
|
66
|
+
it claims or refuses atomically. ``load_workbook(path, preserve=True)`` keeps the
|
|
67
|
+
original package bytes as the source of truth. Every session has one of three
|
|
68
|
+
explicit outcomes:
|
|
69
|
+
|
|
70
|
+
* a **correct save**: your edits are spliced into the original bytes, and
|
|
71
|
+
everything untouched survives byte-identical;
|
|
72
|
+
* a **typed refusal**: an unsafe edit changes nothing on disk or in memory and
|
|
73
|
+
the exception names the remedy;
|
|
74
|
+
* a **loud warning**: a stock-mode path reports that an operation may be lossy.
|
|
75
|
+
|
|
76
|
+
``manifest``, ``model_map``, and ``locate`` expose workbook structure. Six
|
|
77
|
+
pinned JSON schemas make their results available as structured data.
|
|
78
|
+
|
|
79
|
+
Quick start
|
|
80
|
+
-----------
|
|
81
|
+
|
|
82
|
+
.. code-block:: python
|
|
83
|
+
|
|
84
|
+
from openpyxl import Workbook, load_workbook
|
|
85
|
+
|
|
86
|
+
# create a workbook with an input and a formula
|
|
87
|
+
wb = Workbook()
|
|
88
|
+
ws = wb.active
|
|
89
|
+
ws["A1"], ws["B1"] = "Growth rate", 0.05
|
|
90
|
+
ws["A2"], ws["B2"] = "Revenue", 1000
|
|
91
|
+
ws["B3"] = "=B2 * (1 + B1)"
|
|
92
|
+
wb.save("model.xlsx")
|
|
93
|
+
|
|
94
|
+
# reopen it in preserve mode: the original bytes are the source of truth
|
|
95
|
+
wb = load_workbook("model.xlsx", preserve=True)
|
|
96
|
+
|
|
97
|
+
wb.manifest().to_dict() # what's in the file, what survives a save
|
|
98
|
+
wb.model_map().to_dict() # inputs / calculations / outputs
|
|
99
|
+
wb.active.locate("Growth rate") # find a value cell by its label
|
|
100
|
+
|
|
101
|
+
wb.set_input("Growth rate", 0.07) # set an input; does not overwrite formulas
|
|
102
|
+
receipt = wb.save("model_v2.xlsx", receipt=True)
|
|
103
|
+
receipt.to_dict()["cells_changed"] # {'xl/worksheets/sheet1.xml': {'B1': 'changed'}}
|
|
104
|
+
|
|
105
|
+
Structural edits follow the same contract. ``ws.insert_rows(5)`` rewrites the
|
|
106
|
+
formulas, defined names, and chart series that point into the shifted range and
|
|
107
|
+
returns an ``AddressRemap``. If it cannot rewrite a reference safely, it refuses
|
|
108
|
+
and lists every reference that would have broken.
|
|
109
|
+
|
|
110
|
+
Computing values
|
|
111
|
+
----------------
|
|
112
|
+
|
|
113
|
+
``paper-xlsx`` does not implement formula calculation. When LibreOffice is
|
|
114
|
+
installed, the library delegates calculation to it as the oracle:
|
|
115
|
+
|
|
116
|
+
.. code-block:: python
|
|
117
|
+
|
|
118
|
+
import openpyxl.oracle as oracle
|
|
119
|
+
|
|
120
|
+
ev = wb.evaluate(set={"Sheet!B1": 0.10}, read=["Sheet!B3"])
|
|
121
|
+
ev.outputs # {'Sheet!B3': 1100}
|
|
122
|
+
ev.certification.status # did LibreOffice reproduce the file's caches?
|
|
123
|
+
oracle.write_back("model.xlsx") # write cached values after certification
|
|
124
|
+
|
|
125
|
+
Six pinned JSON schemas (``workbook_manifest``, ``model_map``, ``evaluation``,
|
|
126
|
+
``oracle_write_back``, ``edit_receipt``, ``workbook_diff``) make every result
|
|
127
|
+
machine-consumable. The **Preserve mode** guide (``doc/paper.rst``) provides the
|
|
128
|
+
complete API overview and refusal taxonomy.
|
|
129
|
+
|
|
130
|
+
Preserve mode is opt-in today: pass ``preserve=True`` per call, or set
|
|
131
|
+
``PAPER_PRESERVE_DEFAULT=1``. Preserve-by-default for the public/pandas API
|
|
132
|
+
is release-gated.
|
|
133
|
+
|
|
134
|
+
Drop-in and name map
|
|
135
|
+
--------------------
|
|
136
|
+
|
|
137
|
+
Only the distribution and repository are renamed. The importable package stays
|
|
138
|
+
``openpyxl``. This is the same distribution/import split as Pillow
|
|
139
|
+
(``pip install pillow``, ``import PIL``), and it preserves existing code,
|
|
140
|
+
snippets, and model priors. Existing code that says ``import openpyxl`` keeps
|
|
141
|
+
working unchanged, and every upstream feature is still available. Preserve mode
|
|
142
|
+
and the new API are purely additive.
|
|
143
|
+
|
|
144
|
+
* GitHub repository: ``paper-xlsx``
|
|
145
|
+
* PyPI distribution: ``paper-xlsx``
|
|
146
|
+
* Built wheel/sdist names: ``paper_xlsx-*``
|
|
147
|
+
* Python import: ``openpyxl``
|
|
148
|
+
* Fork sentinel: ``openpyxl.__paper_version__ = "0.1.0"``
|
|
149
|
+
* Upstream base: openpyxl **3.1.5** (marker tag ``paper-base``)
|
|
150
|
+
|
|
151
|
+
Upstream releases are merged (never rebased) on a roughly quarterly cadence, so
|
|
152
|
+
drop-in compatibility with openpyxl holds over time.
|
|
153
|
+
|
|
154
|
+
Installation
|
|
155
|
+
------------
|
|
156
|
+
|
|
157
|
+
This repository is private for now and publication to PyPI is gated. Install
|
|
158
|
+
from Git::
|
|
159
|
+
|
|
160
|
+
pip install "paper-xlsx @ git+https://github.com/The-LLM-Data-Company/paper-xlsx.git@main"
|
|
161
|
+
|
|
162
|
+
Verification
|
|
163
|
+
------------
|
|
164
|
+
|
|
165
|
+
::
|
|
166
|
+
|
|
167
|
+
python -c "import openpyxl; print(openpyxl.__paper_version__)"
|
|
168
|
+
|
|
169
|
+
Expected output::
|
|
170
|
+
|
|
171
|
+
0.1.0
|
|
172
|
+
|
|
173
|
+
How it's tested
|
|
174
|
+
---------------
|
|
175
|
+
|
|
176
|
+
* Upstream openpyxl's test suite runs on every change to check compatibility
|
|
177
|
+
with existing behavior.
|
|
178
|
+
* A frozen, hash-pinned fixture corpus under ``tests/paper`` includes real
|
|
179
|
+
third-party files with provenance labels, rather than only self-generated
|
|
180
|
+
fixtures.
|
|
181
|
+
* The contract harness saves and reopens before asserting, enforces an exact
|
|
182
|
+
changed-part budget and refusal atomicity, and runs a headless LibreOffice
|
|
183
|
+
load smoke.
|
|
184
|
+
|
|
185
|
+
License
|
|
186
|
+
-------
|
|
187
|
+
|
|
188
|
+
MIT, inherited from openpyxl. Original work © the openpyxl authors; fork
|
|
189
|
+
additions © Paper Instruments, Inc. The fork preserves the upstream license and
|
|
190
|
+
attribution. See ``LICENCE.rst``.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
paper-xlsx
|
|
2
|
+
==========
|
|
3
|
+
|
|
4
|
+
``paper-xlsx`` is an agent-first Python library for safely inspecting and
|
|
5
|
+
editing existing Excel (``.xlsx``) files. It is a strict-superset hard fork of
|
|
6
|
+
``openpyxl`` 3.1.5 and a drop-in replacement. The distribution is renamed; the
|
|
7
|
+
import name stays ``openpyxl``, so existing code keeps working unchanged.
|
|
8
|
+
|
|
9
|
+
Why it exists
|
|
10
|
+
-------------
|
|
11
|
+
|
|
12
|
+
openpyxl is excellent at *creating* a workbook from scratch. The harder problem
|
|
13
|
+
is changing a real workbook without dropping charts or leaving formulas pointed
|
|
14
|
+
at the wrong cells. That is **silent corruption**: a file that opens fine and is
|
|
15
|
+
quietly wrong, often with numbers that still look plausible.
|
|
16
|
+
|
|
17
|
+
An agent cannot eyeball the result. It needs the workbook's structure and every
|
|
18
|
+
edit outcome as typed, machine-readable data, and it needs the library to refuse
|
|
19
|
+
rather than guess.
|
|
20
|
+
|
|
21
|
+
Safety contract
|
|
22
|
+
---------------
|
|
23
|
+
|
|
24
|
+
Preserve mode applies the shared rule: every operation either does exactly what
|
|
25
|
+
it claims or refuses atomically. ``load_workbook(path, preserve=True)`` keeps the
|
|
26
|
+
original package bytes as the source of truth. Every session has one of three
|
|
27
|
+
explicit outcomes:
|
|
28
|
+
|
|
29
|
+
* a **correct save**: your edits are spliced into the original bytes, and
|
|
30
|
+
everything untouched survives byte-identical;
|
|
31
|
+
* a **typed refusal**: an unsafe edit changes nothing on disk or in memory and
|
|
32
|
+
the exception names the remedy;
|
|
33
|
+
* a **loud warning**: a stock-mode path reports that an operation may be lossy.
|
|
34
|
+
|
|
35
|
+
``manifest``, ``model_map``, and ``locate`` expose workbook structure. Six
|
|
36
|
+
pinned JSON schemas make their results available as structured data.
|
|
37
|
+
|
|
38
|
+
Quick start
|
|
39
|
+
-----------
|
|
40
|
+
|
|
41
|
+
.. code-block:: python
|
|
42
|
+
|
|
43
|
+
from openpyxl import Workbook, load_workbook
|
|
44
|
+
|
|
45
|
+
# create a workbook with an input and a formula
|
|
46
|
+
wb = Workbook()
|
|
47
|
+
ws = wb.active
|
|
48
|
+
ws["A1"], ws["B1"] = "Growth rate", 0.05
|
|
49
|
+
ws["A2"], ws["B2"] = "Revenue", 1000
|
|
50
|
+
ws["B3"] = "=B2 * (1 + B1)"
|
|
51
|
+
wb.save("model.xlsx")
|
|
52
|
+
|
|
53
|
+
# reopen it in preserve mode: the original bytes are the source of truth
|
|
54
|
+
wb = load_workbook("model.xlsx", preserve=True)
|
|
55
|
+
|
|
56
|
+
wb.manifest().to_dict() # what's in the file, what survives a save
|
|
57
|
+
wb.model_map().to_dict() # inputs / calculations / outputs
|
|
58
|
+
wb.active.locate("Growth rate") # find a value cell by its label
|
|
59
|
+
|
|
60
|
+
wb.set_input("Growth rate", 0.07) # set an input; does not overwrite formulas
|
|
61
|
+
receipt = wb.save("model_v2.xlsx", receipt=True)
|
|
62
|
+
receipt.to_dict()["cells_changed"] # {'xl/worksheets/sheet1.xml': {'B1': 'changed'}}
|
|
63
|
+
|
|
64
|
+
Structural edits follow the same contract. ``ws.insert_rows(5)`` rewrites the
|
|
65
|
+
formulas, defined names, and chart series that point into the shifted range and
|
|
66
|
+
returns an ``AddressRemap``. If it cannot rewrite a reference safely, it refuses
|
|
67
|
+
and lists every reference that would have broken.
|
|
68
|
+
|
|
69
|
+
Computing values
|
|
70
|
+
----------------
|
|
71
|
+
|
|
72
|
+
``paper-xlsx`` does not implement formula calculation. When LibreOffice is
|
|
73
|
+
installed, the library delegates calculation to it as the oracle:
|
|
74
|
+
|
|
75
|
+
.. code-block:: python
|
|
76
|
+
|
|
77
|
+
import openpyxl.oracle as oracle
|
|
78
|
+
|
|
79
|
+
ev = wb.evaluate(set={"Sheet!B1": 0.10}, read=["Sheet!B3"])
|
|
80
|
+
ev.outputs # {'Sheet!B3': 1100}
|
|
81
|
+
ev.certification.status # did LibreOffice reproduce the file's caches?
|
|
82
|
+
oracle.write_back("model.xlsx") # write cached values after certification
|
|
83
|
+
|
|
84
|
+
Six pinned JSON schemas (``workbook_manifest``, ``model_map``, ``evaluation``,
|
|
85
|
+
``oracle_write_back``, ``edit_receipt``, ``workbook_diff``) make every result
|
|
86
|
+
machine-consumable. The **Preserve mode** guide (``doc/paper.rst``) provides the
|
|
87
|
+
complete API overview and refusal taxonomy.
|
|
88
|
+
|
|
89
|
+
Preserve mode is opt-in today: pass ``preserve=True`` per call, or set
|
|
90
|
+
``PAPER_PRESERVE_DEFAULT=1``. Preserve-by-default for the public/pandas API
|
|
91
|
+
is release-gated.
|
|
92
|
+
|
|
93
|
+
Drop-in and name map
|
|
94
|
+
--------------------
|
|
95
|
+
|
|
96
|
+
Only the distribution and repository are renamed. The importable package stays
|
|
97
|
+
``openpyxl``. This is the same distribution/import split as Pillow
|
|
98
|
+
(``pip install pillow``, ``import PIL``), and it preserves existing code,
|
|
99
|
+
snippets, and model priors. Existing code that says ``import openpyxl`` keeps
|
|
100
|
+
working unchanged, and every upstream feature is still available. Preserve mode
|
|
101
|
+
and the new API are purely additive.
|
|
102
|
+
|
|
103
|
+
* GitHub repository: ``paper-xlsx``
|
|
104
|
+
* PyPI distribution: ``paper-xlsx``
|
|
105
|
+
* Built wheel/sdist names: ``paper_xlsx-*``
|
|
106
|
+
* Python import: ``openpyxl``
|
|
107
|
+
* Fork sentinel: ``openpyxl.__paper_version__ = "0.1.0"``
|
|
108
|
+
* Upstream base: openpyxl **3.1.5** (marker tag ``paper-base``)
|
|
109
|
+
|
|
110
|
+
Upstream releases are merged (never rebased) on a roughly quarterly cadence, so
|
|
111
|
+
drop-in compatibility with openpyxl holds over time.
|
|
112
|
+
|
|
113
|
+
Installation
|
|
114
|
+
------------
|
|
115
|
+
|
|
116
|
+
This repository is private for now and publication to PyPI is gated. Install
|
|
117
|
+
from Git::
|
|
118
|
+
|
|
119
|
+
pip install "paper-xlsx @ git+https://github.com/The-LLM-Data-Company/paper-xlsx.git@main"
|
|
120
|
+
|
|
121
|
+
Verification
|
|
122
|
+
------------
|
|
123
|
+
|
|
124
|
+
::
|
|
125
|
+
|
|
126
|
+
python -c "import openpyxl; print(openpyxl.__paper_version__)"
|
|
127
|
+
|
|
128
|
+
Expected output::
|
|
129
|
+
|
|
130
|
+
0.1.0
|
|
131
|
+
|
|
132
|
+
How it's tested
|
|
133
|
+
---------------
|
|
134
|
+
|
|
135
|
+
* Upstream openpyxl's test suite runs on every change to check compatibility
|
|
136
|
+
with existing behavior.
|
|
137
|
+
* A frozen, hash-pinned fixture corpus under ``tests/paper`` includes real
|
|
138
|
+
third-party files with provenance labels, rather than only self-generated
|
|
139
|
+
fixtures.
|
|
140
|
+
* The contract harness saves and reopens before asserting, enforces an exact
|
|
141
|
+
changed-part budget and refusal atomicity, and runs a headless LibreOffice
|
|
142
|
+
load smoke.
|
|
143
|
+
|
|
144
|
+
License
|
|
145
|
+
-------
|
|
146
|
+
|
|
147
|
+
MIT, inherited from openpyxl. Original work © the openpyxl authors; fork
|
|
148
|
+
additions © Paper Instruments, Inc. The fork preserves the upstream license and
|
|
149
|
+
attribution. See ``LICENCE.rst``.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Copyright (c) 2010-2024 openpyxl
|
|
2
|
+
|
|
3
|
+
"""paper-xlsx — Paper Instruments' hard fork of openpyxl for LOSSLESS,
|
|
4
|
+
SAFE editing of existing Excel files.
|
|
5
|
+
|
|
6
|
+
The import name stays ``openpyxl`` so existing code is unchanged. The
|
|
7
|
+
fork adds a **preserve mode**: ``load_workbook(path, preserve=True)``
|
|
8
|
+
keeps the original package bytes as the source of truth, so saving
|
|
9
|
+
splices your edits back in without destroying the charts, pivots, VBA,
|
|
10
|
+
or formatting a normal openpyxl round-trip drops — and any edit it
|
|
11
|
+
cannot make safely refuses loudly (a typed :mod:`openpyxl.errors`
|
|
12
|
+
exception) instead of corrupting the file.
|
|
13
|
+
|
|
14
|
+
Start here: :attr:`openpyxl.__paper_version__` (fork sentinel), and the
|
|
15
|
+
:mod:`openpyxl.preserve`, :mod:`openpyxl.oracle` and
|
|
16
|
+
:mod:`openpyxl.errors` modules. The project README and ``doc/paper.rst``
|
|
17
|
+
give the full tour.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
DEBUG = False
|
|
21
|
+
|
|
22
|
+
from openpyxl.compat.numbers import NUMPY
|
|
23
|
+
from openpyxl.xml import DEFUSEDXML, LXML
|
|
24
|
+
from openpyxl.workbook import Workbook
|
|
25
|
+
from openpyxl.reader.excel import load_workbook as open
|
|
26
|
+
from openpyxl.reader.excel import load_workbook
|
|
27
|
+
import openpyxl._constants as constants
|
|
28
|
+
|
|
29
|
+
# Expose constants especially the version number
|
|
30
|
+
|
|
31
|
+
__author__ = constants.__author__
|
|
32
|
+
__author_email__ = constants.__author_email__
|
|
33
|
+
__license__ = constants.__license__
|
|
34
|
+
__maintainer_email__ = constants.__maintainer_email__
|
|
35
|
+
__url__ = constants.__url__
|
|
36
|
+
__version__ = constants.__version__
|
|
37
|
+
__paper_version__ = "0.1.0"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Copyright (c) 2010-2024 openpyxl
|
|
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__ = "openpyxl-users@googlegroups.com"
|
|
11
|
+
__url__ = "https://github.com/The-LLM-Data-Company/paper-xlsx"
|
|
12
|
+
__version__ = "3.1.5"
|
|
13
|
+
__python__ = "3.8"
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Copyright (c) 2010-2024 openpyxl
|
|
2
|
+
|
|
3
|
+
from openpyxl.compat import safe_string
|
|
4
|
+
from openpyxl.xml.functions import Element, SubElement, whitespace, XML_NS
|
|
5
|
+
from openpyxl import LXML
|
|
6
|
+
from openpyxl.utils.datetime import to_excel, to_ISO8601
|
|
7
|
+
from datetime import timedelta
|
|
8
|
+
|
|
9
|
+
from openpyxl.worksheet.formula import DataTableFormula, ArrayFormula
|
|
10
|
+
from openpyxl.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
|