Type TSXml = Class
	class Function XmlHeader();
	Begin
		return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> \n';
	End;

	class Function GetMap();
	Begin
		return array( 
			'Content_Types':('FileName':'[Content_Types].xml','Template':'<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/><Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>'),
			'rels':('FileName':'_rels/.rels','Template':'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>'),
			'docProps_app':('FileName':'docProps/app.xml','Template':'<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><TotalTime>0</TotalTime><Application>TSExcel</Application></Properties>'),
			'docProps_core':('FileName':'docProps/core.xml','Template':'<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:creator>xuri</dc:creator><dcterms:created xsi:type="dcterms:W3CDTF">2006-09-16T00:00:00Z</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">2006-09-16T00:00:00Z</dcterms:modified></cp:coreProperties>'),
			'calcChain':('FileName':'xl/calcChain.xml','Template':''),
			'sharedStrings':('FileName':'xl/sharedStrings.xml','Template':''),
			'styles':('FileName':'xl/styles.xml','Template':'<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac x16r2" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:x16r2="http://schemas.microsoft.com/office/spreadsheetml/2015/02/main"><fonts count="1" x14ac:knownFonts="1"><font><sz val="11"/><color theme="1"/><name val="Calibri"/><family val="2"/></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><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/></cellXfs><cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles><dxfs count="0"/><tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16"/></styleSheet>'),
			'workbook':('FileName':'xl/workbook.xml','Template':'<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x15" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"><fileVersion appName="xl" lastEdited="6" lowestEdited="6" rupBuild="14420" /><workbookPr filterPrivacy="1" defaultThemeVersion="164011" /><bookViews><workbookView xWindow="0" yWindow="0" windowWidth="14805" windowHeight="8010" /></bookViews><sheets><sheet name="Sheet1" sheetId="1" r:id="rId1" /></sheets><calcPr calcId="122211" /></workbook>'),
			'sheet1':('FileName':'xl/worksheets/sheet1.xml','Template':'<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac xr xr2 xr3" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr2="http://schemas.microsoft.com/office/spreadsheetml/2015/revision2" xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3" xr:uid="{DA5AA3E3-79E6-43EC-9C9E-1F515924377F}"><dimension ref="A1"/><sheetViews><sheetView workbookViewId="0"/></sheetViews><sheetFormatPr defaultRowHeight="13.8" x14ac:dyDescent="0.25"/><sheetData/><phoneticPr fontId="1" type="noConversion"/><pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/></worksheet>'),
			'theme1':('FileName':'xl/theme/theme1.xml','Template':'<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme"><a:themeElements><a:clrScheme name="Office"><a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1><a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="44546A"/></a:dk2><a:lt2><a:srgbClr val="E7E6E6"/></a:lt2><a:accent1><a:srgbClr val="5B9BD5"/></a:accent1><a:accent2><a:srgbClr val="ED7D31"/></a:accent2><a:accent3><a:srgbClr val="A5A5A5"/></a:accent3><a:accent4><a:srgbClr val="FFC000"/></a:accent4><a:accent5><a:srgbClr val="4472C4"/></a:accent5><a:accent6><a:srgbClr val="70AD47"/></a:accent6><a:hlink><a:srgbClr val="0563C1"/></a:hlink><a:folHlink><a:srgbClr val="954F72"/></a:folHlink></a:clrScheme><a:fontScheme name="Office"><a:majorFont><a:latin typeface="Calibri Light" panose="020F0302020204030204"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="游ゴシック Light"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="等线 Light"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Times New Roman"/><a:font script="Hebr" typeface="Times New Roman"/><a:font script="Thai" typeface="Tahoma"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="MoolBoran"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Times New Roman"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/></a:majorFont><a:minorFont><a:latin typeface="Calibri" panose="020F0502020204030204"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="游ゴシック"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="等线"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Arial"/><a:font script="Hebr" typeface="Arial"/><a:font script="Thai" typeface="Tahoma"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="DaunPenh"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Arial"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/></a:minorFont></a:fontScheme><a:fmtScheme name="Office"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:lumMod val="110000"/><a:satMod val="105000"/><a:tint val="67000"/></a:schemeClr></a:gs><a:gs pos="50000"><a:schemeClr val="phClr"><a:lumMod val="105000"/><a:satMod val="103000"/><a:tint val="73000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:lumMod val="105000"/><a:satMod val="109000"/><a:tint val="81000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="5400000" scaled="0"/></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:satMod val="103000"/><a:lumMod val="102000"/><a:tint val="94000"/></a:schemeClr></a:gs><a:gs pos="50000"><a:schemeClr val="phClr"><a:satMod val="110000"/><a:lumMod val="100000"/><a:shade val="100000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:lumMod val="99000"/><a:satMod val="120000"/><a:shade val="78000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="5400000" scaled="0"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w="6350" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/><a:miter lim="800000"/></a:ln><a:ln w="12700" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/><a:miter lim="800000"/></a:ln><a:ln w="19050" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/><a:miter lim="800000"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="57150" dist="19050" dir="5400000" algn="ctr" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="63000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"><a:tint val="95000"/><a:satMod val="170000"/></a:schemeClr></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="93000"/><a:satMod val="150000"/><a:shade val="98000"/><a:lumMod val="102000"/></a:schemeClr></a:gs><a:gs pos="50000"><a:schemeClr val="phClr"><a:tint val="98000"/><a:satMod val="130000"/><a:shade val="90000"/><a:lumMod val="103000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="63000"/><a:satMod val="120000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="5400000" scaled="0"/></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>'),
			'workbook_rels':('FileName':'xl/_rels/workbook.xml.rels','Template':'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/></Relationships>'),
			'sheet_rels':('FileName':'','Template':'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"></Relationships>'),
			'drawing_rels':('FileName':'','Template':'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"></Relationships>'),
			'sheetContentType':('FileName':'','Template':'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'),
			'RelationshipWorkSheet':('FileName':'','Template':'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet'),
			'table1':('FileName':'xl/tables/table1.xml','Template':'<table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="xr xr3" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3"></table>'),
			'tableContentType':('FileName':'','Template':'application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml'),
			'commentContentType':('FileName':'','Template':'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml'),
			'drawingContentType':('FileName':'','Template':'application/vnd.openxmlformats-officedocument.drawing+xml'),
			'chartContentType':('FileName':'','Template':'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'),
			);
	End
	
	class Function GetFileName(key);
	Begin
		map := class(TSXml).GetMap();
		if ifarray(map[key]) then return map[key]['FileName'];
		return '';
	End;
	
	class Function GetTemplate(key);
	Begin
		map := class(TSXml).GetMap();
		if ifarray(map[key]) then return map[key]['Template'];
		return '';
	End;
	
	class Function Dom2Xml(r);
	Begin
		xml := new XmlFile();
		xml.Data := '<v/>';
		xml.IsXml := 1;
		node := xml.FirstChild();
		node.Unmarshal(r);
		return string(node.Data);
	End;
	
	class Function Xml2Dom(xmlstr, bAllDoc);
	Begin
		xml := new XmlFile();
		xml.Data := xmlstr;
		xml.IsXml := 1;
		if bAllDoc then
			return string(xml.Marshal());
		return string(xml.FirstChild().Marshal());
	End;
	
	class Function SetNodeValue(obj, r);
	Begin
		arr := str2array(r[0], '/');
		for i:=0 to length(arr)-1 do Begin
			node := i=0 ? obj.FirstChild(arr[i]) : node.FirstChild(arr[i]);
			if not ifObj(node) then return;
		End;
		if ifNil(r[2]) then return;
		if r[1] = 'pcdata' then Begin
			node.FirstChild().SetValue(r[2]);
			return;
		End;
		if r[1] = 'Del' and r[2] then Begin
			node.DeleteChildren();
			return;
		End;
		if r[1] = 'val' then Begin
			node.SetAttribute('val', r[2]);
			return;
		End;
		if r[1] = 'unmarshal' then Begin
			node.DeleteChildren();
			node.Unmarshal(r[2]);
			//node.Print;
			return;
		End;
	End;
	
	class Function UpdateNode(node, attrs, children);
	Begin
		if not ifArray(attrs) then attrs := array();
		if not ifArray(children) then children := array();
		fields := getstrindexs(attrs);
		for i:=0 to length(fields)-1 do Begin
			node.SetAttribute(fields[i], attrs[ fields[i] ]);
		End;
		for i:=0 to length(children)-1 do Begin
			if children[i]['type'] = 'pcdata' then
				child := node.FirstChild();
			else
				child := node.FirstChild(children[i]['name']);
			if not ifObj(child) then Begin
				child := node.InsertEndChild(children[i]);
				continue;
			End;
			if children[i]['type'] = 'pcdata' then
				child.SetValue(children[i]['value']);
			else
				class(TSXml).UpdateNode(child, children[i]['attributes'], children[i]['children']);
		End;
	End;
	
	class Function GetNode(obj, r, n);
	Begin
		arr := str2array(r, '/');
		node := obj;
		prev := obj;
		for i:=0 to length(arr)-1 do Begin
			node := prev.FirstChild(arr[i]);
			if not ifObj(node) then Begin
				if n then 
					if ifString(n) and n = 'first' then
						node := prev.InsertFirstChild('element', arr[i]);
					else 
						node := prev.InsertEndChild('element', arr[i]);
				else
					return nil;
			End;
			prev := node;
		End;
		return node;
	End;

	class Function RemoveNode(obj, r);
	Begin
		arr := str2array(r, '/');
		nodeArr := array();
		for i:=0 to length(arr)-1 do Begin
			node := i=0 ? obj.FirstChild(arr[i]) : node.FirstChild(arr[i]);
			nodeArr[i] := node;
			if not ifObj(node) then return;
		End;
		cnt := length(arr);
		if cnt > 1 and length(arr) = length(nodeArr) and ifObj(nodeArr[cnt - 1]) then 
			nodeArr[cnt - 2].DeleteChild(nodeArr[cnt - 1]);
	End;

	class Function GetNodeN(xmlnode, name, count);	
	Begin
		arr := str2array(name, '/');
		node := xmlnode;
		for i:=0 to length(arr)-1 do
		begin
			node := node.FirstChild(arr[i]);
			if not ifObj(node) then return nil;
		end
		last := arr[length(arr)-1];
		for i:=2 to count do
			node := node.NextElement(last);
		return node;
	End;

	///prefix为空——查找最大rId，prefix非空——查找指定Target
	class Function FindRelationshipRid(xmlfile, prefix);
	Begin
		rId := 0;
		findtarget := '';
		node := xmlfile.FirstChildElement('Relationships').FirstChildElement('Relationship');
		while ifObj(node) do Begin
			id := node.GetAttribute('Id');
			if ifstring(id) and leftstr(id,3)='rId' then Begin
				i := strtoint(rightstr(id, length(id)-3));
				if i > rId then rId := i;
			End;
			if prefix <> '' then Begin
				target := node.GetAttribute("Target");
				if AnsiStartsText(prefix, target) then Begin
					findtarget := target;
					break;
				End;
			End;
			node := node.NextElement();
		End;
		return array(rID, findtarget, i);
	End;

	class Function FindRelationship(xmlfile, rid);
	Begin
		node := xmlfile.FirstChildElement('Relationships').FirstChildElement('Relationship');
		while ifObj(node) do Begin
			id := node.GetAttribute('Id');
			if id = rid then return node;
			node := node.NextElement();
		End;
		return nil;
	End;

	class Function FindRelationshipTarget(xmlfile, rid);
	Begin
		node := class(TSXml).FindRelationship(xmlfile, rid);
		if ifObj(node) then
			return node.GetAttribute('Target');
		return nil;
	End;

	class Function AddRelationshipRid(xmlfile, target, type, rid, targetMode);
	Begin
		node := xmlfile.FirstChildElement('Relationships').InsertEndChild('element', 'Relationship');
		node.SetAttribute('Id', rid);
		node.SetAttribute('Type', type);
		node.SetAttribute('Target', target);
		if not ifnil(targetMode) then node.SetAttribute('TargetMode', targetMode);
	End;

	class Function AddDefaultContentType(xml, extensionName, contentType)
	Begin
		content := xml.FirstChildElement('Types');
		element := content.FirstChildElement('Default');
		while ifObj(element) do
		begin
			attr := element.GetAttribute('Extension');
			if attr = extensionName then return;
			element := element.NextElement('Default');
		end
		element := content.InsertFirstChild('element', 'Default');
		element.SetAttribute('Extension', extensionName);
		element.SetAttribute('ContentType', contentType);
	End
	
	class Function AddOverrideContentType(xml, partName, contentType);
	Begin
		content := xml.FirstChildElement('Types');
		element := content.FirstChildElement('Override');
		while ifObj(element) do
		begin
			attr := element.GetAttribute('PartName');
			if attr = partName then return;
			element := element.NextElement('Override');
		end
		element := content.InsertEndChild('element', 'Override');
		element.SetAttribute('PartName', partName);
		element.SetAttribute('ContentType', contentType);
	End;

	class Function GetDefaultContentType(xml, prefix);
	Begin
		element := xml.FirstChildElement('Default');
		while ifObj(element) do
		begin
			extension := element.GetAttribute('Extension');
			if AnsiStartsText(prefix, extension) then
				return array(extension, element.GetAttribute('ContentType'));
			element := element.NextElement('Default');
		end
		return array('', '');
	End

	class Function GetOverrideContentType(xml, prefix);
	Begin
		element := xml.FirstChildElement('Override');
		while ifObj(element) do
		begin
			partName := element.GetAttribute('PartName');
			if AnsiStartsText(prefix, partName) then
				return array(partName, element.GetAttribute('ContentType'));
			element := element.NextElement('Override');
		end
		return array('', '');
	End

	class Function GetWorkSheetPrevNode(workNode, nodeName);
	Begin
		order_arr := array('dimension', 'sheetPr', 'sheetViews', 'sheetFormatPr', 'cols', 'sheetData', 'sheetProtection', 'mergeCells', 'phoneticPr',
			'hyperlinks', 'pageMargins', 'headerFooter', 'pageSetup', 'rowBreaks', 'colBreaks', 'drawing', 'legacyDrawing', 'picture');
		for i:=0 to length(order_arr)-1 do
		begin
			if order_arr[i] = nodeName then return prev;
			current := workNode.FirstChild(order_arr[i]);
			if i = 0 then prev := current;
			else prev := ifObj(current) ? current : prev;
		end
	End

	class Function GetWorkBookPrevNode(workNode, nodeName);
	Begin
		order_arr := array('fileVersion', 'workbookPr', 'bookViews');
		for i:=0 to length(order_arr)-1 do
		begin
			if order_arr[i] = nodeName then return prev;
			current := workNode.FirstChild(order_arr[i]);
			if i = 0 then prev := current;
			else prev := ifObj(current) ? current : prev;
		end
	End

	class Function GetWorkSheetNode(workNode, nodeName);
	Begin
		node := workNode.FirstChildElement(nodeName);
		if not ifObj(node) then
		begin
			prev_node := class(TSXml).GetWorkSheetPrevNode(workNode, nodeName);
			if ifObj(prev_node) then node := workNode.InsertAfterChild(prev_node, 'element', nodeName);
			else node := workNode.InsertFirstChild('element', nodeName);
		end
		return node;
	End
	
	class Function GetDatetimeStr(v);
	Begin
		return FormatDateTime('YYYY-MM-DD', v) + 'T' + timetostr(v) + 'Z';//2017-03-02T04:16:00Z
	End;

	class Function GetcNvPrID(obj);
	Begin
		cnt := 2;
		node := obj.FirstChild('xdr:wsDr');
		if ifObj(node) then Begin
			node := node.FirstChild();
			while ifObj(node) do Begin
				if node.GetName() in array('xdr:oneCellAnchor', 'xdr:twoCellAnchor') then
					cnt++;
				node := node.NextElement();
			End;
		End;
		return cnt;
	End;
	
	class Function CopyPprFormat(p1, p2);
	Begin
		if ifObj(p1) and ifObj(p2) then Begin
			p1.SpaceBefore := _cp(p1.SpaceBefore, p2.SpaceBefore);
			p1.SpaceAfter := _cp(p1.SpaceAfter, p2.SpaceAfter);
			p1.LineSpacingRule := _cp(p1.LineSpacingRule, p2.LineSpacingRule);
			p1.LineSpacing := _cp(p1.LineSpacing, p2.LineSpacing);
			p1.LeftIndent := _cp(p1.LeftIndent, p2.LeftIndent);
			p1.RightIndent := _cp(p1.RightIndent, p2.RightIndent);
		End;
	End;
	
	class Function CopyRprFormat(r1, r2);
	Begin
		if ifObj(r1) and ifObj(r2) then Begin
			r1.Size := _cp(r1.Size, r2.Size);
			r1.szCs := _cp(r1.szCs, r2.szCs);
			r1.Color := _cp(r1.Color, r2.Color);
			r1.rFont.hint := _cp(r1.rFont.hint, r2.rFont.hint);
			r1.rFont.eastAsia := _cp(r1.rFont.eastAsia, r2.rFont.eastAsia);
			r1.rFont.hAnsi := _cp(r1.rFont.hAnsi, r2.rFont.hAnsi);
			r1.rFont.ascii := _cp(r1.rFont.ascii, r2.rFont.ascii);
			r1.rFont.cs := _cp(r1.rFont.cs, r2.rFont.cs);
		End;
	End;
	
	class Function CodePage(zw);
	Begin
		TOfficeApi().CodePage(zw);
	End;
	
	class Function IsUtf8();
	Begin
		return TOfficeApi().IsUtf8();
	End;
	
	class Function Utf8ToCurCodePage(str);
	Begin
		return TOfficeApi().Utf8ToCurCodePage(str);
	End;
	
	class Function CurCodePageToUtf8(str);
	Begin
		return TOfficeApi().CurCodePageToUtf8(str);
	End;

	//字体属性
	class Function ReadRprFormat(node);
	Begin
		rNode := node.FirstChildElement('w:rPr');
		if not ifObj(rNode) then
			return nil;
		rPr := TOfficeObj('TwrPr');
		rPr.RootObj := rNode;
		rPr.Size := SafeStrToIntDef(rPr.Value('Size'), 0);		//单字节字符（如ASCII编码字符等）的大小。
		rPr.szCs := SafeStrToIntDef(rPr.Value('szCs'), 0);		//双字节字符（如中日韩文字、阿拉伯文等）的大小。
		rPr.rFont.hint := rPr.rFont.Value('hint');
		rPr.rFont.eastAsia := rPr.rFont.Value('eastAsia');
		rPr.rFont.hAnsi := rPr.rFont.Value('hAnsi');
		rPr.rFont.ascii := rPr.rFont.Value('ascii');
		rPr.rFont.cs := rPr.rFont.Value('cs');
		return rPr;
	End;

	//段落属性
	class Function ReadPprFormat(node);
	Begin
		pNode := node.FirstChildElement('w:pPr');
		if not ifObj(pNode) then
			return nil;
		pPr := TOfficeObj('TwpPr');
		pPr.RootObj := pNode;
		pPr.SpaceBefore := SafeStrToIntDef(pPr.Value('SpaceBefore'), 0);
		pPr.SpaceAfter := SafeStrToIntDef(pPr.Value('SpaceAfter'), 0);
		pPr.LineSpacing := SafeStrToIntDef(pPr.Value('LineSpacing'), 0);
		pPr.LineSpacingRule := pPr.Value('LineSpacingRule');
		pPr.LeftIndent := SafeStrToIntDef(pPr.Value('LeftIndent'), 0);//office 2007
		pPr.RightIndent := SafeStrToIntDef(pPr.Value('RightIndent'), 0);
		pPr.EndIndent := SafeStrToIntDef(pPr.Value('EndIndent'), 0);
		pPr.StartIndent := SafeStrToIntDef(pPr.Value('StartIndent'), 0);//office 2011
		pPr.Hanging := SafeStrToIntDef(pPr.Value('Hanging'), 0);
		pPr.FirstLineIndent := SafeStrToIntDef(pPr.Value('FirstLineIndent'), 0);
		if pPr.StartIndent then
			pPr.LeftIndent := pPr.StartIndent;
		if pPr.EndIndent then
			pPr.RightIndent := pPr.EndIndent;
		//pPr.rPr := ReadRprFormat(pNode);
		return pPr;
	End;

	class Function SafeStrToIntDef(s, defaultV);
	Begin
		if ifnumber(s) then return integer(s);
		if not ifstring(s) then 
			return defaultV;
		return StrToIntDef(s, defaultV);
	End;
	
	class Function _cp(v1,v2);
	Begin
		if not v1 and v2 then
			return v2;
		return v1;
	End;
End;
