基於 DocumentFormat.OpenXml 操作 Excel (2)-- 文檔結構


  上一節初步使用了OpenXML 的SDK , DocumentFormat.OpenXml 來操作生成一個Excel ,為了更好的理解這個類庫的使用,需要大致了解一個Excel文檔的基本結構。 而操作這個以及這個類庫里面大致常用類的組織方式。

  在OpenXML 的SDK 中,SpreadsheetDocument 類,表示 Excel 文檔包。要操作Excel,都需要基於它來創建 的一個實例,然后來操作。其中操作Excel的時候,大多數要用到的類型及其關系如下圖所示:

 

  以上只是展示部分類型,還有一些其它的不怎么用的類型沒有展示如 代表主題ThemePart,代表對話框表格DialogsheetPart 等等。 另外我們新建一個Excel文檔TestExcelFile.xlsx】,輸入幾個單元格數據, 表頭姓名和班級,微軟雅黑字體,加粗和居中,同時增加三行數據。保存后,修改后綴名為zip, 並且解壓來對比查看。 這里需要注意,用office excel軟件 和 wps 軟件,創建的excel文件,會不大一樣的,因為軟件初始化的時候是不一樣,給默認excel保存的東西也是不一樣。

  具體如下圖所示:

   

  接下來,通過上面第一張關於OpenXML SDK 中類的關系圖,和第二張圖所展示的解壓縮后的Excel信息 來一起對比看看。

 --》Excel 文件 與 SpreadsheetDocument 類型

  SpreadsheetDocument 就表示一個Excel文檔包(不止是xlsx,也可以是xlsm等其它excel文件類型), 一個Excel文檔,它內部是由多個部件來組成的。而[Content_Types].xml 這個文件,包含了這個Excel文檔包里所有相關部件的關聯信息,這個里面包含了有什么部件,每個部件放在什么文件,而它的內容類型是什么。

具體內容如下:

 1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 2 <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
 3     <Default Extension="bin" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"/>
 4     <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
 5     <Default Extension="xml" ContentType="application/xml"/>
 6     <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
 7     <Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
 8     <Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>
 9     <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
10     <Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
11     <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
12     <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
13     <Override PartName="/docProps/custom.xml" ContentType="application/vnd.openxmlformats-officedocument.custom-properties+xml"/>
14 </Types>

  在DocumentFormat.OpenXml 這個SDK里面,包含了很多類后面會有一個Part結尾,比如WorkbookPartWorksheetPart WorkbookStylesPart 等等,這種就表示一個Excel文檔里面的其中一個部件,而部件是有層級關聯的,部件包含子部件。比如 WorkbookPart 是基於 SpreadsheetDocument , 而 WorksheetPart 是基於 WorkbookPart; 而每一個Part都有一個對應的XML文件來描述這個部件的整體信息,通過xml元素來描述部件的內容,而這些部件最終結合起來,成為我們看到的Excel文檔。

 --》workbook.xml 文件 與 WorkbookPart 類型

  SpreadsheetDocument 下一般會創建一個關鍵部件,就是WorkbookPart ,代表工作簿,對應的就是在解壓后的文件里面的xl文件夾里面的workbook.xml文件。而通常WorkbookPart 里面的還需要創建一個Workbook對象( workbookpart.Workbook = new Workbook() )。那么Workbook WorkbookPart 之間的聯系是什么呢? WorkbookPart 有一個對應的xml文件來描述它,那么Workbook 就是這個xml文件的根節點

打開workbook.xml文件,如下

 1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 2 <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
 3     xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
 4     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x15"
 5     xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">
 6     <fileVersion appName="xl" lastEdited="6" lowestEdited="6" rupBuild="14420"/>
 7     <workbookPr filterPrivacy="1" defaultThemeVersion="164011"/>
 8     <bookViews>
 9         <workbookView xWindow="0" yWindow="0" windowWidth="22260" windowHeight="12645"/>
