v.1.16-patch1
This commit is contained in:
parent
780d9ecb6d
commit
51a499925a
|
|
@ -1,58 +0,0 @@
|
||||||
Type TDocxChart = Class(TSChart)
|
|
||||||
///缺省构造函数
|
|
||||||
Function Create(docx, chartData); overload;
|
|
||||||
Begin
|
|
||||||
docx_ := docx;
|
|
||||||
class(TSChart).Create(chartData);
|
|
||||||
//chartN.xml
|
|
||||||
chartId_ := 1 + vselect countof( ['FileName'] ) from docx.Zip().Files() where AnsiStartsText('word/charts/chart', ['FileName']) end;
|
|
||||||
targetFileName := 'charts/chart' $ chartId_ $ '.xml';
|
|
||||||
chartFile := 'word/' + targetFileName;
|
|
||||||
docx.Zip().Add(chartFile, GetDefaultXml());
|
|
||||||
xmlObj_ := docx.Zip().Get(chartFile);
|
|
||||||
if not chartData_.DisableExcel and istable(chartData.Series) and istable(chartData.Series[0]['Categories']) and istable(chartData.Series[0]['Values']) then Begin
|
|
||||||
chartData_.NewExcelFile();
|
|
||||||
End;
|
|
||||||
Apply(xmlObj_);
|
|
||||||
chartData_.AddExcelFile(docx, xmlObj_, chartId_);//添加excel数据文件
|
|
||||||
|
|
||||||
//Relationship
|
|
||||||
relsObj := docx.Zip().Get('word/_rels/document.xml.rels');
|
|
||||||
[rId_, target] := class(TSXml).FindRelationshipRid(relsObj, '');
|
|
||||||
rId_ ++;
|
|
||||||
class(TSXml).AddRelationshipRid(relsObj, targetFileName, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' $ rId_);
|
|
||||||
//Content_Types
|
|
||||||
contentType := docx.Zip().Get('[Content_Types].xml');
|
|
||||||
class(TSXml).AddOverrideContentType(contentType, '/' + chartFile, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function GetInnerXml();
|
|
||||||
Begin
|
|
||||||
ETU := 360045;//1cm单位
|
|
||||||
return fmt('<w:r>
|
|
||||||
<w:drawing>
|
|
||||||
<wp:inline>
|
|
||||||
<wp:extent cx="{}" cy="{}"/>
|
|
||||||
<wp:effectExtent l="0" t="0" r="19050" b="19050"/>
|
|
||||||
<wp:docPr id="{}" name="{}"/>
|
|
||||||
<wp:cNvGraphicFramePr />
|
|
||||||
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
|
|
||||||
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart">
|
|
||||||
<c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId{}"/>
|
|
||||||
</a:graphicData>
|
|
||||||
</a:graphic>
|
|
||||||
</wp:inline>
|
|
||||||
</w:drawing>
|
|
||||||
</w:r>', integer(chartData_.Width * ETU), integer(chartData_.Height * ETU), docx_.GetDocPrId(), class(TSXml).CurCodePageToUtf8(chartData_.Name), rId_);
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function IsWord();override;
|
|
||||||
Begin
|
|
||||||
return true;
|
|
||||||
End;
|
|
||||||
|
|
||||||
docx_;
|
|
||||||
chartId_;
|
|
||||||
rId_;
|
|
||||||
xmlObj_;
|
|
||||||
End;
|
|
||||||
|
|
@ -1,188 +0,0 @@
|
||||||
Type TDocxStyles = Class
|
|
||||||
//段落格式
|
|
||||||
Function Create(docx);
|
|
||||||
Begin
|
|
||||||
docx_ := docx;
|
|
||||||
stylesXml_ := docx.Zip().Get('word/styles.xml');
|
|
||||||
idMap_ := array();
|
|
||||||
nameMap_ := array();
|
|
||||||
maxStyleId_ := 1;
|
|
||||||
|
|
||||||
if ifObj(stylesXml_) then Begin
|
|
||||||
stylesNode := stylesXml_.FirstChildElement('w:styles');
|
|
||||||
if ifObj(stylesNode) then Begin
|
|
||||||
node := stylesNode.FirstChildElement('w:style');
|
|
||||||
while ifObj(node) do Begin
|
|
||||||
o := TOfficeObj('TDocxStyle');
|
|
||||||
o.Init(node);
|
|
||||||
id := StrToIntDef(o.StyleId, 0);
|
|
||||||
if id > 0 and maxStyleId_ <= id then
|
|
||||||
maxStyleId_ := id + 1;
|
|
||||||
_addStyle(o);
|
|
||||||
node := node.NextElement('w:style');
|
|
||||||
End;
|
|
||||||
pNode := class(TSXml).GetNode(stylesNode, 'w:docDefaults/w:pPrDefault');
|
|
||||||
if ifObj(pNode) then
|
|
||||||
defaultPpr_ := Class(TSXml).ReadPprFormat(pNode);
|
|
||||||
|
|
||||||
rNode := class(TSXml).GetNode(stylesNode, 'w:docDefaults/w:rPrDefault');
|
|
||||||
if ifObj(rNode) then
|
|
||||||
defaultRpr_ := Class(TSXml).ReadRprFormat(rNode);
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
|
|
||||||
///缺省样式
|
|
||||||
///styleType:样式类型(paragraph、character、table)
|
|
||||||
///返回:TDocxStyle对象
|
|
||||||
Function Default(styleType);
|
|
||||||
Begin
|
|
||||||
for k, obj in idMap_ do Begin
|
|
||||||
if obj.wType = styleType then Begin
|
|
||||||
v := obj.node_.GetAttribute('w:default');
|
|
||||||
if v <> '1' then
|
|
||||||
return obj;
|
|
||||||
End;
|
|
||||||
End
|
|
||||||
return nil;
|
|
||||||
End;
|
|
||||||
|
|
||||||
///返回指定名称的TDocxStyle
|
|
||||||
///name:样式名称
|
|
||||||
///返回:TDocxStyle对象
|
|
||||||
Function GetStyle(name);
|
|
||||||
Begin
|
|
||||||
return nameMap_[ lowercase(name) ];
|
|
||||||
End;
|
|
||||||
|
|
||||||
///返回指定StyleId名称的TDocxStyle
|
|
||||||
///id:StyleID号(数字ID号或名称字符串)
|
|
||||||
///返回:TDocxStyle对象
|
|
||||||
Function GetStyleById(id);
|
|
||||||
Begin
|
|
||||||
return idMap_[ id ];
|
|
||||||
End;
|
|
||||||
|
|
||||||
//返回全部LatentStyles对象列表
|
|
||||||
//返回:TDocxStyle对象列表
|
|
||||||
Function LatentStyles();
|
|
||||||
Begin
|
|
||||||
r := array();
|
|
||||||
node := stylesXml_.FirstChildElement('w:styles');
|
|
||||||
if ifObj(node) then
|
|
||||||
node := node.FirstChildElement('w:latentStyles');
|
|
||||||
if ifObj(node) then Begin
|
|
||||||
node := node.FirstChildElement('w:lsdException');
|
|
||||||
while ifObj(node) do Begin
|
|
||||||
o := TOfficeObj('TDocxStyle');
|
|
||||||
o.Init(node);
|
|
||||||
r[ length(r) ] := o;
|
|
||||||
node := node.NextElement('w:lsdException');
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
return r;
|
|
||||||
End;
|
|
||||||
|
|
||||||
///返回全部Styles对象列表
|
|
||||||
///返回:TDocxStyle对象列表
|
|
||||||
Function Styles();
|
|
||||||
Begin
|
|
||||||
return idMap_;
|
|
||||||
End;
|
|
||||||
|
|
||||||
///插入新的段落样式
|
|
||||||
///styleId:样式ID,可以是自定义名称
|
|
||||||
///xmlStr:InnerXml串
|
|
||||||
///返回:TDocxStyle对象
|
|
||||||
Function AddStyleByInnerXml(styleId, xmlStr);
|
|
||||||
Begin
|
|
||||||
if ifstring(styleId) and styleId <> '' then Begin
|
|
||||||
style := GetStyle(styleId);
|
|
||||||
if ifObj(style) then
|
|
||||||
return style;
|
|
||||||
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(xmlStr);
|
|
||||||
node.SetAttribute('w:styleId', styleId);
|
|
||||||
End
|
|
||||||
else Begin
|
|
||||||
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(xmlStr);
|
|
||||||
node.SetAttribute('w:styleId', maxStyleId_++);
|
|
||||||
End;
|
|
||||||
o := TOfficeObj('TDocxStyle');
|
|
||||||
o.Init(node);
|
|
||||||
_addStyle(o);
|
|
||||||
return o;
|
|
||||||
End;
|
|
||||||
|
|
||||||
///插入新的段落样式
|
|
||||||
///o:TDocxStyle对象
|
|
||||||
///StyleId:样式ID,可以是自定义名称
|
|
||||||
///返回:TDocxStyle对象
|
|
||||||
Function AddStyle(o, StyleId);
|
|
||||||
Begin
|
|
||||||
if ifObj(o) then Begin
|
|
||||||
if ifString(StyleId) and StyleId <> '' and not ifObj(idMap_[ StyleId ]) then
|
|
||||||
o.StyleId := StyleId;
|
|
||||||
else
|
|
||||||
o.StyleId := maxStyleId_++;
|
|
||||||
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(o.Marshal());
|
|
||||||
obj := TOfficeObj('TDocxStyle');
|
|
||||||
obj.Init(node);
|
|
||||||
_addStyle(obj);
|
|
||||||
return obj;
|
|
||||||
End;
|
|
||||||
return nil;
|
|
||||||
End;
|
|
||||||
|
|
||||||
///插入新的LatentStyle段落样式
|
|
||||||
///o:TDocxStyle对象
|
|
||||||
///返回:TDocxStyle对象
|
|
||||||
Function AddLatentStyle(o);
|
|
||||||
Begin
|
|
||||||
if ifObj(o) then Begin
|
|
||||||
latentStyles := stylesXml_.FirstChildElement('w:styles').InsertEndChild('w:latentStyles');
|
|
||||||
node := latentStyles.InsertEndChild('lsdException');
|
|
||||||
node.UnMarshal(o);
|
|
||||||
latentStyles.SetAttribute('w:count', length(LatentStyles()));
|
|
||||||
return node;
|
|
||||||
End;
|
|
||||||
return nil;
|
|
||||||
End;
|
|
||||||
|
|
||||||
///插入缺省的段落样式(Title、Heading1-9)
|
|
||||||
///返回:TDocxStyle对象
|
|
||||||
Function AddDefaultStyle(Name);
|
|
||||||
Begin
|
|
||||||
styleId := AnsiReplaceText(Name, ' ', '');
|
|
||||||
charId := StyleId + 'Char';
|
|
||||||
styleFname := 'wStyle/' + styleId + '.xml';
|
|
||||||
cStyleFname := 'wStyle/' + charId + '.xml';
|
|
||||||
xmlData := TOfficeTemplate(styleFname);
|
|
||||||
if ifnil(xmlData) then
|
|
||||||
return xmlData;
|
|
||||||
o := AddStyleByInnerXml(styleId, xmlData);
|
|
||||||
|
|
||||||
charStyle := idMap_[charId];
|
|
||||||
if not ifObj(charStyle) then Begin
|
|
||||||
xmlData := TOfficeTemplate(cStyleFname);
|
|
||||||
if ifstring(xmlData) then Begin
|
|
||||||
AddStyleByInnerXml(charId, xmlData);
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
return o;
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function _addStyle(o);
|
|
||||||
Begin
|
|
||||||
idMap_[ o.StyleId ] := o;
|
|
||||||
nameMap_[ lowercase(o.Name) ] := o;
|
|
||||||
End;
|
|
||||||
|
|
||||||
defaultPpr_;
|
|
||||||
defaultRpr_;
|
|
||||||
private
|
|
||||||
docx_;
|
|
||||||
stylesXml_;
|
|
||||||
idMap_;
|
|
||||||
nameMap_;
|
|
||||||
maxStyleId_:integer;
|
|
||||||
End;
|
|
||||||
|
|
@ -1,225 +0,0 @@
|
||||||
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-6;singleLevel:(decimal、chineseCounting);multilevel:decimal
|
|
||||||
///返回: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;
|
|
||||||
|
|
||||||
///新添加项目样式
|
|
||||||
///xmlStr:xml字符串
|
|
||||||
///返回: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;
|
|
||||||
|
|
||||||
///新添加项目样式
|
|
||||||
///o:TNumStyle对象
|
|
||||||
///返回: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;
|
|
||||||
|
|
@ -1,310 +0,0 @@
|
||||||
Type TTableContent = class
|
|
||||||
//目录
|
|
||||||
Function Create(docx);overload;
|
|
||||||
Begin
|
|
||||||
Create(docx, nil);
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function Create(docx, node);overload;
|
|
||||||
Begin
|
|
||||||
node_ := node;
|
|
||||||
docx_ := docx;
|
|
||||||
impl_ := TOfficeObj('TTableContentImpl');
|
|
||||||
//_CheckNodes('endnotes.xml');
|
|
||||||
//_CheckNodes('footnotes.xml');
|
|
||||||
//contentType := docx.Zip().Get('[Content_Types].xml');
|
|
||||||
//class(TSXml).AddOverrideContentType(contentType, 'wmf', 'image/x-wmf');
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function SetDefaultFormat();
|
|
||||||
Begin
|
|
||||||
defultFont := impl_.stdPr.rPr;
|
|
||||||
defultFont.rFont.cstheme := 'minorBidi';
|
|
||||||
defultFont.rFont.XMLeastAsia := '宋体';
|
|
||||||
defultFont.rFont.XMLhAnsi := '宋体';
|
|
||||||
defultFont.rFont.XMLascii := '宋体';
|
|
||||||
//defultFont.kern := 2;
|
|
||||||
defultFont.Size := 21;
|
|
||||||
defultFont.SzCs := 24;
|
|
||||||
defultFont.Lang := 'en-US';
|
|
||||||
defultFont.bidi := 'ar-SA';
|
|
||||||
defultFont.eastAsia := 'zh-CN';
|
|
||||||
defultFont.Color := 'DBDBDB';
|
|
||||||
defultFormat := impl_.stdPr;
|
|
||||||
defultFormat.ID := integer(time()*24*3600);
|
|
||||||
//defultFormat.Color := 'DBDBDB';
|
|
||||||
defultFormat.docPartObj.docPartGallery := 'Table of Contents';
|
|
||||||
defultFormat.docPartObj.docPartUnique := 1;
|
|
||||||
//impl_.stdEndPr.rPr.Size := 20;
|
|
||||||
//impl_.stdEndPr.rPr.SzCs := 20;
|
|
||||||
impl_.stdEndPr.rPr.Bold := true;
|
|
||||||
End;
|
|
||||||
|
|
||||||
///应用目录样式
|
|
||||||
Function Apply(); override;
|
|
||||||
Begin
|
|
||||||
arr := impl_.Marshal();
|
|
||||||
class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']);
|
|
||||||
End;
|
|
||||||
|
|
||||||
///添加目录条目
|
|
||||||
///UpperHeadingLevel:标题最高级别
|
|
||||||
///LowerHeadingLevel:标题最低级别
|
|
||||||
/// 使用 UpperHeadingLevel 属性可设置起始标题级别(最高)。例如,若要设置 TOC 域语法 {TOC \o "1-3"},可将 LowerHeadingLevel 属性设为 3,并将 UpperHeadingLevel 属性设为 1。
|
|
||||||
Function Add(posOpt, UpperHeadingLevel, LowerHeadingLevel);
|
|
||||||
Begin
|
|
||||||
///目录
|
|
||||||
mParagraph := TOfficeObj('TParagraph');
|
|
||||||
mParagraph.pPr.LineSpacingRule := 'auto';
|
|
||||||
mParagraph.pPr.LineSpacing := 240;
|
|
||||||
mParagraph.pPr.AfterLines := 0;
|
|
||||||
mParagraph.pPr.SpaceAfter := 0;
|
|
||||||
mParagraph.pPr.BeforeLines := 0;
|
|
||||||
mParagraph.pPr.SpaceBefore := 0;
|
|
||||||
mParagraph.pPr.Alignment := 'center';
|
|
||||||
mParagraph.pPr.FirstLineChars := 0;
|
|
||||||
mParagraph.pPr.FirstLineIndent := 0;
|
|
||||||
mParagraph.pPr.RightChars := 0;
|
|
||||||
mParagraph.pPr.RightIndent := 0;
|
|
||||||
mParagraph.pPr.LeftChars := 0;
|
|
||||||
mParagraph.pPr.LeftIndent := 0;
|
|
||||||
mParagraph.Run.T := '目录';
|
|
||||||
mParagraph.Run.rPr.SetName('宋体', true);
|
|
||||||
mParagraph.Run.rPr.Size := 21;
|
|
||||||
mParagraph.Run.rPr.Bold := true;
|
|
||||||
_AddStdContent(mParagraph);
|
|
||||||
|
|
||||||
goback := TOfficeObj('TParagraph');
|
|
||||||
id := docx_.Document().GetBookMarkID();
|
|
||||||
goback.MarkStart.Name := '_GoBack';
|
|
||||||
goback.MarkStart.ID := id;
|
|
||||||
goback.MarkEnd.ID := id;
|
|
||||||
_AddStdContent(goback);
|
|
||||||
|
|
||||||
//缺省目录,需要word或wps打开后,更新目录
|
|
||||||
_AddDefaultTableContent(UpperHeadingLevel, LowerHeadingLevel);
|
|
||||||
|
|
||||||
//自定义页码计算与word、wps有差异,不推荐使用
|
|
||||||
//_AddTableContent(posOpt, UpperHeadingLevel, LowerHeadingLevel);
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function _AddDefaultTableContent(UpperHeadingLevel, LowerHeadingLevel);
|
|
||||||
Begin
|
|
||||||
p := _AddItem(UpperHeadingLevel, LowerHeadingLevel, UpperHeadingLevel - 1, true);
|
|
||||||
_AddStdContent(p);
|
|
||||||
|
|
||||||
p2 := TOfficeObj('TParagraph');
|
|
||||||
//p2.Format.SpaceAfter := 0;
|
|
||||||
run := p2.AddRun();
|
|
||||||
run.rPr.Bold := true;
|
|
||||||
run.rPr.noProof := true;
|
|
||||||
run.fldCharType := 'end';
|
|
||||||
_AddStdContent(p2);
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function _AddItem(UpperHeadingLevel, LowerHeadingLevel, level, first);
|
|
||||||
Begin
|
|
||||||
p := TOfficeObj('TParagraph');
|
|
||||||
//标题段落属性
|
|
||||||
p.Format.StyleId := _GetStyle(level);
|
|
||||||
//p.Format.SpaceAfter := 0;
|
|
||||||
p.Format.rPr.noProof := true;
|
|
||||||
tab := TOfficeObj('TTabStop');
|
|
||||||
tab.Val := 'right';
|
|
||||||
tab.leader := 'dot';
|
|
||||||
tab.Position := 8640;
|
|
||||||
p.Format.Tabs.Add(0, tab);
|
|
||||||
if first then Begin
|
|
||||||
//fldCharType
|
|
||||||
r1 := p.AddRun();
|
|
||||||
r1.fldCharType := 'begin';
|
|
||||||
r1.Dirty := 'true';
|
|
||||||
|
|
||||||
//instrText
|
|
||||||
r2 := p.AddRun();
|
|
||||||
r2.instrTextSpace := 'preserve';
|
|
||||||
r2.instrText := 'TOC \\o \"' $ UpperHeadingLevel $ '-' $ LowerHeadingLevel $ '\" \\h \\u ';
|
|
||||||
|
|
||||||
//fldCharType
|
|
||||||
r3 := p.AddRun();
|
|
||||||
r3.fldCharType := 'separate';
|
|
||||||
End;
|
|
||||||
return p;
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function _AddTableContent(posOpt, UpperHeadingLevel, LowerHeadingLevel);
|
|
||||||
Begin
|
|
||||||
///获取标题列表 array((("Level":level,"Paragraph":"object","Text":title,"numId":,"ilvl":,"numArr":));
|
|
||||||
numMap := array();
|
|
||||||
r := docx_.Document().Body().GetHeadingListImpl(docx_, posOpt, UpperHeadingLevel, LowerHeadingLevel, numMap, true);
|
|
||||||
for i:=0 to length(r)-1 do Begin
|
|
||||||
p := _AddItem(UpperHeadingLevel, LowerHeadingLevel, r[i]['Level'], i = 0 ? true: false);
|
|
||||||
//fldCharType
|
|
||||||
r4 := p.AddRun();
|
|
||||||
r4.fldCharType := 'begin';
|
|
||||||
|
|
||||||
//instrText
|
|
||||||
bookmarke := _GetBookMarkId(r[i]['Paragraph']);
|
|
||||||
r5 := p.AddRun();
|
|
||||||
r5.instrTextSpace := 'preserve';
|
|
||||||
r5.instrText := ' HYPERLINK \\l ' $ bookmarke $ ' ';
|
|
||||||
|
|
||||||
//fldCharType
|
|
||||||
r6 := p.AddRun();
|
|
||||||
r6.fldCharType := 'separate';
|
|
||||||
|
|
||||||
//目录条目文字内容
|
|
||||||
r7 := p.AddRun();
|
|
||||||
r7.Font.SetName('宋体', true);
|
|
||||||
numStr := ''; //数字项目编号
|
|
||||||
if r[i]['numId'] then Begin
|
|
||||||
style := docx_.NumberingObject().NumberStyle(r[i]['numId']);//支持数字、字符串StyleId
|
|
||||||
if ifObj(style) then
|
|
||||||
numStr := style.GetText(r[i]['ilvl'], r[i]['numArr']);
|
|
||||||
End
|
|
||||||
r7.T := numStr + r[i]['Text'];
|
|
||||||
|
|
||||||
//Tab
|
|
||||||
r8 := p.AddRun();
|
|
||||||
r8.Tab := true;
|
|
||||||
|
|
||||||
//fldCharType
|
|
||||||
r9 := p.AddRun();
|
|
||||||
r9.fldCharType := 'begin';
|
|
||||||
|
|
||||||
//instrText
|
|
||||||
r10 := p.AddRun();
|
|
||||||
r10.instrTextSpace := 'preserve';
|
|
||||||
r10.instrText := ' PAGEREF ' $ bookmarke $ ' \\h ';
|
|
||||||
|
|
||||||
//fldCharType
|
|
||||||
r11 := p.AddRun();
|
|
||||||
r11.fldCharType := 'separate';
|
|
||||||
|
|
||||||
//页码
|
|
||||||
r12 := p.AddRun();
|
|
||||||
r12.T := '' $ r[i]['pageNo'];
|
|
||||||
|
|
||||||
//fldCharType
|
|
||||||
r13 := p.AddRun();
|
|
||||||
r13.fldCharType := 'end';
|
|
||||||
|
|
||||||
//fldCharType
|
|
||||||
r14 := p.AddRun();
|
|
||||||
r14.fldCharType := 'end';
|
|
||||||
|
|
||||||
if r[i]['Level']+1 = UpperHeadingLevel then Begin //第一级标题,设置为粗体
|
|
||||||
p.Format.rPr.Bold := true;
|
|
||||||
r4.rPr.Bold := true;
|
|
||||||
r5.rPr.Bold := true;
|
|
||||||
r6.rPr.Bold := true;
|
|
||||||
r7.rPr.Bold := true;
|
|
||||||
r8.rPr.Bold := true;
|
|
||||||
//r9.rPr.Bold := true;
|
|
||||||
r10.rPr.Bold := true;
|
|
||||||
//r11.rPr.Bold := true;
|
|
||||||
r12.Font.Bold := true;
|
|
||||||
//r13.rPr.Bold := true;
|
|
||||||
r14.rPr.Bold := true;
|
|
||||||
End;
|
|
||||||
_AddStdContent(p);
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
|
|
||||||
///更新目录
|
|
||||||
Function UpdatePageNumbers();
|
|
||||||
Begin
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function Marshal();
|
|
||||||
Begin
|
|
||||||
return impl_.Marshal();
|
|
||||||
End;
|
|
||||||
|
|
||||||
Property Format read readFormat;
|
|
||||||
Function readFormat();
|
|
||||||
Begin
|
|
||||||
return impl_.stdPr;
|
|
||||||
End;
|
|
||||||
|
|
||||||
Property EndFormat read readEndFormat;
|
|
||||||
Function readEndFormat();
|
|
||||||
Begin
|
|
||||||
return impl_.stdEndPr;
|
|
||||||
End;
|
|
||||||
|
|
||||||
Property Font read readFont;
|
|
||||||
Function readFont();
|
|
||||||
Begin
|
|
||||||
return impl_.stdPr.rPr;
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function _AddStdContent(o);
|
|
||||||
Begin
|
|
||||||
impl_.SdtContent.NewChildNode( array("field":"", "name":"w:p", "obj":o, "attrEx":"", "nodeType":"") );
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function _GetStyle(level);
|
|
||||||
Begin
|
|
||||||
styleName := 'Tinysoft目录 ' $ (level + 1);
|
|
||||||
style := docx_.StyleObject().GetStyle(styleName);
|
|
||||||
if not ifObj(style) then Begin
|
|
||||||
style := TOfficeObj('TDocxStyle');
|
|
||||||
style.wType := 'paragraph';
|
|
||||||
style.CustomStyle := 1;
|
|
||||||
style.Name := styleName;
|
|
||||||
style.uiPriority := 0;
|
|
||||||
style.pPr.LeftChars := 200 * level;
|
|
||||||
style.rPr.Size := 20;
|
|
||||||
style.rPr.SzCs := 20;
|
|
||||||
docx_.StyleObject().AddStyle(style, 'TsToc' $ (level + 1));
|
|
||||||
End;
|
|
||||||
return style.StyleId;
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function _GetBookMarkId(p);
|
|
||||||
Begin
|
|
||||||
node := p.node_.FirstChildElement('w:bookmarkStart');
|
|
||||||
if ifObj(node) then
|
|
||||||
return node.GetAttribute('w:name');
|
|
||||||
bookMarkID := docx_.Document().GetBookMarkID();
|
|
||||||
return p.AddBookMark();
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function _CheckNodes(name);
|
|
||||||
Begin
|
|
||||||
z := docx_.Zip();
|
|
||||||
xml := z.Get('word/' + name);
|
|
||||||
if not ifObj(xml) then Begin
|
|
||||||
path := docx_.GetPath();
|
|
||||||
if path[1] = '/' then Begin
|
|
||||||
fName := path + '/funcext/TSOffice/template/' + name;
|
|
||||||
End
|
|
||||||
else Begin
|
|
||||||
fName := path + '\\funcext\\TSOffice\\template\\' + name;
|
|
||||||
End;
|
|
||||||
if not ReadFile(rwraw(), '', fName, 0, 100 * 1024, xmlData) then
|
|
||||||
return;
|
|
||||||
z.Add('word/' + name, xmlData);
|
|
||||||
rels := 'word/_rels/document.xml.rels';
|
|
||||||
relsObj := z.Get(rels);
|
|
||||||
[rId, target] := class(TSXml).FindRelationshipRid(relsObj, '');
|
|
||||||
rId ++;
|
|
||||||
|
|
||||||
if name = 'endnotes.xml' then Begin
|
|
||||||
class(TSXml).AddRelationshipRid(relsObj, name, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes', 'rId' $ rId);
|
|
||||||
contentType := z.Get('[Content_Types].xml');
|
|
||||||
class(TSXml).AddOverrideContentType(contentType, '/word/' + name, 'application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml');
|
|
||||||
End
|
|
||||||
else if name = 'footnotes.xml' then Begin
|
|
||||||
class(TSXml).AddRelationshipRid(relsObj, name, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes', 'rId' $ rId);
|
|
||||||
contentType := z.Get('[Content_Types].xml');
|
|
||||||
class(TSXml).AddOverrideContentType(contentType, '/word/' + name, 'application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml');
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
|
|
||||||
docx_;
|
|
||||||
node_;
|
|
||||||
impl_;
|
|
||||||
End;
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
Type docxDocument = Class
|
|
||||||
/// word/document.xml对象
|
|
||||||
|
|
||||||
///缺省构造函数
|
|
||||||
Function Create(z); overload;
|
|
||||||
Begin
|
|
||||||
zipfile_ := z;
|
|
||||||
document_ := zipfile_.Get('word/document.xml');
|
|
||||||
root_ := document_.FirstChildElement('w:document');
|
|
||||||
bodyNode_ := root_.FirstChildElement('w:body');
|
|
||||||
body_ := TOfficeObj('TwBody');
|
|
||||||
body_.InitNode(bodyNode_);
|
|
||||||
body_.zipfile_ := z;
|
|
||||||
body_.document_ := self;
|
|
||||||
bookmarkid_ := -1;
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function Body();
|
|
||||||
Begin
|
|
||||||
return body_;
|
|
||||||
End;
|
|
||||||
|
|
||||||
Function GetBookMarkID();
|
|
||||||
Begin
|
|
||||||
if bookmarkid_ < 0 then Begin
|
|
||||||
bookmarkid_ := 0;
|
|
||||||
p := body_.node_.FirstChildElement('w:p');
|
|
||||||
while ifObj(p) do Begin
|
|
||||||
markStart := p.FirstChildElement('w:bookmarkStart');
|
|
||||||
if ifObj(markStart) then Begin
|
|
||||||
id := markStart.GetAttribute('w:id');
|
|
||||||
if ifstring(id) then Begin
|
|
||||||
iVal := strtoint(id);
|
|
||||||
if bookmarkid_ <= iVal then
|
|
||||||
bookmarkid_ := iVal + 1;
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
p := p.NextElement('w:p');
|
|
||||||
End;
|
|
||||||
End
|
|
||||||
else
|
|
||||||
bookmarkid_++;
|
|
||||||
return bookmarkid_;
|
|
||||||
End;
|
|
||||||
private
|
|
||||||
root_;//w:document
|
|
||||||
bodyNode_;//w:body
|
|
||||||
body_;
|
|
||||||
document_;
|
|
||||||
bookmarkid_;
|
|
||||||
End;
|
|
||||||
Loading…
Reference in New Issue