上一節初步使用了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結尾,比如WorkbookPart, WorksheetPart ,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的對應關系,大概總結為如下對應圖:
下一節,開始通過代碼來實現一些功能。