10     </bookViews>
11     <sheets>
12         <sheet name="Sheet1" sheetId="1" r:id="rId1"/>
13     </sheets>
14     <calcPr calcId="162913"/>
15     <extLst>
16         <ext uri="{140A7094-0E35-4892-8432-C4D2E57EDEB5}"
17             xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">
18             <x15:workbookPr chartTrackingRefBase="1"/>
19         </ext>
20     </extLst>
21 </workbook>

  workbook.xml文件,根節點就是對應代碼中的Workbook類對象。每個元素節點,都會有對應的類型,比如sheets節點元素,對應 Sheets 類型,而 sheet節點元素,對應Sheet 類型,一般元素節點名稱 和 對應的對象類型名稱都一致,但是也不一定是,有時候元素節點是縮寫,簡寫之類的,比如上面的 calcPr 節點元素,對應則是 CalculationProperties 類。

  workbook 元素下面,很多子元素,每一個元素作用,則需要查詢微軟的文檔,和對應的Open XML 標准說明,才能知道。 但是我們做功能導入導出,一般涉及到的,無非是 sheets節點元素和其下的sheet節點元素 。 上一節中,已經針對節點對應的 Sheets 類型 和 Sheet 類型做過了說明,下面再詳細說明一次。

  Sheets 類型對應XML里面 sheets節點元素,它作用就是類似數組和列表;而Sheet 類型,對應sheet節點元素 , 表示一個工作簿中用到的表,一般情況下,我們常用的一個是 工作表(WorkSheet),還有可能會用到的就是圖表(ChartSheet)了。而由於這些表的定義比較復雜,所以Excel中,都是一個獨立的部件(有單獨的xml來描述)存在。 而這里的sheet 就只是一個關聯關系,有對應表展示的名字,表的Id,所關聯的代表具體表的部件,和表的類型是什么,默認情況下沒有type屬性,就是工作表(WorkSheet)。

 --》Excel 文件 與 SpreadsheetDocument 類型

  既然說了Sheet,就來看看這個WorksheetPart 類型,這個部件屬於WorkbookPart 子部件,它需要通過WorksheetPart 類型對象來創建(語法:workbookPart.AddNewPart<WorksheetPart>();),並且可以創建多個。在上圖中所示,xl文件夾中,有一個worksheets文件夾,里面會存在多個XML文件,每一個XML文件描述一個WorksheetPart部件的信息, 而 打開Sheet1.xml查閱其信息, XML根節點元素是 worksheet ,對應我們的類型就是 Worksheet類,其子元素有 sheetViews,sheetFormatPr ,sheetData等等。

具體的XML可以看看下面代碼:

 1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 2 <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
 3     xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
 4     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac"
 5     xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
 6     <dimension ref="A1:B4"/>
 7     <sheetViews>
 8         <sheetView tabSelected="1" workbookViewId="0"/>
 9     </sheetViews>
10     <sheetFormatPr defaultRowHeight="14.25" x14ac:dyDescent="0.2"/>
11     <sheetData>
12         <row r="1" spans="1:2" ht="15" x14ac:dyDescent="0.25">
13             <c r="A1" s="1" t="s">
14                 <v>0</v>
15             </c>
16             <c r="B1" s="1" t="s">
17                 <v>1</v>
18             </c>
19         </row>
20         <row r="2" spans="1:2" x14ac:dyDescent="0.2">
21             <c r="A2" t="s">
22                 <v>2</v>
23             </c>
24             <c r="B2" t="s">
25                 <v>3</v>
26             </c>
27         </row>
28         <row r="3" spans="1:2" x14ac:dyDescent="0.2">
29             <c r="A3" t="s">
30                 <v>5</v>
31             </c>
32             <c r="B3" t="s">
33                 <v>3</v>
34             </c>
35         </row>
36         <row r="4" spans="1:2" x14ac:dyDescent="0.2">
37             <c r="A4" t="s">
38                 <v>6</v>
39             </c>
40             <c r="B4" t="s">
41                 <v>4</v>
42             </c>
43         </row>
44     </sheetData>
45     <phoneticPr fontId="1" type="noConversion"/>
46     <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
47     <pageSetup paperSize="9" orientation="portrait" horizontalDpi="300" verticalDpi="300" r:id="rId1"/>
48 </worksheet>

  從上面的這個XML文檔, worksheet根節點元素,表示一個工作表,其子元素就是構造這個工作表的主要部分。

  簡單敘述下幾個節點的意義:

   (1) dimension 節點元素: 對應類型SheetDimension類型,表示維度,工作表維度,工作表中使用的單元格的行和列的邊界。一般可以理解為你在工作表中,輸入的所有數據中,使用到最大的列,使用的最大的行數,所形成的一個四方形區間。

   (2) sheetViews 節點元素: 對應類型SheetViews類型,工作表視圖定義,一般用它表示當前工作表選擇的部分,比如你光標所在的位置,選中的部分等等。 比如下方代碼片段,結合selection 節點,activeCell屬性表示選擇框在哪個單元格,sqref屬性表示選擇的部分;當然,Excel里面是可以選中多個區域,那么會變成是:<selection activeCell="F4" sqref="B6 C2:C3 C4:F4"/> 這樣子的。

