v1.4.2
This commit is contained in:
parent
8d63ecd7b3
commit
b59c869ae2
Binary file not shown.
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
||||||
// Version 1.4.1
|
// Version 1.4.2
|
||||||
|
|
||||||
Function TOfficeObj(n);
|
Function TOfficeObj(n);
|
||||||
Begin
|
Begin
|
||||||
|
|
@ -12691,7 +12691,7 @@ Type TSectPr = Class
|
||||||
LineRatio := 1.0;
|
LineRatio := 1.0;
|
||||||
if ifObj(pPr) then Begin
|
if ifObj(pPr) then Begin
|
||||||
if pPr.LineSpacingRule = 'exact' and pPr.LineSpacing then //固定行距
|
if pPr.LineSpacingRule = 'exact' and pPr.LineSpacing then //固定行距
|
||||||
defaultLineHeight := _pPr.LineSpacing;
|
defaultLineHeight := pPr.LineSpacing;
|
||||||
else if pPr.LineSpacing then Begin
|
else if pPr.LineSpacing then Begin
|
||||||
LineRatio := pPr.LineSpacing / 240;
|
LineRatio := pPr.LineSpacing / 240;
|
||||||
//LineRatio := 1.0;
|
//LineRatio := 1.0;
|
||||||
|
|
@ -12746,7 +12746,8 @@ Type TSectPr = Class
|
||||||
n += cnt;
|
n += cnt;
|
||||||
if newLine then Begin
|
if newLine then Begin
|
||||||
_addLine(startPage, curPageNo, curLinePos, LineHeight + (linesCnt ? 0 : more), before, linesCnt ? false : true, t); //加入一行
|
_addLine(startPage, curPageNo, curLinePos, LineHeight + (linesCnt ? 0 : more), before, linesCnt ? false : true, t); //加入一行
|
||||||
PageLine.CurrentLine += _getHanging(linesCnt+1, pPr);
|
if ifObj(pPr) then
|
||||||
|
PageLine.CurrentLine += _getHanging(linesCnt+1, pPr);
|
||||||
linesCnt ++;
|
linesCnt ++;
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
|
|
@ -12945,6 +12946,32 @@ Type TDocumentBody = Class(DocObject)
|
||||||
_set_lastParagraph_(posOpt, p.node_);//设置最后一个段落
|
_set_lastParagraph_(posOpt, p.node_);//设置最后一个段落
|
||||||
return p;
|
return p;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///复制w:p节点内容
|
||||||
|
///paragraphObj: TParagraph对象
|
||||||
|
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;DocumentPart对象 在posOpt之后新添加段落
|
||||||
|
///返回TParagraph对象
|
||||||
|
Function CopyWp(paragraphObj, posOpt);
|
||||||
|
Begin
|
||||||
|
addPart(posOpt, paragraphObj, true);
|
||||||
|
p := new TParagraph(paragraphObj.node_);
|
||||||
|
//复制段落字体属性
|
||||||
|
p.CopyRunFormat(false, nil);
|
||||||
|
_set_lastParagraph_(posOpt, p.node_);//设置最后一个段落
|
||||||
|
return p;
|
||||||
|
End;
|
||||||
|
|
||||||
|
///复制w:tbl节点内容
|
||||||
|
///ttable: TTable对象
|
||||||
|
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;DocumentPart对象 在posOpt之后新添加段落
|
||||||
|
///返回TTable对象
|
||||||
|
Function CopyWtbl(table, posOpt);
|
||||||
|
Begin
|
||||||
|
addPart(posOpt, table, true);
|
||||||
|
p := new TTable(table.node_);
|
||||||
|
_set_lastParagraph_(posOpt, p.node_);
|
||||||
|
return p;
|
||||||
|
End;
|
||||||
|
|
||||||
///删除指定段落
|
///删除指定段落
|
||||||
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 第N段;posOpt段落
|
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 第N段;posOpt段落
|
||||||
|
|
@ -13927,13 +13954,14 @@ Type TDocumentBody = Class(DocObject)
|
||||||
return id;
|
return id;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function addPart(posOpt, o);
|
Function addPart(posOpt, o, flag);
|
||||||
Begin
|
Begin
|
||||||
node := posOpt;
|
node := posOpt;
|
||||||
if ifObj(posOpt) and not (posOpt is Class(XmlNode)) then
|
if ifObj(posOpt) and not (posOpt is Class(XmlNode)) then
|
||||||
node := posOpt.Node();
|
node := posOpt.Node();
|
||||||
node := findNode(node, true);
|
node := findNode(node, true);
|
||||||
nodeArr := o.Marshal();
|
if flag then nodeArr := o.node_.Marshal()[0];
|
||||||
|
else nodeArr := o.Marshal();
|
||||||
if ifObj(node) then Begin
|
if ifObj(node) then Begin
|
||||||
o.node_ := node_.InsertAfterChild(node, nodeArr); //XmlNode节点对象或DocObject对象
|
o.node_ := node_.InsertAfterChild(node, nodeArr); //XmlNode节点对象或DocObject对象
|
||||||
End
|
End
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Version 1.4.1
|
// Version 1.4.2
|
||||||
|
|
||||||
Type TSDocxFile = Class
|
Type TSDocxFile = Class
|
||||||
///Version: V1.0 2022-09-20
|
///Version: V1.0 2022-09-20
|
||||||
|
|
@ -371,6 +371,24 @@ Type TSDocxFile = Class
|
||||||
End;
|
End;
|
||||||
return nil;
|
return nil;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///复制Word内容
|
||||||
|
///docxObj: TSDocxFile对象
|
||||||
|
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加图片
|
||||||
|
///返回: [err, TDocxCopy对象]
|
||||||
|
///TDocxCopy.GetCopiedTable() 返回复制的对象表格数组
|
||||||
|
///TDocxCopy.GetCopiedParagraph() 返回复制对象的段落数组
|
||||||
|
///TDocxCopy.GetCopiedDrawing() 返回复制对象的图表数组
|
||||||
|
Function InsertFile(alias, fileName, posOpt);
|
||||||
|
Begin
|
||||||
|
docxObj := new TSDocxFile();
|
||||||
|
[err, msg] := docxObj.OpenFile(alias, fileName);
|
||||||
|
if err then return array(err, msg);
|
||||||
|
copy_obj := new TDocxCopy(self, docxObj);
|
||||||
|
copy_obj.Init();
|
||||||
|
copy_obj.Copy(posOpt);
|
||||||
|
return array(0, copy_obj);
|
||||||
|
End;
|
||||||
|
|
||||||
///遍历文档中所有[TSTAG][/TSTAG]标签,针对每一个TAG执行tagObj.Apply()
|
///遍历文档中所有[TSTAG][/TSTAG]标签,针对每一个TAG执行tagObj.Apply()
|
||||||
///tagName:string 标签名称
|
///tagName:string 标签名称
|
||||||
|
|
@ -561,8 +579,8 @@ Type TSDocxFile = Class
|
||||||
DocPrId_ ++;
|
DocPrId_ ++;
|
||||||
return DocPrId_;
|
return DocPrId_;
|
||||||
End;
|
End;
|
||||||
private
|
|
||||||
Function getPosNode(posOpt);
|
Function GetPosNode(posOpt);
|
||||||
Begin
|
Begin
|
||||||
node := posOpt;
|
node := posOpt;
|
||||||
if ifObj(node) and not (node is Class(XmlNode)) then
|
if ifObj(node) and not (node is Class(XmlNode)) then
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Version 1.4.1
|
// Version 1.4.2
|
||||||
|
|
||||||
Type TSExcelFile = Class
|
Type TSExcelFile = Class
|
||||||
///Version: V1.0 2022-08-08
|
///Version: V1.0 2022-08-08
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,447 @@
|
||||||
|
Type TDocxCopy = class
|
||||||
|
|
||||||
|
Function Create(oldObj, newObj)
|
||||||
|
Begin
|
||||||
|
old_docx_obj_ := oldObj;
|
||||||
|
new_docx_obj_ := newObj;
|
||||||
|
copy_table_ := array();
|
||||||
|
copy_paragraph_ := array();
|
||||||
|
copy_drawing_ := array();
|
||||||
|
style_copy_obj_ := new TDocxStyleCopy(oldObj.StyleObject(), newObj.StyleObject());
|
||||||
|
number_copy_obj_ := new TDocxNumberCopy(oldObj, newObj);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function Init();
|
||||||
|
Begin
|
||||||
|
style_copy_obj_.Init();
|
||||||
|
End;
|
||||||
|
|
||||||
|
///从posOpt位置开始复制word
|
||||||
|
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加图片
|
||||||
|
Function Copy(posOpt);
|
||||||
|
Begin
|
||||||
|
// 复制所有的样式
|
||||||
|
style_copy_obj_.CopyStyle();
|
||||||
|
|
||||||
|
parts := new_docx_obj_.Body().Parts();
|
||||||
|
pos := old_docx_obj_.GetPosNode(posOpt);
|
||||||
|
for i:=0 to length(parts)-1 do
|
||||||
|
begin
|
||||||
|
case GetPartType(parts[i]) of
|
||||||
|
0: pos := CopyParagraph(parts[i], pos);
|
||||||
|
1: pos := CopyDrawing(parts[i], pos);
|
||||||
|
2: pos := CopyTable(parts[i], pos);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyParagraph(obj, pos);
|
||||||
|
Begin
|
||||||
|
paragraph := old_docx_obj_.Body().CopyWp(obj, pos);
|
||||||
|
SetParagraphInfo(paragraph);
|
||||||
|
copy_paragraph_[length(copy_paragraph_)] := paragraph;
|
||||||
|
return paragraph;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyDrawing(obj, pos);
|
||||||
|
Begin
|
||||||
|
paragraph := old_docx_obj_.Body().CopyWp(obj, pos);
|
||||||
|
SetDrawingInfo(paragraph);
|
||||||
|
copy_drawing_[length(copy_drawing_)] := paragraph;
|
||||||
|
return paragraph;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyTable(obj, pos);
|
||||||
|
Begin
|
||||||
|
table := old_docx_obj_.Body().CopyWtbl(obj, pos);
|
||||||
|
SetTableInfo(table);
|
||||||
|
copy_table_[length(copy_table_)] := table;
|
||||||
|
return table;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetCopiedTable();
|
||||||
|
Begin
|
||||||
|
return copy_table_;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetCopiedParagraph();
|
||||||
|
Begin
|
||||||
|
return copy_paragraph_;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetCopiedDrawing();
|
||||||
|
Begin
|
||||||
|
return copy_drawing_;
|
||||||
|
End;
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
Function DeleteComment(paragraph);
|
||||||
|
Begin
|
||||||
|
node := paragraph.node_.FirstChildElement('w:commentRangeStart');
|
||||||
|
while ifObj(node) do
|
||||||
|
begin
|
||||||
|
name := node.GetName();
|
||||||
|
if name = "w:commentRangeStart" or name = "w:commentRangeEnd" then
|
||||||
|
begin
|
||||||
|
delete_node := node;
|
||||||
|
node := node.NextElement();
|
||||||
|
paragraph.node_.DeleteChild(delete_node);
|
||||||
|
if node.FirstChildElement('w:commentReference') then
|
||||||
|
begin
|
||||||
|
delete_node := node;
|
||||||
|
node := node.NextElement();
|
||||||
|
paragraph.node_.DeleteChild(delete_node);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
node := node.NextElement();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetPic(node);
|
||||||
|
Begin
|
||||||
|
// 获取新文件的图片
|
||||||
|
rembed := node.GetAttribute('r:embed');
|
||||||
|
rels := new_docx_obj_.Zip().Get('word/_rels/document.xml.rels');
|
||||||
|
target := class(TSXml).FindRelationshipTarget(rels, rembed);
|
||||||
|
image_file := new_docx_obj_.Zip().Get('word/' $ target).Data();
|
||||||
|
|
||||||
|
// 比较新文件的图片在旧文件中是否存在
|
||||||
|
zip := old_docx_obj_.Zip();
|
||||||
|
files := sselect ['FileName'] from zip.Files() where AnsiStartsText('word/media/image', ['FileName']) end;
|
||||||
|
for i:=0 to length(files)-1 do Begin
|
||||||
|
if zip.Diff(files[i], image_file) = 0 then Begin
|
||||||
|
prefix := ReplaceStr(files[i], 'word/', '');
|
||||||
|
[maxRid, imageFile, rid] := class(TSXml).FindRelationshipRid(xml, prefix);
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
xml := zip.Get('word/_rels/document.xml.rels');
|
||||||
|
if rid = 0 then
|
||||||
|
begin
|
||||||
|
image_cnt := length(files) + 1;
|
||||||
|
if ParseRegExpr("\\w+$", target, "", result, Mpos, Mlen) then
|
||||||
|
begin
|
||||||
|
postfix := result[0][0];
|
||||||
|
image_path := "media/image" $ image_cnt $ '.' $ postfix;
|
||||||
|
[rid, tar] := class(TSXml).FindRelationshipRid(xml, '');
|
||||||
|
rid ++;
|
||||||
|
class(TSXml).AddRelationshipRid(xml, image_path, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid);
|
||||||
|
zip.Add('word/' + image_path, image_file);
|
||||||
|
contentXml := zip.Get('[Content_Types].xml');
|
||||||
|
class(TSXml).AddDefaultContentType(contentXml, postfix, 'image/' $ postfix);
|
||||||
|
node.SetAttribute('r:embed', 'rId' $ rid);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetChart(node);
|
||||||
|
Begin
|
||||||
|
rid := node.GetAttribute('r:id');
|
||||||
|
rels := new_docx_obj_.Zip().Get('word/_rels/document.xml.rels');
|
||||||
|
target := class(TSXml).FindRelationshipTarget(rels, rid);
|
||||||
|
new_zip := new_docx_obj_.Zip();
|
||||||
|
chart_file := new_zip.Get('word/' $ target);
|
||||||
|
|
||||||
|
// 复制charN.xml
|
||||||
|
zip := old_docx_obj_.Zip();
|
||||||
|
files := sselect ['FileName'] from zip.Files() where AnsiStartsText('word/charts/chart', ['FileName']) end;
|
||||||
|
new_chart_file := "charts/chart" $ (length(files) + 1) $ ".xml";
|
||||||
|
xml := zip.Get('word/_rels/document.xml.rels');
|
||||||
|
[new_rid, tar] := class(TSXml).FindRelationshipRid(xml, '');
|
||||||
|
new_rid++;
|
||||||
|
class(TSXml).AddRelationshipRid(xml, new_chart_file, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart", 'rId' $ new_rid);
|
||||||
|
zip.Add('word/' + new_chart_file, chart_file.Data());
|
||||||
|
contentXml := zip.Get('[Content_Types].xml');
|
||||||
|
class(TSXml).AddOverrideContentType(contentXml, '/word/' + new_chart_file, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
|
||||||
|
node.SetAttribute('r:id', 'rId' $ new_rid);
|
||||||
|
|
||||||
|
// 复制charN.xml.rels
|
||||||
|
chart_rels := "word/charts/_rels" + target[pos('/', target):] $ ".rels";
|
||||||
|
chart_rels_xml := new_zip.Get(chart_rels);
|
||||||
|
if ifObj(chart_rels_xml) then
|
||||||
|
begin
|
||||||
|
zip.Add('word/charts/_rels/chart' $ (length(files) + 1) $ ".xml.rels", chart_rels_xml.Data());
|
||||||
|
relationship := chart_rels_xml.FirstChildElement('Relationships').FirstChildElement('Relationship');
|
||||||
|
while ifObj(relationship) do
|
||||||
|
begin
|
||||||
|
target := relationship.GetAttribute('Target');
|
||||||
|
target_path := AnsiReplaceText(target, '..', 'word');
|
||||||
|
file := new_zip.Get(target_path);
|
||||||
|
if ifObj(file) then
|
||||||
|
begin
|
||||||
|
[new_file, filetype] := GetNewTargetFileName(zip, target_path);
|
||||||
|
zip.Add(new_file, file.Data());
|
||||||
|
if filetype then Class(TSXml).AddDefaultContentType(contentXml, filetype[2:], 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||||
|
end
|
||||||
|
relationship := relationship.NextElement();
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetNewTargetFileName(zip, fileName);
|
||||||
|
Begin
|
||||||
|
files := zip.Files()[:, 'FileName'];
|
||||||
|
ret := ParseRegExpr("(.*/)(\\w+)(\.\\w+)$", fileName, "", result, Mpos, Mlen);
|
||||||
|
count := 0;
|
||||||
|
while fileName in files do
|
||||||
|
begin
|
||||||
|
if ret then
|
||||||
|
fileName := result[0][1] $ result[0][2] $ "tinysoft" $ count $ result[0][3];
|
||||||
|
else fileName := fileName $ "tinysoft" $ count;
|
||||||
|
count++;
|
||||||
|
end
|
||||||
|
if ret then filetype := result[0][3];
|
||||||
|
return array(fileName, filetype);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetDrawingInfo(drawing);
|
||||||
|
Begin
|
||||||
|
graphic_node := class(TSXml).GetNode(drawing.node_,'w:r/w:drawing/wp:inline/a:graphic/a:graphicData');
|
||||||
|
if ifObj(graphic_node) then
|
||||||
|
begin
|
||||||
|
node := class(TSXml).GetNode(graphic_node,'pic:pic/pic:blipFill/a:blip');
|
||||||
|
if ifObj(node) then SetPic(node);
|
||||||
|
node := class(TSXml).GetNode(graphic_node, 'c:chart');
|
||||||
|
if ifObj(node) then SetChart(node);
|
||||||
|
end;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetParagraphInfo(paragraph);
|
||||||
|
Begin
|
||||||
|
style := class(TSXml).GetNode(paragraph.node_, 'w:pPr/w:pStyle');
|
||||||
|
if ifObj(style) then
|
||||||
|
begin
|
||||||
|
styleid := style.GetAttribute('w:val');
|
||||||
|
new_id := style_copy_obj_.GetStyleNewId(styleid);
|
||||||
|
if new_id then style.SetAttribute('w:val', new_id);
|
||||||
|
end
|
||||||
|
numpr := class(TSXml).GetNode(paragraph.node_, 'w:pPr/w:numPr/w:numId');
|
||||||
|
if ifObj(numpr) then
|
||||||
|
begin
|
||||||
|
id := numpr.GetAttribute('w:val');
|
||||||
|
numberid := number_copy_obj_.CopyNumbering(id);
|
||||||
|
numpr.SetAttribute('w:val', id);
|
||||||
|
end
|
||||||
|
DeleteComment(paragraph); // 删除批注
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetTableInfo(table);
|
||||||
|
Begin
|
||||||
|
style := class(TSXml).GetNode(table.node_, 'w:tblPr/w:tblStyle');
|
||||||
|
if ifObj(style) then
|
||||||
|
begin
|
||||||
|
id := style.GetAttribute('w:val');
|
||||||
|
new_id := style_copy_obj_.GetStyleNewId(id);
|
||||||
|
if new_id then style.SetAttribute('w:val', new_id);
|
||||||
|
end
|
||||||
|
col := table.Cols();
|
||||||
|
row := table.Rows();
|
||||||
|
for r:=1 to row do
|
||||||
|
begin
|
||||||
|
for c:=1 to col do
|
||||||
|
begin
|
||||||
|
node := table.Cell(r, c).node_;
|
||||||
|
if (tbl := node.FirstChildElement('w:tbl')) then
|
||||||
|
begin
|
||||||
|
obj := TOfficeObj('TTable');
|
||||||
|
obj.Init(tbl);
|
||||||
|
SetTableInfo(obj);
|
||||||
|
end
|
||||||
|
else if (p := node.FirstChildElement('w:p')) then
|
||||||
|
begin
|
||||||
|
draw := class(TSXml).GetNode(p, 'w:r/w:drawing');
|
||||||
|
if ifObj(draw) then
|
||||||
|
begin
|
||||||
|
obj := TOfficeObj('TPicture');
|
||||||
|
obj.Init(p);
|
||||||
|
SetDrawingInfo(obj);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
obj := TOfficeObj('TParagraph');
|
||||||
|
obj.Init(p);
|
||||||
|
SetParagraphInfo(obj);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
/// 普通段落: 0
|
||||||
|
/// 图片段落: 1
|
||||||
|
/// 表格: 2
|
||||||
|
/// 其他类型暂不复制
|
||||||
|
Function GetPartType(part);
|
||||||
|
Begin
|
||||||
|
name := part.name_;
|
||||||
|
case name of
|
||||||
|
'w:p':
|
||||||
|
begin
|
||||||
|
if class(TSXml).GetNode(part.node_, 'w:r/w:drawing') then return 1;
|
||||||
|
return 0;
|
||||||
|
end
|
||||||
|
'w:tbl':
|
||||||
|
return 2;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
private
|
||||||
|
old_docx_obj_;
|
||||||
|
new_docx_obj_;
|
||||||
|
style_copy_obj_;
|
||||||
|
number_copy_obj_;
|
||||||
|
|
||||||
|
copy_table_;
|
||||||
|
copy_paragraph_;
|
||||||
|
copy_drawing_;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Type TDocxStyleCopy = class
|
||||||
|
|
||||||
|
Function Create(oldObj, newObj);
|
||||||
|
Begin
|
||||||
|
old_style_obj_ := oldObj;
|
||||||
|
new_style_obj_ := newObj;
|
||||||
|
style_id_map_ := array();
|
||||||
|
style_name_map_ := array();
|
||||||
|
style_id_map2_ := array();
|
||||||
|
style_name_map2_ := array();
|
||||||
|
id_map_ := array();
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function Init();
|
||||||
|
Begin
|
||||||
|
id_styles := new_style_obj_.Styles();
|
||||||
|
for id, obj in id_styles do
|
||||||
|
begin
|
||||||
|
new_obj := obj;
|
||||||
|
id_map_[id] := new_obj;
|
||||||
|
SetId(new_obj, id);
|
||||||
|
SetName(new_obj);
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyStyle();
|
||||||
|
Begin
|
||||||
|
for id, obj in id_map_ do
|
||||||
|
begin
|
||||||
|
SetBasedOn(obj);
|
||||||
|
SetLink(obj);
|
||||||
|
old_style_obj_.CopyStyle(obj);
|
||||||
|
end;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetStyleNewId(oldId)
|
||||||
|
Begin
|
||||||
|
if ifnumber(oldId) then oldId := tostring(oldId);
|
||||||
|
return style_id_map_[oldId];
|
||||||
|
End;
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
Function SetId(obj, id);
|
||||||
|
Begin
|
||||||
|
new_id := GetNewId(id);
|
||||||
|
obj.node_.SetAttribute('w:styleId', new_id);
|
||||||
|
style_id_map_[id] := new_id;
|
||||||
|
style_id_map2_[new_id] := id;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetName(obj);
|
||||||
|
Begin
|
||||||
|
name_node := obj.node_.FirstChildElement('w:name');
|
||||||
|
name := name_node.GetAttribute('w:val');
|
||||||
|
new_name := GetNewName(name);
|
||||||
|
name_node.SetAttribute('w:val', new_name);
|
||||||
|
style_name_map_[name] := new_name;
|
||||||
|
style_name_map2_[new_name] := name;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetBasedOn(obj);
|
||||||
|
Begin
|
||||||
|
basedon := obj.node_.FirstChildElement('w:basedOn');
|
||||||
|
if ifObj(basedon) then
|
||||||
|
begin
|
||||||
|
val := basedon.GetAttribute('w:val');
|
||||||
|
if style_id_map_[val] then basedOn.SetAttribute('w:val', style_id_map_[val]);
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetLink(obj);
|
||||||
|
Begin
|
||||||
|
link := obj.node_.FirstChildElement('w:link');
|
||||||
|
if ifObj(link) then
|
||||||
|
begin
|
||||||
|
val := link.GetAttribute('w:val');
|
||||||
|
if style_id_map_[val] then link.SetAttribute('w:val', style_id_map_[val]);
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetNewName(name);
|
||||||
|
Begin
|
||||||
|
new_name := name;
|
||||||
|
count := 0;
|
||||||
|
while ifObj(old_style_obj_.GetStyle(new_name)) or style_name_map2_[new_name] do
|
||||||
|
new_name := new_name $ count++;
|
||||||
|
return new_name;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetNewId(id);
|
||||||
|
Begin
|
||||||
|
new_id := id;
|
||||||
|
count := 0;
|
||||||
|
while ifObj(old_style_obj_.GetStyleById(new_id)) or style_id_map2_[new_id] do
|
||||||
|
new_id := new_id $ count++;
|
||||||
|
return new_id;
|
||||||
|
End;
|
||||||
|
|
||||||
|
private
|
||||||
|
old_style_obj_;
|
||||||
|
new_style_obj_;
|
||||||
|
|
||||||
|
style_id_map_; // [old_id: new_id];
|
||||||
|
style_name_map_; // [old_name: new_name];
|
||||||
|
style_id_map2_; // [new_id: old_id];
|
||||||
|
style_name_map2_; // [old_name: new_name];
|
||||||
|
|
||||||
|
id_map_; // [id: styleobj]
|
||||||
|
End;
|
||||||
|
|
||||||
|
Type TDocxNumberCopy = class
|
||||||
|
|
||||||
|
Function Create(oldObj, newObj);
|
||||||
|
Begin
|
||||||
|
numberingxml := newObj.Zip().Get('word/numbering.xml');
|
||||||
|
if ifObj(numberingxml) then
|
||||||
|
begin
|
||||||
|
old_number_obj_ := oldObj.NumberingObject();
|
||||||
|
new_number_obj_ := newObj.NumberingObject();
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
old_number_obj_ := nil;
|
||||||
|
new_number_obj_ := nil;
|
||||||
|
end
|
||||||
|
number_id_map_ := array();
|
||||||
|
id_map_ := array();
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyNumbering(number);
|
||||||
|
Begin
|
||||||
|
if ifObj(old_number_obj_) and ifObj(new_number_obj_) then
|
||||||
|
begin
|
||||||
|
if (obj := new_number_obj_.NumberStyle(number)) then
|
||||||
|
begin
|
||||||
|
return old_number_obj_.CopyNumber(obj);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
End;
|
||||||
|
|
||||||
|
private
|
||||||
|
old_number_obj_;
|
||||||
|
new_number_obj_;
|
||||||
|
|
||||||
|
id_map_; // [id: styleobj]
|
||||||
|
End;
|
||||||
|
|
@ -133,6 +133,23 @@ Type TDocxStyles = Class
|
||||||
return nil;
|
return nil;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///复制样式
|
||||||
|
///newstyle:样式节点TDocxStyle对象
|
||||||
|
///返回:TDocxStyle对象
|
||||||
|
Function CopyStyle(newstyle);
|
||||||
|
Begin
|
||||||
|
if ifObj(newstyle) and ifObj(newstyle.node_) then Begin
|
||||||
|
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(newstyle.node_.Marshal()[0]);
|
||||||
|
obj := TOfficeObj('TDocxStyle');
|
||||||
|
obj.StyleId := node.GetAttribute('w:styleId');
|
||||||
|
obj.Name := node.FirstChildElement('w:name').GetAttribute('w:val');
|
||||||
|
obj.Init(node);
|
||||||
|
_addStyle(obj);
|
||||||
|
return obj;
|
||||||
|
End;
|
||||||
|
return nil;
|
||||||
|
End;
|
||||||
|
|
||||||
///插入新的LatentStyle段落样式
|
///插入新的LatentStyle段落样式
|
||||||
///o:TDocxStyle对象
|
///o:TDocxStyle对象
|
||||||
///返回:TDocxStyle对象
|
///返回:TDocxStyle对象
|
||||||
|
|
@ -185,4 +202,4 @@ private
|
||||||
idMap_;
|
idMap_;
|
||||||
nameMap_;
|
nameMap_;
|
||||||
maxStyleId_:integer;
|
maxStyleId_:integer;
|
||||||
End;
|
End;
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,19 @@ Type TNumbering = Class
|
||||||
numIdMap_[''$num.numId] := num.abstractNumId;
|
numIdMap_[''$num.numId] := num.abstractNumId;
|
||||||
return num.numId;
|
return num.numId;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///复制number样式
|
||||||
|
///numberObj: 样式xmlNode
|
||||||
|
Function CopyNumber(numberObj);
|
||||||
|
Begin
|
||||||
|
obj := AddStyle(numberObj, true);
|
||||||
|
num := TOfficeObj('TNumber');
|
||||||
|
num.numId := maxNumId_++;
|
||||||
|
num.abstractNumId := obj.Id;
|
||||||
|
numberingXml_.FirstChildElement('w:numbering').InsertEndChild(num.Marshal());
|
||||||
|
numIdMap_[''$num.numId] := num.abstractNumId;
|
||||||
|
return num.numId;
|
||||||
|
End;
|
||||||
|
|
||||||
///根据numId获取TNumStyle对象(已存在)
|
///根据numId获取TNumStyle对象(已存在)
|
||||||
///返回:TNumStyle对象
|
///返回:TNumStyle对象
|
||||||
|
|
@ -148,14 +161,16 @@ Type TNumbering = Class
|
||||||
///新添加项目样式
|
///新添加项目样式
|
||||||
///o:TNumStyle对象
|
///o:TNumStyle对象
|
||||||
///返回:TNumStyle对象
|
///返回:TNumStyle对象
|
||||||
Function AddStyle(o);
|
Function AddStyle(o, flag);
|
||||||
Begin
|
Begin
|
||||||
if ifObj(o) then Begin
|
if ifObj(o) then Begin
|
||||||
o.abstractNumId := maxAbstractNumId_++;
|
o.abstractNumId := maxAbstractNumId_++;
|
||||||
|
if flag then marshal := o.node_.Marshal()[0];
|
||||||
|
else marshal := o.Marshal();
|
||||||
if ifObj(lastAbstractNumStyle_) then
|
if ifObj(lastAbstractNumStyle_) then
|
||||||
node := numberingXml_.FirstChildElement('w:numbering').InsertAfterChild(lastAbstractNumStyle_, o.Marshal());
|
node := numberingXml_.FirstChildElement('w:numbering').InsertAfterChild(lastAbstractNumStyle_, marshal);
|
||||||
else
|
else
|
||||||
node := numberingXml_.FirstChildElement('w:numbering').InsertFirstChild(o.Marshal());
|
node := numberingXml_.FirstChildElement('w:numbering').InsertFirstChild(marshal);
|
||||||
lastAbstractNumStyle_ := node;
|
lastAbstractNumStyle_ := node;
|
||||||
o := TOfficeObj('TNumStyle');
|
o := TOfficeObj('TNumStyle');
|
||||||
o.Init(node);
|
o.Init(node);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue