我正在尝试从Excel文件中读取格式化文本。它由一系列反应组成,一些反应物有下标,而其他反应物有上标。我正在努力区分上标和下标。
例如,反应物是:
O2+
我想区别于
O2+
这里有一个相关的问题: Usage of unicode() and encode() functions in Python
由此,我想也许我应该将字符串转换为unicode,但是pandas似乎根本不会读取上标/下标。
答案 0 :(得分:0)
Pandas使用xlrd读取Excel文件,遗憾的是xlrd不解析单元格中使用的格式。
openpyxl包可以处理字符串格式,但仅适用于较旧的.xls格式。您可能需要编写一个查看基础XML数据的自定义解析器。
.xlsx文件只是一个包含xml文件集合的zip存档。你需要看的两个是
第一个文件包含字符串及其格式。第二个文件包含工作表中的单元格以及它们引用的字符串。字符串在sharedStrings.xml中按顺序引用。
以下是excel表示例的屏幕截图:
示例sharedStrings.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="3" uniqueCount="3">
<si>
<r>
<t>O</t>
</r>
<r>
<rPr>
<vertAlign val="subscript"/><sz val="11"/><color theme="1"/><rFont val="Calibri"/><family val="2"/><scheme val="minor" />
</rPr>
<t>2</t>
</r>
<r>
<rPr>
<vertAlign val="superscript"/><sz val="11"/><color theme="1"/><rFont val="Calibri"/><family val="2"/><scheme val="minor" />
</rPr>
<t>+</t>
</r>
</si>
<si>
<r>
<t>H</t>
</r>
<r>
<rPr>
<vertAlign val="subscript"/><sz val="11"/><color theme="1"/><rFont val="Calibri"/><family val="2"/><scheme val="minor" />
</rPr>
<t>2</t>
</r>
<r>
<rPr>
<sz val="11"/><color theme="1"/><rFont val="Calibri"/><family val="2"/><scheme val="minor" />
</rPr>
<t>O</t>
</r>
</si>
<si>
<r>
<t>O</t>
</r>
<r>
<rPr>
<vertAlign val="superscript"/><sz val="11"/><color theme="1"/><rFont val="Calibri"/><family val="2"/><scheme val="minor" />
</rPr>
<t>2+</t>
</r>
</si>
</sst>
每个<si>
元素都是一堆文本。 <r>
元素是一组字符和格式。 <t>
元素是实际字符,前面的<rPr>
元素是样式/格式。您可以区分上标和下标何时出现在<vertAlign>
元素中。
sheet1.xml的示例:
<?xml version="1.0" encoding="UTF-8"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" mc:Ignorable="x14ac">
<dimension ref="A1:A3" />
<sheetViews>
<sheetView tabSelected="1" workbookViewId="0">
<selection activeCell="A4" sqref="A4" />
</sheetView>
</sheetViews>
<sheetFormatPr defaultRowHeight="15" x14ac:dyDescent="0.25" />
<sheetData>
<row r="1" spans="1:1" ht="18.75" x14ac:dyDescent="0.35">
<c r="A1" t="s">
<v>0</v>
</c>
</row>
<row r="2" spans="1:1" ht="18" x14ac:dyDescent="0.35">
<c r="A2" t="s">
<v>1</v>
</c>
</row>
<row r="3" spans="1:1" ht="17.25" x14ac:dyDescent="0.25">
<c r="A3" t="s">
<v>2</v>
</c>
</row>
</sheetData>
<pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3" />
<pageSetup orientation="portrait" r:id="rId1" />
</worksheet>
单元格元素<c>
包含在<row>
元素中。 <v>
的值是对共享字符串的顺序/索引的引用。因此,单元格A1
具有第0个sharedString的值,该值为0
,后跟下标2
,后跟上标+
:
<si>
<r>
<t>O</t>
</r>
<r>
<rPr>
<vertAlign val="subscript"/><sz val="11"/><color theme="1"/><rFont val="Calibri"/><family val="2"/><scheme val="minor" />
</rPr>
<t>2</t>
</r>
<r>
<rPr>
<vertAlign val="superscript"/><sz val="11"/><color theme="1"/><rFont val="Calibri"/><family val="2"/><scheme val="minor" />
</rPr>
<t>+</t>
</r>
</si>
要开始解析Excel文件,您可以使用:
import zipfile
from lxml import etree
z = zipfile.ZipFile('file.xlsx')
with z.open('xl/sharedStrings.xml') as fp:
ss = etree.fromstring(fp.read())
with z.open('xl/worksheets/sheet1.xml') as fp:
sh1 = etree.fromstring(fp.read())
z.close()
# get the namespaces
ssns = ss.nsmap
if None in ssns:
ssns['none'] = ssns.pop(None)
sh1ns = sh1.nsmap
if None in sh1ns:
sh1ns['none'] = sh1ns.pop(None)
text_list = ss.xpath('//none:si', namespaces=ssns)
cell_list = sh1.xpath('//none:c', namespaces=sh1ns)
您必须编写一个解析器来将格式转换为您想要的格式。