294 lines
9.1 KiB
Plaintext
294 lines
9.1 KiB
Plaintext
Type xlsxStyles = Class
|
|
|
|
Function Create(sheetobj, file);
|
|
Begin
|
|
sheet_ := sheetobj;
|
|
file_ := file;
|
|
styleXmlFile_ := file_.WorkBook().GetXmlFileObj('xl/styles.xml');
|
|
End
|
|
|
|
Function GetStyleId(style);overload;
|
|
Begin
|
|
node := styleXmlFile_.FirstChildElement('styleSheet');
|
|
font_id := insertNode(node, 'fonts', style.Font);
|
|
border_id := insertNode(node, 'borders', style.Border);
|
|
fill_id := insertNode(node, 'fills', style.Fill);
|
|
|
|
processNumFmtId(node, 'numFmts', style.NumberFormat);
|
|
numfmt_id := insertNode(node, 'numFmts', style.NumberFormat);
|
|
|
|
alignment_marshal := style.Alignment.Marshal();
|
|
if istable(alignment_marshal['children']) or istable(alignment_marshal['attributes']) then
|
|
alignment_flag := 1;
|
|
protection_marshal := style.Protection.Marshal();
|
|
if istable(protection_marshal['children']) or istable(protection_marshal['attributes']) then
|
|
protection_flag := 1;
|
|
|
|
xf := TOfficeObj('TXf');
|
|
xf.NumFmtId := style.NumberFormat.NumFmtId ? : 0;
|
|
xf.FontId := font_id;
|
|
xf.FillId := fill_id;
|
|
xf.BorderId := border_id;
|
|
xf.XfId := 0;
|
|
xf.ApplyFont := font_id <> '0' ? 1 : nil;
|
|
xf.ApplyFill := fill_id <> '0' ? 1 : nil;
|
|
xf.ApplyBorder := border_id <> '0' ? 1 : nil;
|
|
xf.ApplyAlignment := alignment_flag ?: nil;
|
|
xf.ApplyProtection := protection_flag ?: nil;
|
|
xf.Alignment := style.Alignment;
|
|
xf.Protection := style.Protection;
|
|
|
|
node := node.FirstChildElement('cellXfs');
|
|
count := node.GetAttribute('count');
|
|
node.InsertEndChild(xf.Marshal());
|
|
node.SetAttribute('count', strtoint(count) + 1);
|
|
return count;
|
|
End;
|
|
|
|
Function GetStyleId(newStyle, oldStyleId);overload;
|
|
Begin
|
|
if oldStyleId = '' then return nil;
|
|
style_node := styleXmlFile_.FirstChildElement('styleSheet');
|
|
cellXfs_node := style_node.FirstChildElement('cellXfs');
|
|
count := strtoint(cellXfs_node.GetAttribute('count'));
|
|
Id := strtoint(oldStyleId);
|
|
if Id > count-1 then return nil;
|
|
|
|
xf := getNode(cellXfs_node, 'xf', Id);
|
|
marshal := xf.marshal()[0];
|
|
xf_node := cellXfs_node.InsertEndChild(marshal);
|
|
cellXfs_node.SetAttribute('count', count + 1);
|
|
attrs := marshal['attributes'];
|
|
|
|
style := newStyle;
|
|
|
|
numfmt_id := trystrtoint(attrs['numFmtId'], r) ? r : 0;
|
|
copyNode(style_node, xf_node, 'numFmts', 'numFmt', 'numFmtId', numfmt_id, style.NumberFormat);
|
|
|
|
font_id := trystrtoint(attrs['fontId'], r) ? r : 0;
|
|
copyNode(style_node, xf_node, 'fonts', 'font', 'fontId', font_id, style.Font);
|
|
|
|
border_id := trystrtoint(attrs['borderId'], r) ? r : 0;
|
|
copyNode(style_node, xf_node, 'borders', 'border', 'borderId', border_id, style.Border);
|
|
|
|
fill_id := trystrtoint(attrs['fillId'], r) ? r : 0;
|
|
copyNode(style_node, xf_node, 'fills', 'fill', 'fillId', fill_id, style.Fill);
|
|
|
|
marshal := style.Alignment.Marshal();
|
|
alignment := xf_node.FirstChildElement('alignment');
|
|
if ifObj(alignment) then class(TSXml).UpdateNode(alignment, marshal['attributes'], marshal['children']);
|
|
else begin
|
|
xf_node.InsertEndChild(marshal);
|
|
xf_node.SetAttribute('applyAlignment', 1);
|
|
end
|
|
marshal := style.Protection.Marshal();
|
|
protection := xf_node.FirstChildElement('protection');
|
|
if ifObj(protection) then class(TSXml).UpdateNode(protection, marshal['attributes'], marshal['children']);
|
|
else begin
|
|
xf_node.InsertEndChild(marshal);
|
|
xf_node.SetAttribute('applyProtection', 1);
|
|
end
|
|
|
|
return inttostr(count);
|
|
End;
|
|
|
|
Function GetStyle(styleId);
|
|
Begin
|
|
if styleId = '' then return nil;
|
|
style_node := styleXmlFile_.FirstChildElement('styleSheet');
|
|
cellXfs_node := style_node.FirstChildElement('cellXfs');
|
|
count := strtoint(cellXfs_node.GetAttribute('count'));
|
|
Id := strtoint(styleId);
|
|
if Id > count-1 then return nil;
|
|
|
|
xf := getNode(cellXfs_node, 'xf', Id);
|
|
attrs := xf.Attributes();
|
|
numfmt_id := trystrtoint(attrs['numFmtId'], r) ? r : 0;
|
|
font_id := trystrtoint(attrs['fontId'], r) ? r : 0;
|
|
border_id := trystrtoint(attrs['borderId'], r) ? r : 0;
|
|
fill_id := trystrtoint(attrs['fillId'], r) ? r : 0;
|
|
|
|
alignment := xf.FirstChildElement('alignment');
|
|
protection := xf.FirstChildElement('protection');
|
|
style := TOfficeObj('TStyle');
|
|
numFmts_node := style_node.FirstChildElement('numFmts');
|
|
fonts_node := style_node.FirstChildElement('fonts');
|
|
borders_node := style_node.FirstChildElement('borders');
|
|
fills_node := style_node.FirstChildElement('fills');
|
|
setRootObj(style.NumberFormat, getNode(numFmts_node, 'numFmt', numfmt_id));
|
|
setRootObj(style.Font, getNode(fonts_node, 'font', font_id));
|
|
setRootObj(style.Border, getNode(borders_node, 'border', border_id));
|
|
node := getNode(fills_node, 'fill', fill_id);
|
|
setRootObj(style.Fill, node);
|
|
setFillGradientObj(style.Fill.Gradient, node);
|
|
style.Alignment.RootObj := ifObj(alignment) ? alignment : nil;
|
|
style.Protection.RootObj := ifObj(protection) ? protection : nil;
|
|
setNodeUri(style);
|
|
return style;
|
|
End;
|
|
|
|
class Function NewObject(sheetname, file);
|
|
Begin
|
|
o := file.WorkBook().GetSheetObj(sheetname);
|
|
if not ifObj(o) then return 0;
|
|
styles := new xlsxStyles(o, file);
|
|
return styles;
|
|
End;
|
|
|
|
private
|
|
|
|
Function setFillGradientObj(obj, node);
|
|
Begin
|
|
gradient_node := node.FirstChildElement('gradientFill');
|
|
if not ifObj(gradient_node) then return;
|
|
stop_node := gradient_node.FirstChildElement('stop');
|
|
if ifObj(stop_node) then
|
|
begin
|
|
obj.Stop1.RootObj := stop_node;
|
|
obj.Stop1.NodeUri := '';
|
|
end
|
|
stop_node := stop_node.NextElement();
|
|
if ifObj(stop_node) then
|
|
begin
|
|
obj.Stop2.RootObj := stop_node;
|
|
obj.Stop2.NodeUri := '';
|
|
end
|
|
stop_node := stop_node.NextElement();
|
|
if ifObj(stop_node) then
|
|
begin
|
|
obj.Stop3.RootObj := stop_node;
|
|
obj.Stop3.NodeUri := '';
|
|
end
|
|
End;
|
|
|
|
Function setRootObj(obj, node);
|
|
Begin
|
|
obj.RootObj := node;
|
|
children := obj.GetChildren();
|
|
for i:=0 to length(children)-1 do
|
|
begin
|
|
val := children[i]['obj'];
|
|
if ifObj(val) then
|
|
begin
|
|
val.NodeUri := children[i]['name'];
|
|
val.RootObj := node;
|
|
end
|
|
end;
|
|
End;
|
|
|
|
Function setNodeUri(obj);
|
|
Begin
|
|
obj.NodeUri := '';
|
|
children := obj.GetChildren();
|
|
for i:=0 to length(children)-1 do
|
|
begin
|
|
val := children[i]['obj'];
|
|
if ifObj(val) then val.NodeUri := '';
|
|
end;
|
|
End;
|
|
|
|
Function getNode(rootNode, name, count);
|
|
Begin
|
|
if name = 'numFmt' then return getNodeNumFmts(rootNode, count);
|
|
if not ifObj(rootNode) then return nil;
|
|
node := rootNode.FirstChildElement(name);
|
|
times := count;
|
|
while times > 0 do
|
|
begin
|
|
node := node.NextElement();
|
|
times--;
|
|
end
|
|
return node;
|
|
End;
|
|
|
|
Function getNodeNumFmts(rootNode, id);
|
|
Begin
|
|
if not ifObj(rootNode) then return nil;
|
|
node := rootNode.FirstChildElement('numFmt');
|
|
num_id := inttostr(id);
|
|
while ifObj(node) do
|
|
begin
|
|
if num_id = node.GetAttribute('numFmtId') then return node;
|
|
node := node.NextElement();
|
|
end
|
|
return nil;
|
|
End;
|
|
|
|
Function copyNodeNumFmts(root, xf_node, id, obj);
|
|
Begin
|
|
if id = 0 then
|
|
begin
|
|
if ifnil(obj.FormatCode) then xf_node.SetAttribute('numFmtId', 0);
|
|
else begin
|
|
obj.NumFmtId := 176;
|
|
insertNode(root, 'numFmts', obj);
|
|
xf_node.SetAttribute('numFmtId', 176);
|
|
end
|
|
end
|
|
else begin
|
|
nodeName_node := root.FirstChildElement('numFmts');
|
|
println("id = {}", id);
|
|
num_node := getNodeNumFmts(nodeName_node, id);
|
|
processNumFmtId(root, 'numFmts', obj);
|
|
new_node := nodeName_node.InsertEndChild(num_node.Marshal()[0]);
|
|
count := strtoint(nodeName_node.GetAttribute('count'));
|
|
nodeName_node.SetAttribute('count', count + 1);
|
|
xf_node.SetAttribute('numFmtId', obj.NumFmtId);
|
|
marshal := obj.Marshal();
|
|
class(TSXml).UpdateNode(new_node, marshal['attributes'], marshal['children']);
|
|
end
|
|
End;
|
|
|
|
Function copyNode(root, xf_node, nodeName, name, idName, id, obj);
|
|
Begin
|
|
if nodeName = 'numFmts' then return copyNodeNumFmts(root, xf_node, id, obj);
|
|
nodeName_node := root.FirstChildElement(nodeName);
|
|
if not ifObj(nodeName_node) then return;
|
|
node := getNode(nodeName_node, name, id);
|
|
new_node := nodeName_node.InsertEndChild(node.Marshal()[0]);
|
|
count := strtoint(nodeName_node.GetAttribute('count'));
|
|
nodeName_node.SetAttribute('count', count + 1);
|
|
xf_node.SetAttribute(idName, count);
|
|
|
|
if ifObj(obj) then
|
|
begin
|
|
marshal := obj.Marshal();
|
|
class(TSXml).UpdateNode(new_node, marshal['attributes'], marshal['children']);
|
|
end;
|
|
End;
|
|
|
|
Function insertNode(rootNode, childName, obj);
|
|
Begin
|
|
marshal := obj.Marshal();
|
|
if not istable(marshal['children']) and not istable(marshal['attributes']) then return '0';
|
|
node := rootNode.FirstChildElement(childName);
|
|
if not ifObj(node) then
|
|
begin
|
|
info := array('name': childName, 'type': 'element', 'attributes': ('count': '0'));
|
|
rootNode.InsertFirstChild(info);
|
|
node := rootNode.FirstChildElement(childName);
|
|
end
|
|
count := node.GetAttribute('count');
|
|
node.InsertEndChild(marshal);
|
|
node.SetAttribute('count', strtoint(count) + 1);
|
|
return count;
|
|
End
|
|
|
|
Function processNumFmtId(rootNode, childName, obj);
|
|
Begin
|
|
if ifnil(obj.FormatCode) then return;
|
|
node := rootNode.FirstChildElement(childName);
|
|
if not ifObj(node) then id := 176;
|
|
else begin
|
|
node := node.LastChildElement('numFmt');
|
|
id := strtoint(node.GetAttribute('numFmtId')) + 1;
|
|
end
|
|
obj.numFmtId := id;
|
|
End
|
|
|
|
private
|
|
sheet_; //XmlSheet对象
|
|
file_; //TSExcelFile对象
|
|
styleXmlFile_; //xmlFile对象
|
|
End;
|