Pandas 使用 xlrd 读取 Excel 文件,不幸的是 xlrd 不解析单元格中使用的格式。
openpyxl 包可以处理字符串格式,但仅适用于较旧的 .xls 格式。您可能需要编写一个查看底层 XML 数据的自定义解析器。
.xlsx 文件只是一个包含 xml 文件集合的 zip 存档。你需要看的两个是
- file.xlsx/xl/sharedStrings.xml
- file.xlsx/xl/worksheets/sheet1.xml(或您的工作表名称)
第一个文件包含字符串及其格式。第二个文件包含工作表中的单元格以及它们引用的字符串。这些字符串是按它们在 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)
您必须编写一个解析器来将格式转换为您想要的格式。