问题描述
我最近为openpyxl作了贡献,这是一个非常令人愉快的图书馆。
但是,至少对于我来说,有些方面会减慢我的最初进度,因为我不得不学习一些新工具和概念等。当然,如果您有贡献的动力,那么您会发现这些问题,但是如果有人策划了一些提示/说明/常见问题解答等,我本来可以早做的。
因此,我决定在MR 384下的openpyxl上打开一个问题(在我以文稿{-issue 1003提交,以issue 1530提交之后)。当我计划编写什么内容和以什么格式编写时,我还认为,出于一些不同的原因,也可以在stackoverflow上解决此问题。首先,当我陷入与编程相关的问题时,我总是搜索stackoverflow,因此其他人可能也会这样做。其次,在将水提交给七足动物/ openpyxl之前,这是测试水质并查看人们对此问答的一种好方法。最后,它可能使某些人有动力,不仅消耗开源和stackoverflow,而且也为他们做出了贡献:)
这是我逐步进行设置以提交到openpyxl
的逐步指南stackoverflow的优点在于,如果不清楚,可以轻松进行评论并让我知道,我应该能够在这里直接解决。因此,随着时间的流逝,答案应该会变得更好,并提供一个简单的替代渠道来询问有关openpyxl贡献的问题。
解决方法
分步进行(以下各方面的详细信息):
- 在https://foss.heptapod.net/上注册一个帐户
- 下载并安装Mercurial https://www.mercurial-scm.org/wiki/Download和hg-evolve https://pypi.org/project/hg-evolve/
- 克隆openpyxl存储库
- 请求开发者访问权限
- 阅读Python Cookbook 3rd Edition的8.13节(类型检查类,mixin等)
- 阅读代码库,尝试从诸如
open_workbook()
之类的初始方法开始,并在代码库中跟踪/跟踪它们,以了解它们是如何连接的。 - 在https://foss.heptapod.net/openpyxl/openpyxl/-/issues上选择一个问题,最好是有一些赞扬/正面评论的问题,然后自己发表评论以表示您希望实施/解决此问题。
- 阅读您要处理的零件的OOMXL规范(某些功能/文档的缺陷/改进可能不需要)
- 使用您的本地hg(
hg topic topic-name
)为该问题创建主题 - 代码-实现功能/修复错误/更新文档等。
- 编写测试(如果它是一项新功能)
- 编写文档(如果它是一项新功能)
- hg addremove和hg提交所有更改
- 推送到foss(这将触发PR / MR)
- 等待维护人员的审查,回答任何问题并提出任何要求(例如:请添加测试以覆盖xyz,尝试使文档中的演示更加真实,并确保您符合PEP-8样式等)
- 进行任何进一步的更改,例如hg addremove,hg commit,hg push
- MR被接受-恭喜!
更多详细信息:
与源代码管理有关:
- openpyxl托管在https://foss.heptapod.net/而不是github 上
- openpyxl使用Mercurial代替Git,并要求hg-evolve与pip一起安装
- Mercurial / hg使用“主题”代替分支(但它们本质上是相同的),并且您无法派生该存储库,您必须在本地克隆该存储库,然后为您的工作创建一个主题,并向其中添加和提交所有代码该主题。
- Mercurial / hg使用的命令与git不同,这是一个常见的工作流程(示例来自我的贡献):
$ hg clone https://foss.heptapod.net/openpyxl/openpyxl openpyxl $ cd openpyxl $ hg pull # not needed $ hg up 3.1 # because it's a new feature $ hg topic workbook-customDocProps # write your code... $ hg pull $ hg addremove # add any new files,and remove any you deleted $ hg forget TempScripts/** # because I added some temp scripts during investigation,not to be committed $ hg commit -m ":heavy_plus_sign: implemented wb.custom_doc_props,with tests and docs" $ hg push https://{username}:{accessToken}@foss.heptapod.net/openpyxl/openpyxl
- 这里有一些很好的帮助资源,例如:
- 您将需要创建访问令牌以推送到存储库(并且您需要使用上面显示的格式,例如
https://{username}:{accessToken}@foss.heptapod.net/openpyxl/openpyxl
推送)https://heptapod.net/pages/tuto-repo-http-access-token.html
与库本身有关:
- 这是一个很大的库,具有许多相互连接的部分,因此需要一段时间才能自行解决。
- 如果不阅读Python Cookbook 3rd Edition的8.13节,可能很难理解为了对XML进行序列化和反序列化所需要的所有类,继承和mixin等。
- 因此,为了尝试解决前面的两个要点,我尝试从与我合作的部分中尽最大可能解释该库:
-
descriptors
文件夹包含一些类,这些类启用类型系统(带有诸如Typed
之类的类),并允许在XML和XML的字符串表示形式之间进行序列化和反序列化(带有类,例如带有方法Serlializable
和to_tree()
的{{1}})。类型系统很重要,因为OOXML规范相当严格,并且因为python是动态语言,所以我们需要一种以可伸缩方式强制类型的方法。另外,由于.xlsx或.xlsm(2007年后)工作簿实际上只是一个内部包含XML文件的Zip文件,因此XML序列化和反序列化当然至关重要。 -
from_tree()
文件夹包含workbook
类,它是工作簿的python表示形式。此类的属性,对应于实际工作簿的属性 -
Workbook
文件夹包含用于存储工作簿文档属性(例如作者,创建时间等)的类 -
packaging
文件夹包含用于将工作簿从磁盘读取到内存中的类(进入reader
类) -
Workbook
文件夹包含用于将内存工作簿(在writer
类中)写入磁盘的类 -
还有更多的文件夹和类,但是在我从事这些领域的工作之前,我将不再讨论它们。但是,一旦完成,我将返回并进行更新。
在本地克隆库之后,该库的文件夹结构:
-
与Excel文件本身有关:
(仅谈论2007/10后的.xlsx和.xlsm变体)
- Open XML文件格式的规范非常干燥:http://www.ecma-international.org/news/TC45_current_work/Office%20Open%20XML%20Part%201%20-%20Fundamentals_final.docx,但是根据规范(并且不是通过反向工程示例Excel文件,正确实现新功能非常重要和必要)-尽管有时可以帮助您指向规范的正确部分,等等。)
- 您需要了解清单,rel,uuid,名称空间等如何一起工作,以将Excel工作簿(及其所有工作表,图像,图表等)存储为XML,在某些情况下还以二进制格式存储。
- 因此,为了尝试解决前面的两个要点,我尝试从与我合作的部分中尽最大可能解释OOXML格式:
-
工作簿的结构如下,这是一个相当简单的工作簿。通常,根文件夹仅包含一个文件
Workbook
,这也称为“清单”。这包含默认类型和替代类型的列表。本质上,当您向工作簿中添加越来越多的功能时,此类型列表会扩展。例如,我实现了对Workbook.CustomDocumentProperties的支持,并将它们保存在[Content_Types].xml
中,并且一旦添加一个CustomDocumentProperty,Excel就会添加此文件,但还会在清单中添加类型覆盖,以让Excel知道,这是什么类型的XML文件:docProps/custom.xml
-
此外,在根文件夹中,通常有3个子文件夹
<?xml version="1.0"?> <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/> <Default Extension="xml" ContentType="application/xml"/> <Default Extension="bin" ContentType="application/vnd.ms-office.vbaProject"/> <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/> <Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/> <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/> <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/> <Override PartName="docProps/custom.xml" ContentType="application/vnd.openxmlformats-officedocument.custom-properties+xml"/> <Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/> <Override PartName="/xl/workbook.xml" ContentType="application/vnd.ms-excel.sheet.macroEnabled.main+xml"/> </Types>
,_rels
和docProps
。文件夹xl
通常称为“根关系”或“根关系”。该文件夹包含文件_rels
,它是整个文档的XML关系文件。这些“相关”文件(或关系文件)在整个OOXML格式中都具有特征,简而言之,它们解释了如何将一个XML文件链接到另一个XML文件或二进制文件。例如,在这个简单的.xslm文件中,我们具有一些CustomDocumentProperties(可选)以及默认属性(“ docProps / core.xml”和“ docProps / app.xml”)和根rel,如下所示:_rels/.rels
-
您在上面的XML中看到,工作簿本身存储在“ xl / workbook.xml”中,因此您可以从层次结构的角度来考虑诸如
<?xml version="1.0"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Target="xl/workbook.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Id="rId1"/> <Relationship Target="docProps/core.xml" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Id="rId2"/> <Relationship Target="docProps/app.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Id="rId3"/> <Relationship Target="docProps/custom.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Id="rId4"/> </Relationships>
之类的Excel文件。每个工作簿至少需要一个工作表,就像我们在这里一样。还请注意,主题也适合层次结构,例如Document > Workbook > Worksheets
,如下面的文件夹结构所示。 -
同样,您可以推断出诸如
Document > Workbook > Themes
和Document > Styles
之类的层次结构,这意味着它们与Document > vbaProject
处于同一层次结构级别。 -
深入研究结构,您会再次看到
Workbook
文件夹,这次在_rels
处更深一层,这意味着它是Workbook.xml文件的关系:>xl/_rels/workbook.xml.rels
-
<?xml version="1.0"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="/xl/worksheets/sheet1.xml" Id="rId1"/> <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml" Id="rId2"/> <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml" Id="rId3"/> <Relationship Type="http://schemas.microsoft.com/office/2006/relationships/vbaProject" Target="vbaProject.bin" Id="rId4"/> </Relationships>
文件本身就是这样(尽管样式,主题和vbaProject不在此处列出,但上面显示的关系很重要,因此Excel知道这些文件存在):>xl/workbook.xml
-
最后,查看
<?xml version="1.0"?> <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> <workbookPr codeName="ThisWorkbook"/> <bookViews> <workbookView visibility="visible" minimized="0" showHorizontalScroll="1" showVerticalScroll="1" showSheetTabs="1" xWindow="-120" yWindow="-120" windowWidth="29040" windowHeight="15840" tabRatio="600" firstSheet="0" activeTab="0" autoFilterDateGrouping="1"/> </bookViews> <sheets> <sheet xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" name="Sheet1" sheetId="1" state="visible" r:id="rId1"/> </sheets> <definedNames/> <calcPr calcId="191029" fullCalcOnLoad="1"/> </workbook>
,我们将看到如何保存工作表数据。在这里,我们只在单元格B1中保存了“测试”一词:xl/worksheets/sheet1.xml
-
当前,Sheet1没有关系,但是随着我们向表中添加更多功能,该关系文件将在
<?xml version="1.0"?> <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> <sheetPr codeName="Sheet1"> <outlinePr summaryBelow="1" summaryRight="1"/> <pageSetUpPr/> </sheetPr> <dimension ref="B1:B1"/> <sheetViews> <sheetView tabSelected="1" workbookViewId="0"> <selection activeCell="B3" sqref="B3"/> </sheetView> </sheetViews> <sheetFormatPr baseColWidth="8" defaultRowHeight="15"/> <sheetData> <row r="1"> <c r="B1" s="1" t="inlineStr"><is><t>Test</t></is></c> </row> </sheetData> <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/> </worksheet>
处创建,并告知我们还有哪些额外的数据(如XML文件或有时是.bin)文件)与sheet1有关。如果将
xl/worksheets/_rels/sheet1.xml.rels
之类的excel文件重命名为outfile.xlsm
,则可以提取所有文件并查看OOXML文档的结构:
-