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