<sheetViews>
    <sheetView tabSelected="1" workbookViewId="0">
        <selection activeCell="A1" sqref="A1"/>
    </sheetView>
</sheetViews>

  不過在 sheetViews 節點元素下,還有其它的功能,涉及多窗口窗格子的選擇等等,具體可以再細細研究。

  (3) sheetFormatPr 節點元素:對應類型 SheetFormatProperties 類型,工作表的格式屬性,一般可以設置默認行高,默認的列寬度等等。

  (4) sheetData 節點元素:對應類型 SheetData 類型,這個表示單元格表的數據信息的集合,里面包含了每個單元格的信息。這個基本上是我們做導入導出等功能的時候,最需要打交道的類型之一了。從上面XML代碼中,看起來還是很容易理解的。 在這個sheetData節點下,有節點元素row (對應類型Row類型),表示一行; 而節點元素row的下面,有節點元素c(對應類型Cell類型),表示一單元格;其節點元素c的下面,有節點元素v(對應類型CellValue類型), 表示單元格的內容值,不過這個值的內容,和其節點元素c的一個t屬性有關系, 后續再來探討。

   (5) phoneticPr  節點元素: 對應類型 PhoneticProperties類型,這個和拼音文本的有關。

   (6) pageMargins 節點元素: 對應類型 PageMargins類型,定義工作表的頁邊距,對應Excel功能里面的頁面布局-頁邊距功能。

   (7) pageSetup 節點元素: 對應類型 PageSetup類型,涉及到Excel頁面設置的一些功能內容,包含紙張大小,紙張方向,紙張高度,寬度等等。

  根據上述提及的 XML 元素節點,和最上面的圖 對比來看,WorksheetPart 類型下方,還有幾個類型沒有出現。 其中 Columns類型 和 Column類型, 這2個類型一般是用來定義列寬。而MergeCells 類型 和 MergeCell 類型主要是合並單元格相關。

 --》sharedStrings.xml 文件 與 SharedStringTablePart 類型

   sharedStrings.xml 文件,對應類型 SharedStringTablePart 類型,這部分主要表示,共享字符串部分,用來減少文件大小的。

具體的XML可以看看下面代碼:

 1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 2 <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="8" uniqueCount="7">
 3     <si>
 4         <t>姓名</t>
 5         <phoneticPr fontId="1" type="noConversion"/>
 6     </si>
 7     <si>
 8         <t>班級</t>
 9         <phoneticPr fontId="1" type="noConversion"/>
