TSOffice/funcext/TSOffice/document/TNumbering.tsf

226 lines
6.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Type TNumbering = Class
//项目编号
Function Create(docx);
Begin
docx_ := docx;
numberingXml_ := docx.Zip().Get('word/numbering.xml');
if not ifObj(numberingXml_) then Begin
xmlData := TOfficeTemplate('numbering/numbering.xml');
if ifString(xmlData) then Begin
docx.Zip().Add('word/numbering.xml', xmlData);
rels := 'word/_rels/document.xml.rels';
relsObj := docx.Zip().Get(rels);
[rId, target] := class(TSXml).FindRelationshipRid(relsObj, '');
rId ++;
class(TSXml).AddRelationshipRid(relsObj, 'numbering.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering', 'rId' $ rId);
contentType := docx.Zip().Get('[Content_Types].xml');
class(TSXml).AddOverrideContentType(contentType, '/word/numbering.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml');
numberingXml_ := docx.Zip().Get('word/numbering.xml');
End;
End;
maxAbstractNumId_ := 0;
maxNumId_ := 1;
numStyleObjs_ := array();
numIdMap_ := array();
bullet_ := array();
hash_ := array();
bulletDefine_ := array("ef82b2","ef81b5","ef83bc","ef81b6","ef81ac","ef8398","ef81ae");//缺省项目符号文字内容utf8 -> hex16
if ifObj(numberingXml_) then Begin
numbering := numberingXml_.FirstChildElement('w:numbering');
if ifObj(numbering) then Begin
node := numbering.FirstChildElement('w:abstractNum');
numNode := numbering.FirstChildElement('w:num');
End;
while ifObj(node) do Begin
o := TOfficeObj('TNumStyle');
o.Init(node);
nsid := o.Value('nsid');
if nsid then
hash_[nsid] := 1;
tmpl := o.Value('tmpl');
if tmpl then
hash_[tmpl] := 1;
id := StrToIntDef(o.abstractNumId, 0);
if id >= 0 and maxAbstractNumId_ <= id then
maxAbstractNumId_ := id + 1;
_addStyle(o);
lastAbstractNumStyle_ := node;
node := node.NextElement('w:abstractNum');
End;
while ifObj(numNode) do Begin
idStr := numNode.GetAttribute('w:numId');
id := StrToIntDef(idStr, 0);
if id > 0 and maxNumId_ <= id then
maxNumId_ := id + 1;
abstractNumIdNode := numNode.FirstChildElement('w:abstractNumId');
if ifObj(abstractNumIdNode) then
numIdMap_[idStr] := abstractNumIdNode.GetAttribute('w:val');
numNode := numNode.NextElement('w:num');
End;
End;
End;
///新生成numId
///levelType字符串bullet、singleLevel、multilevel
///fmt项目格式取值范围bullet:0-6singleLevel(decimal、chineseCounting)multileveldecimal
///返回numId
Function NumberId(levelType, fmt);
Begin
style := NumberStyle(levelType, fmt);
if not ifObj(style) then
return -1;
num := TOfficeObj('TNumber');
num.numId := maxNumId_++;
num.abstractNumId := style.Id;
numberingXml_.FirstChildElement('w:numbering').InsertEndChild(num.Marshal());
numIdMap_[''$num.numId] := num.abstractNumId;
return num.numId;
End;
///根据numId获取TNumStyle对象已存在
///返回TNumStyle对象
Function NumberStyle(numId);overload;
Begin
abstractNumId := numIdMap_['' $ numId];
if abstractNumId then Begin
return numStyleObjs_[abstractNumId];
End;
return nil;
End;
//获取TNumStyle对象如果不存在插入系统缺省
Function NumberStyle(levelType, fmt);overload;
Begin
if levelType = 'bullet' then Begin
if fmt < 0 or fmt > 6 then return nil;
k := bulletDefine_[fmt];
o := bullet_[k];
if ifObj(o) then
return o;
//不存在,插入缺省项目编号
return AddDefaultStyle('bullet' $ fmt);
End;
if lowercase(levelType) = 'singlelevel' and lowercase(fmt) = 'decimal' then Begin
if ifObj(singleNumLevel_) then
return singleNumLevel_;
return AddDefaultStyle('singleNumLevel-decimal');
End;
if lowercase(levelType) = 'singlelevel' and lowercase(fmt) in array('chinese','chinesecounting','cn','china') then Begin
if ifObj(singleCNLevel_) then
return singleCNLevel_;
return AddDefaultStyle('singlelevel-chineseCounting');
End;
if lowercase(levelType) = 'multilevel' and lowercase(fmt) = 'decimal' then Begin
if ifObj(multiNumLevel_) then
return multiNumLevel_;
return AddDefaultStyle('multilevel-decimal');
End;
return nil;
End;
///返回TNumStyle全部对象列表array('id1':obj1,'id2':obj2);
Function Numberings();
Begin
return numStyleObjs_;
End;
///新添加项目样式
///xmlStrxml字符串
///返回TNumStyle对象
Function AddStyleByInnerXml(xmlStr);
Begin
if ifObj(lastAbstractNumStyle_) then
node := numberingXml_.FirstChildElement('w:numbering').InsertAfterChild(lastAbstractNumStyle_, xmlStr);
else
node := numberingXml_.FirstChildElement('w:numbering').InsertFirstChild(xmlStr);
node.SetAttribute('w:abstractNumId', maxAbstractNumId_++);
lastAbstractNumStyle_ := node;
o := TOfficeObj('TNumStyle');
o.Init(node);
_addStyle(o);
_setNsId(o);
return o;
End;
///新添加项目样式
///oTNumStyle对象
///返回TNumStyle对象
Function AddStyle(o);
Begin
if ifObj(o) then Begin
o.abstractNumId := maxAbstractNumId_++;
if ifObj(lastAbstractNumStyle_) then
node := numberingXml_.FirstChildElement('w:numbering').InsertAfterChild(lastAbstractNumStyle_, o.Marshal());
else
node := numberingXml_.FirstChildElement('w:numbering').InsertFirstChild(o.Marshal());
lastAbstractNumStyle_ := node;
o := TOfficeObj('TNumStyle');
o.Init(node);
_addStyle(o);
_setNsId(o);
return o;
End;
return nil;
End;
//系统默认支持的项目编号样式
Function AddDefaultStyle(Name);
Begin
xmlData := TOfficeTemplate('numbering/' + name + '.xml');
if not ifString(xmlData) then
return nil;
return AddStyleByInnerXml(xmlData);
End;
//map项目对象
Function _addStyle(o);
Begin
if o.multiLevelType = 'singleLevel' and o.numFmt = 'bullet' then Begin
lvlText := o.lvl.Value('lvlText');
if lvlText then Begin
str := encoderadixstr(lvlText,"", 0x40000000+16);
bullet_[str] := o;
End;
End
else if not ifObj(singleNumLevel_) and o.multiLevelType = 'singleLevel' and o.numFmt = 'decimal' then
singleNumLevel_ := o;
else if not ifObj(singleCNLevel_) and o.multiLevelType = 'singleLevel' and o.numFmt = 'chineseCounting' then
singleCNLevel_ := o;
else if not ifObj(multiNumLevel_) and o.multiLevelType = 'multilevel' and o.numFmt = 'decimal' then
multiNumLevel_ := o;
numStyleObjs_[o.abstractNumId] := o;
End;
//生成nsid随机数->转16进制
Function _setNsId(o);
Begin
v := Integer(RandomRange(1000000000,2000000000));
id := inttohex(v, 1);
if hash_[id] then
return _setNsId(o);
hash_[id] := 1;
o.nsid := id;
o.tmpl := id;
arr := o.Marshal();
class(TSXml).UpdateNode(o.node_, arr['attributes'], arr['children']);
End;
private
docx_;
numberingXml_;
maxAbstractNumId_:integer;
maxNumId_:integer;
lastAbstractNumStyle_;
numStyleObjs_;
singleNumLevel_;
singleCNLevel_;
multiNumLevel_;
bulletDefine_;
bullet_;
numIdMap_;
hash_;
End;