Excel2007底层实现 - 图1

  1. Excel2007是使用xml格式来存储的,把一个excel文件后缀改为.zip打开之后就直接可以看到一个excel文件对应的xml格式的文件了。

Excel2007底层实现 - 图2

1.1 docProps目录

Excel2007底层实现 - 图3

1.1.1 core.xml文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/"
  3. xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  4. <!-- 创建人 -->
  5. <dc:creator>Administrator</dc:creator>
  6. <!-- 最后修改人 -->
  7. <cp:lastModifiedBy>Administrator</cp:lastModifiedBy>
  8. <!-- 创建时间 -->
  9. <dcterms:created xsi:type="dcterms:W3CDTF">2008-09-11T17:22:52Z</dcterms:created>
  10. <!-- 修改时间 -->
  11. <dcterms:modified xsi:type="dcterms:W3CDTF">2017-03-31T15:29:39Z</dcterms:modified>
  12. </cp:coreProperties>

1.1.2 app.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" 
  xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
    <!-- 文档类型 -->
    <Application>Microsoft Excel</Application>
    <!-- 是否加密 -->
    <DocSecurity>0</DocSecurity>
    <ScaleCrop>false</ScaleCrop>
    <HeadingPairs>
        <vt:vector size="2" baseType="variant">
            <vt:variant>
                <vt:lpstr>工作表</vt:lpstr>
            </vt:variant>
            <vt:variant>
                <vt:i4>3</vt:i4>
            </vt:variant>
        </vt:vector>
    </HeadingPairs>
    <TitlesOfParts>
        <vt:vector size="3" baseType="lpstr">
            <vt:lpstr>Sheet1</vt:lpstr>
            <vt:lpstr>Sheet2</vt:lpstr>
            <vt:lpstr>Sheet3</vt:lpstr>
        </vt:vector>
    </TitlesOfParts>
    <Company/>
    <LinksUpToDate>false</LinksUpToDate>
    <!-- 是否共享 -->
    <SharedDoc>false</SharedDoc>
    <HyperlinksChanged>false</HyperlinksChanged>
    <!-- 版本 -->
    <AppVersion>12.0000</AppVersion>
</Properties>

1.2 xl目录,该目录保存的是excel中的详细内容

Excel2007底层实现 - 图4

1.2.1 workbook.xml文件:

文件包含一对标签,其中的每个元素都代表Excel2007文件中的一个sheet,工作表的名称就是name属性的值,这里有三个sheet:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" 
    xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
    <fileVersion appName="xl" lastEdited="4" lowestEdited="4" rupBuild="4506"/>
    <workbookPr defaultThemeVersion="124226"/>
    <bookViews>
        <workbookView xWindow="0" yWindow="105" windowWidth="12765" windowHeight="5715"/>
    </bookViews>
    <sheets>
        <sheet name="Sheet1" sheetId="1" r:id="rId1"/>
        <sheet name="Sheet2" sheetId="2" r:id="rId2"/>
        <sheet name="Sheet3" sheetId="3" r:id="rId3"/>
    </sheets>
    <calcPr calcId="125725"/>
</workbook>

1.2.2 _rels/workbook.xml.res:

定义每个sheetid对应的sheet内容文件sheet1.xml,共享的单元格内容文件sharedstring.xml,样式文件style.xml是当前单元格的样式字体,颜色等样式的xml配置。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
    <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet3.xml"/>
    <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet2.xml"/>
    <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>
    <Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>
    <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
    <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>
</Relationships>

worksheets文件夹保存的就是excel中的sheet

Excel2007底层实现 - 图5