10     </si>
11     <si>
12         <t>王同學</t>
13         <phoneticPr fontId="1" type="noConversion"/>
14     </si>
15     <si>
16         <t>一班</t>
17         <phoneticPr fontId="1" type="noConversion"/>
18     </si>
19     <si>
20         <t>二班</t>
21         <phoneticPr fontId="1" type="noConversion"/>
22     </si>
23     <si>
24         <t>陳同學</t>
25         <phoneticPr fontId="1" type="noConversion"/>
26     </si>
27     <si>
28         <t>林同學</t>
29         <phoneticPr fontId="1" type="noConversion"/>
30     </si>
31 </sst>

  根據以上的XML代碼,結合我們Excel文件輸入的數據,Excel默認把這些數據存放在這個共享字符串變量里面,而單元格的值是純粹引用這里而已,后續再探討。

 --》styles.xml 文件 與 WorkbookStylesPart 類型

  styles.xml 文件,對應類型 WorkbookStylesPart 類型。 這個類型相對復雜很多,主要涵蓋的內容是Excel里面的樣式,包含字體的定義,填充色定義,邊框定義等等。

樣式部分暫時不在這里探討了,后續單獨說明。可以先看看具體的XML代碼:

 1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 2 <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
 3     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac x16r2"
 4     xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"
 5     xmlns:x16r2="http://schemas.microsoft.com/office/spreadsheetml/2015/02/main">
 6     <fonts count="3" x14ac:knownFonts="1">
 7         <font>
 8             <sz val="11"/>
 9             <color theme="1"/>
10             <name val="等線"/>
11             <family val="2"/>
12             <scheme val="minor"/>
13         </font>
14         <font>
15             <sz val="9"/>
16             <name val="等線"/>
17             <family val="3"/>
18             <charset val="134"/>
19             <scheme val="minor"/>
20         </font>
21         <font>
22             <b/>
23             <sz val="11"/>
24             <color theme="1"/>
25             <name val="微軟雅黑"/>
26             <family val="2"/>
27             <charset val="134"/>
28         </font>
29     </fonts>
30     <fills count="2">
31         <fill>
32             <patternFill patternType="none"/>
33         </fill>
34         <fill>
35             <patternFill patternType="gray125"/>
36         </fill>
37     </fills>
38     <borders count="1">
39         <border>
40             <left/>
41             <right/>
42             <top/>
43             <bottom/>
44             <diagonal/>
45         </border>
46     </borders>
47     <cellStyleXfs count="1">
48         <xf numFmtId="0" fontId="0" fillId="0" borderId="0"/>
49     </cellStyleXfs>
50     <cellXfs count="2">
51         <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/>
52         <xf numFmtId="0" fontId="2" fillId="0" borderId="0" xfId="0" applyFont="1" applyAlignment="1">
53             <alignment horizontal="center"/>
54         </xf>
55     </cellXfs>
56     <cellStyles count="1">
57         <cellStyle name="常規" xfId="0" builtinId="0"/>
58     </cellStyles>
59     <dxfs count="2">
60         <dxf>
61             <font>
62                 <b/>
63                 <i val="0"/>
64             </font>
65             <fill>
66                 <patternFill>
67                     <bgColor rgb="FFD7D7D7"/>
68                 </patternFill>
69             </fill>
70         </dxf>
71         <dxf>
72             <font>
73                 <b val="0"/>
74                 <i val="0"/>
75             </font>
76             <fill>
77                 <patternFill patternType="none">
78                     <bgColor indexed="65"/>
79                 </patternFill>
80             </fill>
81         </dxf>
82     </dxfs>
83     <tableStyles count="1" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16">
84         <tableStyle name="MySqlDefault" pivot="0" table="0" count="2">
85             <tableStyleElement type="wholeTable" dxfId="1"/>
86             <tableStyleElement type="headerRow" dxfId="0"/>
87         </tableStyle>
88     </tableStyles>
89     <extLst>
90         <ext uri="{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}"
91             xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main">
92             <x14:slicerStyles defaultSlicerStyle="SlicerStyleLight1"/>
93         </ext>
94         <ext uri="{9260A510-F301-46a8-8635-F512D64BE5F5}"
95             xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">
96             <x15:timelineStyles defaultTimelineStyle="TimeSlicerStyleLight1"/>
97         </ext>
98     </extLst>
99 </styleSheet>

 

 --》小結

  本節大概說明了下常用類型和Excel文檔包中關聯的XML的對應關系,大概總結為如下對應圖:

  

  下一節,開始通過代碼來實現一些功能。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM