This commit is contained in:
csh
2026-07-30 14:05:16 +08:00
parent 6b0f11cebb
commit 3df8ce2be0
6 changed files with 222 additions and 215 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
// Version 1.8.6 // Version 1.8.7
Function TOfficeObj(n); Function TOfficeObj(n);
Begin Begin
case lowercase(n) of case lowercase(n) of
+1 -1
View File
@@ -1,4 +1,4 @@
// Version 1.8.6 // Version 1.8.7
Type TSDocxFile = Class Type TSDocxFile = Class
///Version: V1.0 2022-09-20 ///Version: V1.0 2022-09-20
///适用于 Microsoft Word docx格式文件 ///适用于 Microsoft Word docx格式文件
+1 -1
View File
@@ -1,4 +1,4 @@
// Version 1.8.6 // Version 1.8.7
Type TSXlsxFile = Class Type TSXlsxFile = Class
///Version: V1.0 2022-08-08 ///Version: V1.0 2022-08-08
///适用于 Microsoft Excel? 2007 及以上版本创建的电子表格文档。支持 XLSX / XLSM / XLTM / XLTX 等多种文档格式。 ///适用于 Microsoft Excel? 2007 及以上版本创建的电子表格文档。支持 XLSX / XLSM / XLTM / XLTX 等多种文档格式。
+2 -4
View File
@@ -501,18 +501,16 @@ private
Function GetNewName(name); Function GetNewName(name);
Begin Begin
new_name := name; new_name := name;
count := 0;
while ifObj(old_style_obj_.GetStyle(class(TSXml).Utf8ToCurCodePage(new_name))) or style_name_map2_[new_name] do while ifObj(old_style_obj_.GetStyle(class(TSXml).Utf8ToCurCodePage(new_name))) or style_name_map2_[new_name] do
new_name := new_name $ count++; new_name := new_name $ crc32(inttostr(random(2000000)));
return new_name; return new_name;
End; End;
Function GetNewId(id); Function GetNewId(id);
Begin Begin
new_id := id; new_id := id;
count := 0;
while ifObj(old_style_obj_.GetStyleById(new_id)) or style_id_map2_[new_id] do while ifObj(old_style_obj_.GetStyleById(new_id)) or style_id_map2_[new_id] do
new_id := new_id $ count++; new_id := new_id $ crc32(inttostr(random(2000000)));
return new_id; return new_id;
End; End;
+207 -206
View File
@@ -1,206 +1,207 @@
Type TDocxStyles = Class Type TDocxStyles = Class
//段落格式 //段落格式
Function Create(docx); Function Create(docx);
Begin Begin
docx_ := docx; docx_ := docx;
stylesXml_ := docx.Zip().Get('word/styles.xml'); stylesXml_ := docx.Zip().Get('word/styles.xml');
idMap_ := array(); idMap_ := array();
nameMap_ := array(); nameMap_ := array();
maxStyleId_ := 1; maxStyleId_ := 1;
if ifObj(stylesXml_) then Begin if ifObj(stylesXml_) then Begin
stylesNode := stylesXml_.FirstChildElement('w:styles'); stylesNode := stylesXml_.FirstChildElement('w:styles');
if ifObj(stylesNode) then Begin if ifObj(stylesNode) then Begin
node := stylesNode.FirstChildElement('w:style'); node := stylesNode.FirstChildElement('w:style');
while ifObj(node) do Begin while ifObj(node) do Begin
o := TOfficeObj('TDocxStyle'); o := TOfficeObj('TDocxStyle');
o.Init(node); o.Init(node);
id := StrToIntDef(o.StyleId, 0); id := StrToIntDef(o.StyleId, 0);
if id > 0 and maxStyleId_ <= id then if id > 0 and maxStyleId_ <= id then
maxStyleId_ := id + 1; maxStyleId_ := id + 1;
_addStyle(o); _addStyle(o);
node := node.NextElement('w:style'); node := node.NextElement('w:style');
End; End;
pNode := class(TSXml).GetNode(stylesNode, 'w:docDefaults/w:pPrDefault'); pNode := class(TSXml).GetNode(stylesNode, 'w:docDefaults/w:pPrDefault');
if ifObj(pNode) then if ifObj(pNode) then
defaultPpr_ := Class(TSXml).ReadPprFormat(pNode); defaultPpr_ := Class(TSXml).ReadPprFormat(pNode);
rNode := class(TSXml).GetNode(stylesNode, 'w:docDefaults/w:rPrDefault'); rNode := class(TSXml).GetNode(stylesNode, 'w:docDefaults/w:rPrDefault');
if ifObj(rNode) then if ifObj(rNode) then
defaultRpr_ := Class(TSXml).ReadRprFormat(rNode); defaultRpr_ := Class(TSXml).ReadRprFormat(rNode);
End; End;
End; End;
End; End;
///缺省样式 ///缺省样式
///styleType:样式类型(paragraph、character、table ///styleType:样式类型(paragraph、character、table
///返回:TDocxStyle对象 ///返回:TDocxStyle对象
Function Default(styleType); Function Default(styleType);
Begin Begin
for k, obj in idMap_ do Begin for k, obj in idMap_ do Begin
if obj.wType = styleType then Begin if obj.wType = styleType then Begin
v := obj.node_.GetAttribute('w:default'); v := obj.node_.GetAttribute('w:default');
if v <> '1' then if v <> '1' then
return obj; return obj;
End; End;
End End
return nil; return nil;
End; End;
///返回指定名称的TDocxStyle ///返回指定名称的TDocxStyle
///name:样式名称 ///name:样式名称
///返回:TDocxStyle对象 ///返回:TDocxStyle对象
Function GetStyle(name); Function GetStyle(name);
Begin Begin
return nameMap_[ class(TSXml).CurCodePageToUtf8(lowercase(name)) ]; return nameMap_[ class(TSXml).CurCodePageToUtf8(lowercase(name)) ];
End; End;
///返回指定StyleId名称的TDocxStyle ///返回指定StyleId名称的TDocxStyle
///idStyleID号(数字ID号或名称字符串) ///idStyleID号(数字ID号或名称字符串)
///返回:TDocxStyle对象 ///返回:TDocxStyle对象
Function GetStyleById(id); Function GetStyleById(id);
Begin Begin
newid := ifnumber(id) ? tostring(id) : id; newid := ifnumber(id) ? tostring(id) : id;
return idMap_[ newid ]; return idMap_[ newid ];
End; End;
//返回全部LatentStyles对象列表 //返回全部LatentStyles对象列表
//返回:TDocxStyle对象列表 //返回:TDocxStyle对象列表
Function LatentStyles(); Function LatentStyles();
Begin Begin
r := array(); r := array();
node := stylesXml_.FirstChildElement('w:styles'); node := stylesXml_.FirstChildElement('w:styles');
if ifObj(node) then if ifObj(node) then
node := node.FirstChildElement('w:latentStyles'); node := node.FirstChildElement('w:latentStyles');
if ifObj(node) then Begin if ifObj(node) then Begin
node := node.FirstChildElement('w:lsdException'); node := node.FirstChildElement('w:lsdException');
while ifObj(node) do Begin while ifObj(node) do Begin
o := TOfficeObj('TDocxStyle'); o := TOfficeObj('TDocxStyle');
o.Init(node); o.Init(node);
r[ length(r) ] := o; r[ length(r) ] := o;
node := node.NextElement('w:lsdException'); node := node.NextElement('w:lsdException');
End; End;
End; End;
return r; return r;
End; End;
///返回全部Styles对象列表 ///返回全部Styles对象列表
///返回:TDocxStyle对象列表 ///返回:TDocxStyle对象列表
Function Styles(); Function Styles();
Begin Begin
return idMap_; return idMap_;
End; End;
///插入新的段落样式 ///插入新的段落样式
///styleId:样式ID,可以是自定义名称 ///styleId:样式ID,可以是自定义名称
///xmlStrInnerXml串 ///xmlStrInnerXml串
///返回:TDocxStyle对象 ///返回:TDocxStyle对象
Function AddStyleByInnerXml(styleId, xmlStr); Function AddStyleByInnerXml(styleId, xmlStr);
Begin Begin
if ifstring(styleId) and styleId <> '' then Begin if ifstring(styleId) and styleId <> '' then Begin
style := GetStyle(styleId); style := GetStyle(styleId);
if ifObj(style) then if ifObj(style) then
return style; return style;
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(xmlStr); node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(xmlStr);
node.SetAttribute('w:styleId', styleId); node.SetAttribute('w:styleId', styleId);
End End
else Begin else Begin
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(xmlStr); node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(xmlStr);
node.SetAttribute('w:styleId', maxStyleId_++); node.SetAttribute('w:styleId', maxStyleId_++);
End; End;
o := TOfficeObj('TDocxStyle'); o := TOfficeObj('TDocxStyle');
o.Init(node); o.Init(node);
_addStyle(o); _addStyle(o);
return o; return o;
End; End;
///插入新的段落样式 ///插入新的段落样式
///oTDocxStyle对象 ///oTDocxStyle对象
///StyleId:样式ID,可以是自定义名称 ///StyleId:样式ID,可以是自定义名称
///返回:TDocxStyle对象 ///返回:TDocxStyle对象
Function AddStyle(o, StyleId); Function AddStyle(o, StyleId);
Begin Begin
if ifObj(o) then Begin if ifObj(o) then Begin
if ifString(StyleId) and StyleId <> '' and not ifObj(idMap_[ StyleId ]) then if ifString(StyleId) and StyleId <> '' and not ifObj(idMap_[ StyleId ]) then
o.StyleId := StyleId; o.StyleId := StyleId;
else else
o.StyleId := maxStyleId_++; o.StyleId := maxStyleId_++;
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(o.Marshal()); node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(o.Marshal());
obj := TOfficeObj('TDocxStyle'); obj := TOfficeObj('TDocxStyle');
obj.Init(node); obj.Init(node);
_addStyle(obj); _addStyle(obj);
return obj; return obj;
End; End;
return nil; return nil;
End; End;
///复制样式 ///复制样式
///newstyle:样式节点TDocxStyle对象 ///newstyle:样式节点TDocxStyle对象
///返回:TDocxStyle对象 ///返回:TDocxStyle对象
Function CopyStyle(newstyle); Function CopyStyle(newstyle);
Begin Begin
if ifObj(newstyle) and ifObj(newstyle.node_) then Begin if ifObj(newstyle) and ifObj(newstyle.node_) then Begin
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(newstyle.node_.Marshal()[0]); node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(newstyle.node_.Marshal()[0]);
obj := TOfficeObj('TDocxStyle'); node.DeleteAttribute('w:default');
obj.StyleId := node.GetAttribute('w:styleId'); obj := TOfficeObj('TDocxStyle');
obj.Name := node.FirstChildElement('w:name').GetAttribute('w:val'); obj.StyleId := node.GetAttribute('w:styleId');
obj.Init(node); obj.Name := node.FirstChildElement('w:name').GetAttribute('w:val');
_addStyle(obj); obj.Init(node);
return obj; _addStyle(obj);
End; return obj;
return nil; End;
End; return nil;
End;
///插入新的LatentStyle段落样式
///oTDocxStyle对象 ///插入新的LatentStyle段落样式
///返回TDocxStyle对象 ///oTDocxStyle对象
Function AddLatentStyle(o); ///返回:TDocxStyle对象
Begin Function AddLatentStyle(o);
if ifObj(o) then Begin Begin
latentStyles := stylesXml_.FirstChildElement('w:styles').InsertEndChild('w:latentStyles'); if ifObj(o) then Begin
node := latentStyles.InsertEndChild('lsdException'); latentStyles := stylesXml_.FirstChildElement('w:styles').InsertEndChild('w:latentStyles');
node.UnMarshal(o); node := latentStyles.InsertEndChild('lsdException');
latentStyles.SetAttribute('w:count', length(LatentStyles())); node.UnMarshal(o);
return node; latentStyles.SetAttribute('w:count', length(LatentStyles()));
End; return node;
return nil; End;
End; return nil;
End;
///插入缺省的段落样式(Title、Heading1-9
///返回:TDocxStyle对象 ///插入缺省的段落样式(Title、Heading1-9
Function AddDefaultStyle(Name); ///返回:TDocxStyle对象
Begin Function AddDefaultStyle(Name);
styleId := AnsiReplaceText(Name, ' ', ''); Begin
charId := StyleId + 'Char'; styleId := AnsiReplaceText(Name, ' ', '');
styleFname := 'wStyle/' + styleId + '.xml'; charId := StyleId + 'Char';
cStyleFname := 'wStyle/' + charId + '.xml'; styleFname := 'wStyle/' + styleId + '.xml';
xmlData := TOfficeTemplate(styleFname); cStyleFname := 'wStyle/' + charId + '.xml';
if ifnil(xmlData) then xmlData := TOfficeTemplate(styleFname);
return xmlData; if ifnil(xmlData) then
o := AddStyleByInnerXml(styleId, xmlData); return xmlData;
o := AddStyleByInnerXml(styleId, xmlData);
charStyle := idMap_[charId];
if not ifObj(charStyle) then Begin charStyle := idMap_[charId];
xmlData := TOfficeTemplate(cStyleFname); if not ifObj(charStyle) then Begin
if ifstring(xmlData) then Begin xmlData := TOfficeTemplate(cStyleFname);
AddStyleByInnerXml(charId, xmlData); if ifstring(xmlData) then Begin
End; AddStyleByInnerXml(charId, xmlData);
End; End;
return o; End;
End; return o;
End;
Function _addStyle(o);
Begin Function _addStyle(o);
idMap_[ o.StyleId ] := o; Begin
nameMap_[ lowercase(o.Name) ] := o; idMap_[ o.StyleId ] := o;
End; nameMap_[ lowercase(o.Name) ] := o;
End;
defaultPpr_;
defaultRpr_; defaultPpr_;
private defaultRpr_;
[weakref]docx_; private
stylesXml_; [weakref]docx_;
idMap_; stylesXml_;
nameMap_; idMap_;
maxStyleId_:integer; nameMap_;
End; maxStyleId_:integer;
End;
+10 -2
View File
@@ -1,8 +1,16 @@
# 更新日志 # 更新日志
## 2026-07-30
### V1.8.7
#### word
1. 修复`InsertFile`时,样式重复导致wps/word识别失败从而渲染错误问题
## 2026-01-16 ## 2026-01-16
#### V1.8.6 ### V1.8.6
修复语法问题 修复语法问题
@@ -12,7 +20,7 @@
## 2025-12-15 ## 2025-12-15
#### V1.8.5 ### V1.8.5
#### word #### word