1.2.3 sheet.xml文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" 
    xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
    <!-- 
        容积,即该sheet中以供占用了多大的地方,哪个单元格到哪个单元格,矩形的左上角单元格和右下角单元格
        此属性可以判断列数,如下就是:(M-A+1)
    -->
    <dimension ref="A1:M8"/>
    <!-- sheet视图的配置信息,如打开时默认选中的单元格是哪个 -->
    <sheetViews>
        <sheetView tabSelected="1" workbookViewId="0">
            <selection activeCell="G12" sqref="G12"/>
        </sheetView>
    </sheetViews>
    <!-- sheet的格式参数 -->
    <sheetFormatPr defaultRowHeight="14.25"/>
    <!-- 行中每列的配置参数 -->
    <cols>
        <col min="1" max="1" width="7.875" customWidth="1"/>
        <col min="2" max="2" width="6.75" customWidth="1"/>
        <col min="3" max="3" width="6" customWidth="1"/>
        <col min="4" max="4" width="4.5" customWidth="1"/>
        <col min="5" max="5" width="8.5" customWidth="1"/>
        <col min="6" max="6" width="9.375" customWidth="1"/>
        <col min="7" max="7" width="13.5" customWidth="1"/>
        <col min="8" max="8" width="7" customWidth="1"/>
        <col min="9" max="9" width="7.625" customWidth="1"/>
        <col min="10" max="10" width="4.625" customWidth="1"/>
        <col min="11" max="11" width="9.5" bestFit="1" customWidth="1"/>
    </cols>
    <!-- 数据区域,这个里面就是我们的单元格的相关数据信息了,是以行(Row)的方式记录的 -->
    <sheetData>
        <!-- excel中的行 -->
        <row r="1" spans="1:13">
            <!-- 
                excel中的列
                    r:单元格坐标
                    s:单元格的style,对应style.xml中cellXfs元素下的某个元素xf元素,
                      此处就是对应索引为12的元素,从0开始计算,即为第13个xf元素。
                    t:元素类型,s表示是字符串类型,对应到sharedStrings.xml中的sst元素
            -->
            <c r="A1" s="12" t="s">
                <!-- 
                    如果是t="s" 则存储的是sharedStrings.xml中sst元素下的某个si元素,此处对应索引为0的元素,即第一个si元素
                    否则,这里存储的就是单元格的值 
                -->
                <v>0</v>
            </c><c r="B1" s="12" t="s">
                <v>10</v>
            </c><c r="C1" s="12" t="s">
                <v>1</v>
            </c><c r="D1" s="12" t="s">
                <v>2</v>
            </c><c r="E1" s="12" t="s">
                <v>3</v>
            </c><c r="F1" s="12" t="s">
                <v>4</v>
            </c><c r="G1" s="12" t="s">
                <v>5</v>
            </c><c r="H1" s="12" t="s">
                <v>6</v>
            </c><c r="I1" s="12" t="s">
                <v>7</v>
            </c><c r="J1" s="12" t="s">
                <v>8</v>
            </c><c r="K1" s="12" t="s">
                <v>9</v>
            </c>
        </row>
        <row r="2" spans="1:13">
            <c r="A2" t="s">
                <v>11</v>
            </c><c r="B2" s="10" t="s">
                <v>12</v>
            </c><c r="C2" s="1">
                <v>2</v>
            </c><c r="D2" s="2" t="s">
                <v>13</v>
            </c><c r="E2" s="3" t="s">
                <v>14</v>
            </c><c r="F2" s="4">
                <v>89</v>
            </c><c r="G2" s="5">
                <v>10</v>
            </c><c r="H2" s="6">
                <v>12</v>
            </c><c r="I2" s="7">
                <v>0.2</v>
            </c><c r="J2" s="8">
                <v>0.5</v>
            </c><c r="K2" s="9">
                <v>4564645</v>
            </c><c r="L2" s="10"/>
            <c r="M2" s="11"/>
        </row>
        <row r="3" spans="1:13">
            <!-- 
                此处为什么没有A3?
                因为excel中常规列如果没有值,此处就不记录,因此在读取excel是应该特别注意,否则可能导致列错乱
            -->
            <c r="B3" s="10"/>
            <c r="C3" s="1"/>
            <c r="D3" s="2"/>
            <c r="E3" s="3"/>
            <c r="F3" s="4"/>
            <c r="G3" s="5"/>
            <c r="H3" s="6"/>
            <c r="I3" s="7"/>
            <c r="J3" s="8"/>
            <c r="K3" s="9"/>
        </row>

        <!-- 该行每列都是常规列,因此没有值的就不记录在这里 -->
        <row r="4" spans="1:13">
            <c r="A4" s="12" t="s">
                <v>15</v>
            </c>
                    <c r="E4" t="s">
                <v>16</v>
            </c>
        </row>
        <!-- 5,6,7 行都是合并再一起的单元格 -->
        <row r="5" spans="1:13">
            <!-- 合并单元格的值记录在起始单元格里,其余单元格置空 -->
            <c r="A5" s="14" t="s">
                <v>17</v>
            </c><c r="B5" s="13"/>
            <c r="C5" s="13"/>
            <c r="D5" s="13"/>
            <c r="E5" s="13"/>
            <c r="F5" s="13"/>
            <c r="G5" s="13"/>
            <c r="H5" s="13"/>
            <c r="I5" s="13"/>
            <c r="J5" s="13"/>
            <c r="K5" s="13"/>
        </row>
        <row r="6" spans="1:13">
            <c r="A6" s="13"/>
            <c r="B6" s="13"/>
            <c r="C6" s="13"/>
            <c r="D6" s="13"/>
            <c r="E6" s="13"/>
            <c r="F6" s="13"/>
            <c r="G6" s="13"/>
            <c r="H6" s="13"/>
            <c r="I6" s="13"/>
            <c r="J6" s="13"/>
            <c r="K6" s="13"/>
        </row>
        <row r="7" spans="1:13">
            <c r="A7" s="13"/>
            <c r="B7" s="13"/>
            <c r="C7" s="13"/>
            <c r="D7" s="13"/>
            <c r="E7" s="13"/>
            <c r="F7" s="13"/>
            <c r="G7" s="13"/>
            <c r="H7" s="13"/>
            <c r="I7" s="13"/>
            <c r="J7" s="13"/>
            <c r="K7" s="13"/>
        </row>
        <row r="8" spans="1:13">
            <c r="A8" s="13"/>
            <c r="B8" s="13"/>
            <c r="C8" s="13"/>
            <c r="D8" s="13"/>
            <c r="E8" s="13"/>
            <c r="F8" s="13"/>
            <c r="G8" s="13"/>
            <c r="H8" s="13"/>
            <c r="I8" s="13"/>
            <c r="J8" s="13"/>
            <c r="K8" s="13"/>
        </row>
    </sheetData>
    <!-- 这个是记录哪个到哪个是合并单元格的信息的 -->
    <mergeCells count="1">
        <!-- A5到K8被合并了 -->
        <mergeCell ref="A5:K8"/>
    </mergeCells>
    <!-- -->
    <phoneticPr fontId="1" type="noConversion"/>
    <!-- 页的相关属性设置 -->
    <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
    <!-- 分页设置 -->
    <pageSetup paperSize="9" orientation="portrait" r:id="rId1"/>
    <!-- 图形信息,由图可以看出,这里引用了draw的文档了-->
    <drawing/>
</worksheet>

1.2.4 sharedStrings.xml文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="18" uniqueCount="18">
    <!-- si存储的是字符串的值 -->
    <!-- 此处存储的是sheet.xml中c(列)中属性带有t="s"的列的值,
        带有t="s"字符串列的定位是通过c元素下的v元素中的值来定位的
        此处对应的就是v的值为0的单元格的实际值
    -->
    <si>
        <t>常规</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <!-- sheet.xml中c元素中属性t="s"的子元素<v>1</v>的单元格的实际值 -->
    <si>
        <t>数值</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>货币</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>会计专用</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>短日期</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>长日期</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>时间</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>百分比</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>分数</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>科学计数</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>文本</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>common</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>String</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>$</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>D1</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>常规A</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <r>
            <rPr>
                <sz val="11"/>
                <color theme="1"/>
                <rFont val="宋体"/>
                <family val="3"/>
                <charset val="134"/>
            </rPr><t>常规</t>
        </r><r>
            <rPr>
                <sz val="11"/>
                <color theme="1"/>
                <rFont val="Tahoma"/>
                <family val="2"/>
                <charset val="134"/>
            </rPr><t>D</t>
        </r>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
    <si>
        <t>说明: 为了简单,行数就设置的少点  
   第一行为标题行(本身是常规行),分别标注了每列的属性。
   第三行和第二行一样的列格式
   第四行为常规行</t>
        <phoneticPr fontId="1" type="noConversion"/>
    </si>
</sst>

1.2.5 style.xml文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <!-- 数字格式化显示的定义 -->
    <numFmts count="5">
        <!-- 此处的numFmtId和cellXfs中的numFmtId对应 -->
        <!-- 会计专用 -->
        <!-- 该元素表示cellXfs中xf元素的numFmtId="44"对应的格式化样式 -->
        <numFmt numFmtId="44" formatCode="_ &quot;¥&quot;* #,##0.00_ ;_ &quot;¥&quot;* \-#,##0.00_ ;_ &quot;¥&quot;* &quot;-&quot;??_ ;_ @_ "/>
        <!-- 数值格式 -->
        <numFmt numFmtId="176" formatCode="0.00_);[Red]\(0.00\)"/>
        <!-- 货币 -->
        <numFmt numFmtId="177" formatCode="&quot;¥&quot;#,##0.00_);[Red]\(&quot;¥&quot;#,##0.00\)"/>
        <!-- 长日期 -->
        <numFmt numFmtId="178" formatCode="[$-F800]dddd\,\ mmmm\ dd\,\ yyyy"/>
        <!-- 时间 -->
        <numFmt numFmtId="179" formatCode="[$-F400]h:mm:ss\ AM/PM"/>
    </numFmts>
    <!-- 字体样式 -->
    <fonts count="3">
        <font>
            <sz val="11"/>
            <color theme="1"/>
            <name val="Tahoma"/>
            <family val="2"/>
            <charset val="134"/>
        </font>
        <font>
            <sz val="9"/>
            <name val="Tahoma"/>
            <family val="2"/>
            <charset val="134"/>
        </font>
        <font>
            <sz val="11"/>
            <color theme="1"/>
            <name val="宋体"/>
            <family val="3"/>
            <charset val="134"/>
        </font>
    </fonts>
    <!-- 填充样式,包括背景色 -->
    <fills count="2">
        <fill>
            <patternFill patternType="none"/>
        </fill>
        <fill>
            <patternFill patternType="gray125"/>
        </fill>
    </fills>
    <!-- 边框 -->
    <borders count="1">
        <border>
            <left/>
            <right/>
            <top/>
            <bottom/>
            <diagonal/>
        </border>
    </borders>
    <!-- 提供给cellXfs来调用 -->
    <cellStyleXfs count="1">
        <!-- 此处的numFmtId和cellXfs中的numFmtId对应 -->
        <xf numFmtId="0" fontId="0" fillId="0" borderId="0"/>
    </cellStyleXfs>
    <!-- 真正的样式定义 -->
    <cellXfs count="15">
        <!-- 此处的numFmtId和cellStyleXfs、numFmts等中的numFmtId对应 -->
        <!-- sheet.xml中的c(列)元素属性中s的属性值都对应这里一个xf元素,s的属性值存储的就是xf的索引-->
        <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/>
        <!-- 该元素表示sheet.xml中c元素中s="1"对应的样式 -->
        <xf numFmtId="176" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
        <!-- 该元素表示sheet.xml中c元素中s="2"对应的样式 -->
        <xf numFmtId="177" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
        <xf numFmtId="44" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
        <xf numFmtId="14" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
        <xf numFmtId="178" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
        <xf numFmtId="179" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
        <xf numFmtId="10" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
        <xf numFmtId="12" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
        <xf numFmtId="11" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
        <xf numFmtId="49" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
        <xf numFmtId="13" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
        <xf numFmtId="0" fontId="2" fillId="0" borderId="0" xfId="0" applyFont="1"/>
        <xf numFmtId="0" fontId="2" fillId="0" borderId="0" xfId="0" applyFont="1" applyAlignment="1">
            <alignment horizontal="left" vertical="top"/>
        </xf>
        <xf numFmtId="0" fontId="2" fillId="0" borderId="0" xfId="0" applyFont="1" applyAlignment="1">
            <alignment horizontal="left" vertical="top" wrapText="1"/>
        </xf>
    </cellXfs>
    <cellStyles count="1">
        <cellStyle name="常规" xfId="0" builtinId="0"/>
    </cellStyles>
    <dxfs count="0"/>
    <tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleLight16"/>
</styleSheet>