1621 lines
53 KiB
Plaintext
1621 lines
53 KiB
Plaintext
Type xlsxWorkBook = Class
|
||
///WorkBook文件操作接口
|
||
///规范1:类首字母小写,表示该类只在模块内部使用,不作为接口提供;
|
||
///规范2:成员变量首字母大写:成员可以被访问;
|
||
///规范3:成员变量首字母小写:不建议外部访问;
|
||
///规范4:成员函数首字母大写:成员函数可以被调用;
|
||
///规范5:成员函数首字母小写:不建议外部调用;
|
||
///规范6:成员变量以_结尾;
|
||
///规范7:字符串用单引号;
|
||
///规范8:模块tsf文件编码格式为UTF8
|
||
|
||
///缺省构造函数
|
||
Function Create(z); overload;
|
||
Begin
|
||
zipfile_ := z;
|
||
xmlFileObjMap_ := array();
|
||
sheetObjMap_ := array();
|
||
sheetPrefix_ := 'xl/worksheets/sheet';
|
||
End;
|
||
|
||
Function Load();
|
||
Begin
|
||
sheetsCount_ := 0;
|
||
sheetNames_ := array();
|
||
sheetIndexMap_ := array();
|
||
|
||
//workbook.xml.rels中加载(rid -> sheet-filename)
|
||
rids := array();
|
||
workbook_rels := GetXmlFileObj(class(TSXml).GetFileName('workbook_rels'));
|
||
rels := workbook_rels.FirstChildElement('Relationships').FirstChildElement('Relationship');
|
||
while ifObj(rels) do Begin
|
||
id := rels.GetAttribute('Id');
|
||
target := rels.GetAttribute('Target');
|
||
rids[ id ] := target;
|
||
rels := rels.NextElement();
|
||
End;
|
||
//workbook_rels.Print();
|
||
|
||
workbook := GetXmlFileObj('xl/workbook.xml');
|
||
//workbook.Print();
|
||
//workbook.Dump();
|
||
//echo tostn(workbook.dom());
|
||
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').FirstChildElement('sheet');
|
||
while ifObj(node) do Begin
|
||
name := node.GetAttribute("name");
|
||
sheetNames_[sheetsCount_]['name'] := name;
|
||
sheetNames_[sheetsCount_]['sheetId'] := strtoint(node.GetAttribute("sheetId"));
|
||
rid := node.GetAttribute("r:id");
|
||
sheetNames_[sheetsCount_]['rid'] := rid;
|
||
sheetNames_[sheetsCount_]['file'] := 'xl/' + rids[ rid ];
|
||
sheetIndexMap_[ LowerCase(name) ] := sheetsCount_;
|
||
sheetsCount_ ++;
|
||
node := node.NextElement('sheet');
|
||
End;
|
||
|
||
files := zipfile_.Files();
|
||
table_files := sselect ['FileName'] from files where AnsiContainsStr(['FileName'], 'tables/table') end;
|
||
for i:=0 to length(table_files)-1 do
|
||
begin
|
||
table_xml := GetXmlFileObj(table_files[i]);
|
||
if ifObj(table_xml) then
|
||
begin
|
||
display_name := table_xml.FirstChildElement('table').GetAttribute('displayName');
|
||
TOfficeApi().Set('Table-' $ display_name, true);
|
||
end
|
||
end
|
||
//echo tostn(sheetNames_);
|
||
End;
|
||
|
||
///获取工作表列表
|
||
Function GetSheets();
|
||
Begin
|
||
return sselect ['name'] from sheetNames_ end;
|
||
End;
|
||
|
||
Function GetSheetName(index);
|
||
Begin
|
||
name := GetSheets()[index];
|
||
return ifString(name) ? name : '';
|
||
End;
|
||
|
||
Function TotalCols(sheet);
|
||
Begin
|
||
o := GetSheetObj(sheet);
|
||
if ifObj(o) then return o.TotalCols();
|
||
End;
|
||
|
||
Function TotalRows(sheet);
|
||
Begin
|
||
o := GetSheetObj(sheet);
|
||
if ifObj(o) then return o.TotalRows();
|
||
End;
|
||
|
||
Function GetCellValue(sheet, axis);
|
||
Begin
|
||
o := GetSheetObj(sheet);
|
||
if ifObj(o) then return o.GetCellValue(axis);
|
||
return class(ErrorMessage).Fail();
|
||
End;
|
||
|
||
Function GetCellValueType(sheet, axis);
|
||
Begin
|
||
o := GetSheetObj(sheet);
|
||
if ifObj(o) then return o.GetAttribute(axis, '', 't')[1];
|
||
return '';
|
||
End;
|
||
|
||
Function SetCellValue(sheet, axis, val, opt);
|
||
Begin
|
||
o := GetSheetObj(sheet);
|
||
if ifObj(o) then
|
||
ret := o.SetCellValue(axis, val, opt);
|
||
return ret;
|
||
End;
|
||
|
||
Function SetCellStyleOpt(sheet, axis, opt);
|
||
Begin
|
||
o := GetSheetObj(sheet);
|
||
if ifObj(o) then
|
||
begin
|
||
if ifnil(opt['s']) and not o.CellIsExists(axis) then
|
||
begin
|
||
[err, col, row] := CellNameToCoordinates(axis);
|
||
xml := GetSheetXmlFile(sheet);
|
||
cols_node := xml.FirstChildElement('worksheet').FirstChildElement('cols');
|
||
if ifObj(cols_node) then
|
||
begin
|
||
col_node := cols_node.FirstChildElement();
|
||
while ifObj(col_node) do
|
||
begin
|
||
min := strtoint(col_node.GetAttribute('min'));
|
||
max := strtoint(col_node.GetAttribute('max'));
|
||
style := col_node.GetAttribute('style');
|
||
if col >= min and col <= max and style <> '' then
|
||
begin
|
||
opt['s'] := style;
|
||
break;
|
||
end
|
||
col_node := col_node.NextElement();
|
||
end
|
||
end
|
||
end
|
||
end
|
||
End;
|
||
|
||
Function GetCellRichText(sheet, axis);
|
||
Begin
|
||
o := GetSheetObj(sheet);
|
||
if ifObj(o) then return o.GetCellValue(axis, 'RichText');
|
||
return class(ErrorMessage).Fail();
|
||
End;
|
||
|
||
Function ClearCell(sheet, topLeft, bottomRight);
|
||
Begin
|
||
o := GetSheetObj(sheet);
|
||
if ifObj(o) then o.ClearCell(topLeft, bottomRight);
|
||
End;
|
||
|
||
Function SetCellFormula(sheet, axis, formula);
|
||
Begin
|
||
o := GetSheetObj(sheet);
|
||
if not o.CellIsExists(axis) then SetCellValue(sheet, axis, '');
|
||
if ifObj(o) then o.SetCellFormula(axis, formula);
|
||
End;
|
||
|
||
Function GetCellFormula(sheet, axis);
|
||
Begin
|
||
o := GetSheetObj(sheet);
|
||
if ifObj(o) then return o.GetCellFormula(axis);
|
||
return class(ErrorMessage).Fail();
|
||
End;
|
||
|
||
Function GetTable(sheet, topLeft, bottomRight, includeHeader, includeIndex, forceSingle);
|
||
Begin
|
||
o := GetSheetObj(sheet);
|
||
if ifObj(o) then
|
||
begin
|
||
data := o.Import(topLeft, bottomRight, includeHeader, includeIndex, forceSingle);
|
||
if not TOfficeApi().IsUtf8() then
|
||
begin
|
||
fields := fieldnames(data);
|
||
if ifarray(fields) and length(fields) then
|
||
begin
|
||
map := array();
|
||
for i:=0 to length(fields)-1 do
|
||
map[fields[i]] := class(TSXml).Utf8ToCurCodePage(fields[i]);
|
||
reindex(data, nil, map);
|
||
end
|
||
data::begin
|
||
if ifstring(mcell) then mcell := class(TSXml).Utf8ToCurCodePage(mcell);
|
||
end
|
||
end
|
||
return data;
|
||
end
|
||
End;
|
||
|
||
Function NewSheet(sheet);overload;
|
||
Begin
|
||
lname := LowerCase(sheet);
|
||
if ifint(sheetIndexMap_[ lname ]) then return 'The sheet already exists.';
|
||
|
||
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
|
||
sheetId := addSheetN(fname);
|
||
rid := setWorkbookRels();
|
||
setWorkbookSheet(sheet, sheetId, rid);
|
||
setDocPropsApp(sheet);
|
||
setContentTypes(fname);
|
||
|
||
sheetNames_[sheetsCount_]['name'] := sheet;
|
||
sheetNames_[sheetsCount_]['sheetId'] := sheetId;
|
||
sheetNames_[sheetsCount_]['rid'] := rid;
|
||
sheetNames_[sheetsCount_]['file'] := fname;
|
||
sheetIndexMap_[ lname ] := sheetsCount_;
|
||
sheetsCount_ ++;
|
||
SetDefaultSheet(sheet);
|
||
End;
|
||
|
||
Function addSheetN(fname);
|
||
Begin
|
||
//添加文件xl/worksheets/sheetN.xml
|
||
sheetId := vselect maxof(['sheetId']) from sheetNames_ end;
|
||
sheetId := integer(sheetId) + 1;
|
||
zipfile_.Add(fname, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('sheet1'));
|
||
return sheetId;
|
||
End;
|
||
|
||
Function setWorkbookRels();
|
||
Begin
|
||
rid := getWorkbookRelsRid();
|
||
//设置 workbook.xml.rels
|
||
workbook_rels := GetXmlFileObj('xl/_rels/workbook.xml.rels');
|
||
rels := workbook_rels.FirstChildElement('Relationships').InsertEndChild('element', 'Relationship');
|
||
rels.SetAttribute('Target', getTarget( sheetsCount_ + 1));
|
||
rels.SetAttribute('Type', class(TSXml).GetTemplate('RelationshipWorkSheet'));
|
||
rels.SetAttribute('Id', rid);
|
||
return rid;
|
||
End;
|
||
|
||
Function setWorkbookSheet(sheetName, sheetId, rid);
|
||
Begin
|
||
//设置 xl/workbook.xml
|
||
workbook := GetXmlFileObj('xl/workbook.xml');
|
||
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').InsertEndChild('element','sheet');
|
||
node.SetAttribute('name', sheetName);
|
||
node.SetAttribute('sheetId', sheetId);
|
||
node.SetAttribute('r:id', rid);
|
||
End;
|
||
|
||
Function setDocPropsApp(sheet);
|
||
Begin
|
||
//设置docProps/app.xml
|
||
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
|
||
properties_node := app.FirstChildElement('Properties');
|
||
// HeadingPairs
|
||
variant_node := class(TSXml).GetNode(properties_node, 'HeadingPairs/vt:vector/vt:variant');
|
||
while ifObj(variant_node) do
|
||
begin
|
||
vt_node := variant_node.FirstChildElement('vt:i4');
|
||
if ifObj(vt_node) then
|
||
begin
|
||
vt_node.SetValue(length(sheetNames_) + 1);
|
||
break;
|
||
end
|
||
variant_node := variant_node.NextElement();
|
||
end
|
||
|
||
// TitlesOfParts
|
||
vector := class(TSXml).GetNode(properties_node, 'TitlesOfParts/vt:vector');
|
||
vector.SetAttribute('size', length(sheetNames_) + 1);
|
||
vector.InsertEndChild('element', 'vt:lpstr', sheet);
|
||
End;
|
||
|
||
Function setContentTypes(fname);
|
||
Begin
|
||
//设置[Content_Types].xml
|
||
content_xml := GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
|
||
class(TSXml).AddOverrideContentType(content_xml, '/' + fname, class(TSXml).GetTemplate('sheetContentType'));
|
||
End;
|
||
|
||
Function insertWorkbookSheet(targetSheetName, newSheetName, sheetId, rId, direction);
|
||
Begin
|
||
workbook := GetXmlFileObj('xl/workbook.xml');
|
||
node := class(TSXml).GetNode(workbook, 'workbook/sheets');
|
||
sheet_node := node.FirstChildElement('sheet');
|
||
while ifObj(sheet_node) do
|
||
begin
|
||
if sheet_node.GetAttribute('name') = targetSheetName then
|
||
begin
|
||
if direction = "after" then
|
||
sheet_node := node.InsertAfterChild(sheet_node, 'element', 'sheet');
|
||
else
|
||
sheet_node := node.InsertBeforeChild(sheet_node, 'element', 'sheet');
|
||
sheet_node.SetAttribute('name', newSheetName);
|
||
sheet_node.SetAttribute('sheetId', sheetId);
|
||
sheet_node.SetAttribute('r:id', rid);
|
||
break;
|
||
end
|
||
sheet_node := sheet_node.NextElement();
|
||
end
|
||
End;
|
||
|
||
Function insertDocPropsApp(targetSheetName, newSheetName, direction);
|
||
Begin
|
||
//设置docProps/app.xml
|
||
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
|
||
properties_node := app.FirstChildElement('Properties');
|
||
// HeadingPairs
|
||
variant_node := class(TSXml).GetNode(properties_node, 'HeadingPairs/vt:vector/vt:variant');
|
||
while ifObj(variant_node) do
|
||
begin
|
||
vt_node := variant_node.FirstChildElement('vt:i4');
|
||
if ifObj(vt_node) then
|
||
begin
|
||
vt_node.SetValue(length(sheetNames_) + 1);
|
||
break;
|
||
end
|
||
variant_node := variant_node.NextElement();
|
||
end
|
||
|
||
// TitlesOfParts
|
||
vector := class(TSXml).GetNode(properties_node, 'TitlesOfParts/vt:vector');
|
||
vector.SetAttribute('size', length(sheetNames_) + 1);
|
||
lpstr := vector.FirstChildElement('vt:lpstr');
|
||
while ifObj(lpstr) do
|
||
begin
|
||
if LowerCase(lpstr.GetText()) = LowerCase(targetSheetName) then
|
||
begin
|
||
if direction = 'after' then
|
||
lpstr := vector.InsertAfterChild(lpstr, 'element', 'vt:lpstr');
|
||
else
|
||
lpstr := vector.InsertBeforeChild(lpstr, 'element', 'vt:lpstr');
|
||
lpstr.SetValue(newSheetName);
|
||
break;
|
||
end
|
||
lpstr := lpstr.NextElement();
|
||
end
|
||
End;
|
||
|
||
Function NewSheet(sourceSheet, destSheet);overload;
|
||
Begin
|
||
lname := LowerCase(destSheet);
|
||
if ifint(sheetIndexMap_[ lname ]) then return 'destSheet already exists.';
|
||
sname := LowerCase(sourceSheet);
|
||
if not ifint(sheetIndexMap_[ sname ]) then return 'sourceSheet does not exists';
|
||
|
||
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
|
||
sheetId := addSheetN(fname);
|
||
rid := setWorkbookRels();
|
||
insertWorkbookSheet(sourceSheet, destSheet, sheetId, rid, 'after');
|
||
insertDocPropsApp(sourceSheet, destSheet, 'after');
|
||
setContentTypes(fname);
|
||
|
||
ind := sheetIndexMap_[sname];
|
||
for i:=sheetsCount_ downto ind+2 do
|
||
begin
|
||
sheetNames_[i]['name'] := sheetNames_[i-1]['name'];
|
||
sheetNames_[i]['sheetId'] := sheetNames_[i-1]['sheetId'];
|
||
sheetNames_[i]['rid'] := sheetNames_[i-1]['rid'];
|
||
sheetNames_[i]['file'] := sheetNames_[i-1]['file'];
|
||
sheetIndexMap_[ LowerCase(sheetNames_[i]['name']) ] := i;
|
||
end
|
||
sheetIndexMap_[lname] := ind + 1;
|
||
sheetNames_[ind+1]['name'] := destSheet;
|
||
sheetNames_[ind+1]['sheetId'] := sheetId;
|
||
sheetNames_[ind+1]['rid'] := rid;
|
||
sheetNames_[ind+1]['file'] := fname;
|
||
sheetsCount_ ++;
|
||
SetDefaultSheet(destSheet);
|
||
End;
|
||
|
||
Function InsertSheet(sourceSheet, destSheet);
|
||
Begin
|
||
lname := LowerCase(destSheet);
|
||
if ifint(sheetIndexMap_[ lname ]) then return 'destSheet already exists.';
|
||
sname := LowerCase(sourceSheet);
|
||
if not ifint(sheetIndexMap_[ sname ]) then return 'sourceSheet does not exists';
|
||
|
||
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
|
||
sheetId := addSheetN(fname);
|
||
rid := setWorkbookRels();
|
||
insertWorkbookSheet(sourceSheet, destSheet, sheetId, rid, 'before');
|
||
insertDocPropsApp(sourceSheet, destSheet, 'before');
|
||
setContentTypes(fname);
|
||
|
||
ind := sheetIndexMap_[sname];
|
||
for i:=sheetsCount_ downto ind+1 do
|
||
begin
|
||
sheetNames_[i]['name'] := sheetNames_[i-1]['name'];
|
||
sheetNames_[i]['sheetId'] := sheetNames_[i-1]['sheetId'];
|
||
sheetNames_[i]['rid'] := sheetNames_[i-1]['rid'];
|
||
sheetNames_[i]['file'] := sheetNames_[i-1]['file'];
|
||
sheetIndexMap_[ LowerCase(sheetNames_[i]['name']) ] := i;
|
||
end
|
||
sheetIndexMap_[lname] := ind;
|
||
sheetNames_[ind]['name'] := destSheet;
|
||
sheetNames_[ind]['sheetId'] := sheetId;
|
||
sheetNames_[ind]['rid'] := rid;
|
||
sheetNames_[ind]['file'] := fname;
|
||
sheetsCount_ ++;
|
||
SetDefaultSheet(destSheet);
|
||
End;
|
||
|
||
Function DeleteSheet(sheet);
|
||
Begin
|
||
if sheetsCount_ <= 1 then return 'Cant not delete the last sheet.';
|
||
ind := sheetIndexMap_[ LowerCase(sheet) ];
|
||
if not ifint(ind) then return ;
|
||
|
||
del := sheetNames_[ind];
|
||
defaultSheet := GetDefaultSheet();
|
||
sheetsCount_--;
|
||
sheetNames_ := select * from sheetNames_ where thisrowindex <> ind end;
|
||
|
||
//删除文件xl/worksheets/sheetN.xml
|
||
zipfile_.Remove(del['file']);
|
||
|
||
//设置 workbook.xml.rels
|
||
files := zipfile_.Files();
|
||
for i:=0 to length(sheetNames_)-1 do Begin
|
||
sheetNames_[i]['rid'] := 'rId' + inttostr(i + 1); //重置rId
|
||
oldname := sheetNames_[i]['file'];
|
||
newname := sheetPrefix_ + inttostr(i + 1) + '.xml';
|
||
sheetNames_[i]['file'] := newname;
|
||
if oldname <> newname then Begin
|
||
n := vselect thisrowindex from files where ['FileName'] = oldname end;
|
||
if ifint(n) then Begin
|
||
files[n]['New-FileName'] := newname; //重置文件名
|
||
End;
|
||
End;
|
||
End;
|
||
for i:=0 to length(files)-1 do Begin
|
||
if ifstring(files[i]['New-FileName']) then Begin
|
||
f := zipfile_.Get(i);
|
||
f.FileName := files[i]['New-FileName'];
|
||
End;
|
||
End;
|
||
workbook_rels := GetXmlFileObj(class(TSXml).GetFileName('workbook_rels'));
|
||
parent := workbook_rels.FirstChildElement('Relationships');
|
||
rels := parent.FirstChildElement('Relationship');
|
||
while ifObj(rels) do Begin
|
||
target := rels.GetAttribute('Target');
|
||
if AnsiStartsText('worksheets/sheet', target) then Begin
|
||
parent.DeleteChild(rels);
|
||
break;
|
||
End;
|
||
rels := rels.NextElement();//删除节点
|
||
End;
|
||
//workbook_rels.Print();
|
||
i := 0;
|
||
maxRid := sheetsCount_ + 1;
|
||
node := workbook_rels.FirstChildElement('Relationships').FirstChildElement('Relationship');
|
||
while ifObj(node) do Begin
|
||
target := node.GetAttribute('Target');
|
||
if AnsiStartsText('worksheets/sheet', target) then Begin
|
||
node.SetAttribute('Target', getTarget( i + 1));//重置文件名
|
||
node.SetAttribute('Id', sheetNames_[i]['rid']);//重置rId
|
||
i++;
|
||
End
|
||
Else Begin
|
||
node.SetAttribute('Id', 'rId' $ maxRid);//重置rId
|
||
maxRid ++;
|
||
End;
|
||
node := node.NextElement();
|
||
End;
|
||
//workbook_rels.Print();
|
||
|
||
//设置 xl/workbook.xml
|
||
workbook := GetXmlFileObj('xl/workbook.xml');
|
||
workbook.FirstChildElement('workbook').FirstChildElement('sheets').DeleteChildren();
|
||
for i:=0 to length(sheetNames_)-1 do Begin
|
||
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').InsertEndChild('element','sheet');
|
||
node.SetAttribute('name', sheetNames_[i]['name']);
|
||
node.SetAttribute('sheetId', sheetNames_[i]['sheetId']);
|
||
node.SetAttribute('r:id', sheetNames_[i]['rid']);
|
||
End;
|
||
//workbook.Print();
|
||
|
||
//设置docProps/app.xml
|
||
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
|
||
node := app.FirstChildElement('Properties').FirstChildElement('TitlesOfParts');
|
||
if ifObj(node) then Begin
|
||
vector := node.FirstChildElement('vt:vector');
|
||
if ifObj(vector) then Begin
|
||
vector.SetAttribute('size', sheetsCount_);
|
||
n := vector.FirstChildElement('vt:lpstr');
|
||
while ifObj(n) do Begin
|
||
if n.GetText() = del['name'] then Begin
|
||
vector.DeleteChild(n);
|
||
break;
|
||
End;
|
||
n := n.NextElement();
|
||
End;
|
||
End;
|
||
End;
|
||
//app.Print();
|
||
|
||
//设置[Content_Types].xml
|
||
del_partname := '/' + sheetPrefix_ + inttostr(sheetsCount_ + 1) + '.xml';
|
||
DeleteContentType(del_partname);
|
||
|
||
//删除calcChain.xml
|
||
zipfile_.Remove('xl/calcChain.xml');
|
||
|
||
xmlFileObjMap_ := array();
|
||
|
||
//设置默认工作表
|
||
sheet_name := LowerCase(sheet);
|
||
ind := sheetIndexMap_[sheet_name];
|
||
for k, v in sheetIndexMap_ do
|
||
Begin
|
||
if v > ind then sheetIndexMap_[k] := v - 1;
|
||
End
|
||
reindex(sheetIndexMap_, array(sheet_name: nil));
|
||
ind--;
|
||
if ind < 0 then SetDefaultSheet(sheetNames_[0]['name']);
|
||
else if ind = length(sheetIndexMap_) then SetDefaultSheet(sheetNames_[length(sheetIndexMap_)]['name']);
|
||
else SetDefaultSheet(sheetNames_[ind]['name']);
|
||
|
||
xmlFileObjMap_ := array();
|
||
|
||
End;
|
||
|
||
Function CopySheet(sourceSheet, destSheet);
|
||
Begin
|
||
ind := sheetIndexMap_[ LowerCase(sourceSheet) ];
|
||
if not ifint(ind) then return sourceSheet $ ' does not exists.';
|
||
dest_ind := sheetIndexMap_[ LowerCase(destSheet) ];
|
||
|
||
//copy sheet
|
||
if ifint(dest_ind) then
|
||
begin
|
||
fname := sheetNames_[dest_ind]['file'];
|
||
zipfile_.Remove(fname);
|
||
end
|
||
else begin
|
||
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
|
||
end
|
||
sheet := GetSheetXmlFile(sourceSheet);
|
||
zipfile_.Add(fname, sheet.Data());
|
||
xml_file := GetXmlFileObj(fname);
|
||
sheet_node := xml_file.FirstChildElement('worksheet').FirstChildElement('sheetviews').FirstChildElement('sheetview');
|
||
if sheet_node.GetAttribute('tabSelected') = '1' then sheet_node.SetAttribute('tabSelected', 0);
|
||
|
||
// sheetN.xml.rels
|
||
DrawingFun := Function(obj, target, count);
|
||
Begin
|
||
rels_name := 'xl/drawings/_rels' + ReplaceStr(target, '../drawings', '') + '.rels';
|
||
rels_obj := GetXmlFileObj(rels_name);
|
||
rels_new_file := 'xl/drawings/_rels/drawing' $ count $ '.xml.rels';
|
||
if ifObj(rels_obj) then
|
||
begin
|
||
zipfile_.Add(rels_new_file, rels_obj.Data());
|
||
rels_file := GetXmlFileObj(rels_new_file);
|
||
relationship := rels_file.FirstChildElement('Relationships').FirstChildElement('Relationship');
|
||
while ifObj(relationship) do
|
||
begin
|
||
target := relationship.GetAttribute('Target');
|
||
if AnsiContainsStr(target, 'chart') then copyFile(relationship, target, 'chartContentType');
|
||
relationship := relationship.NextElement();
|
||
end
|
||
end
|
||
End;
|
||
sheet_rels := GetSheetRelsFile(sourceSheet);
|
||
if ifObj(sheet_rels) then
|
||
begin
|
||
if ifint(dest_ind) then
|
||
begin
|
||
rels_name := 'xl/worksheets/_rels/' + ExtractFileName(sheetNames_[dest_ind]['file']) + '.rels';
|
||
zipfile_.Remove(rels_name);
|
||
end
|
||
else begin
|
||
rels_name := 'xl/worksheets/_rels/' + 'sheet' + inttostr(sheetsCount_ + 1) + '.xml.rels';
|
||
end
|
||
zipfile_.Add(rels_name, sheet_rels.Data());
|
||
rels_file := GetXmlFileObj(rels_name);
|
||
relationship := rels_file.FirstChildElement('Relationships').FirstChildElement('Relationship');
|
||
while ifObj(relationship) do
|
||
begin
|
||
target := relationship.GetAttribute('Target');
|
||
if AnsiContainsStr(target, 'vmlDrawing') then copyFile(relationship, target);
|
||
else if AnsiContainsStr(target, 'drawing') then
|
||
begin
|
||
[count, file] := copyFile(relationship, target, 'drawingContentType');
|
||
##DrawingFun(relationship, target, count);
|
||
end
|
||
else if AnsiContainsStr(target, 'comments') then copyFile(relationship, target, 'commentContentType');
|
||
else if AnsiContainsStr(target, 'table') then
|
||
begin
|
||
[count, file] := copyFile(relationship, target, 'tableContentType');
|
||
table_xml := GetXmlFileObj(file).FirstChildElement('table');
|
||
table_xml.SetAttribute('id', count);
|
||
display_name := table_xml.GetAttribute('displayName');
|
||
display_name := class(xlsxTable).GenerateValidDisplayName(display_name, count);
|
||
table_xml.SetAttribute('displayName', display_name);
|
||
end
|
||
relationship := relationship.NextElement();
|
||
end
|
||
end
|
||
|
||
if ifint(dest_ind) then return;
|
||
|
||
//workbook.xml.rels
|
||
rid := getWorkbookRelsRid();
|
||
workbook_rels := GetXmlFileObj('xl/_rels/workbook.xml.rels');
|
||
rels := workbook_rels.FirstChildElement('Relationships').InsertEndChild('element', 'Relationship');
|
||
rels.SetAttribute('Target', getTarget( sheetsCount_ + 1));
|
||
rels.SetAttribute('Type', class(TSXml).GetTemplate('RelationshipWorkSheet'));
|
||
rels.SetAttribute('Id', rid);
|
||
|
||
//xl/workbook.xml
|
||
sheetId := vselect maxof(['sheetId']) from sheetNames_ end;
|
||
sheetId := integer(sheetId) + 1;
|
||
workbook := GetXmlFileObj('xl/workbook.xml');
|
||
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').InsertEndChild('element','sheet');
|
||
node.SetAttribute('name', destSheet);
|
||
node.SetAttribute('sheetId', sheetId);
|
||
node.SetAttribute('r:id', rid);
|
||
|
||
//app.xml
|
||
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
|
||
vector := app.FirstChildElement('Properties').FirstChildElement('TitlesOfParts').FirstChildElement('vt:vector');
|
||
vector.SetAttribute('size', sheetsCount_+1);
|
||
vector.InsertEndChild('element', 'vt:lpstr', destSheet);
|
||
|
||
//[Content_Types].xml
|
||
content_xml := GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
|
||
class(TSXml).AddOverrideContentType(content_xml, '/' + fname, class(TSXml).GetTemplate('sheetContentType'));
|
||
|
||
sheetNames_[sheetsCount_]['name'] := destSheet;
|
||
sheetNames_[sheetsCount_]['sheetId'] := sheetId;
|
||
sheetNames_[sheetsCount_]['rid'] := rid;
|
||
sheetNames_[sheetsCount_]['file'] := fname;
|
||
sheetIndexMap_[ LowerCase(destSheet) ] := sheetsCount_;
|
||
sheetsCount_ ++;
|
||
End;
|
||
|
||
Function SetSheetName(sourceName, destName);
|
||
Begin
|
||
ind := sheetIndexMap_[ LowerCase(destName) ];
|
||
if ifint(ind) then return destName $ ' already exists.';
|
||
ind := sheetIndexMap_[ LowerCase(sourceName) ];
|
||
if not ifint(ind) then return sourceName $ ' does not exists.';
|
||
|
||
//设置 xl/workbook.xml
|
||
workbook := GetXmlFileObj('xl/workbook.xml');
|
||
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').FirstChildElement('Sheet');
|
||
while ifObj(node) do
|
||
Begin
|
||
name := node.GetAttribute('name');
|
||
if LowerCase(name) = LowerCase(sourceName) then
|
||
Begin
|
||
node.SetAttribute('name', destName);
|
||
break;
|
||
End
|
||
node := node.NextElement();
|
||
End
|
||
|
||
//设置docProps/app.xml
|
||
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
|
||
node := app.FirstChildElement('Properties').FirstChildElement('TitlesOfParts');
|
||
lpstr := node.FirstChildElement('vt:vector').FirstChildElement('vt:lpstr');
|
||
while ifObj(lpstr) do
|
||
Begin
|
||
if LowerCase(lpstr.GetText()) = LowerCase(sourceName) then lpstr.SetValue(destName);
|
||
lpstr := lpstr.NextElement();
|
||
End
|
||
|
||
sheetNames_[ind]['name'] := destName;
|
||
reindex(sheetIndexMap_, array(LowerCase(sourceName) : LowerCase(destName)));
|
||
sheetObjMap_ := array();
|
||
End;
|
||
|
||
Function InsertCol(sheet, col);
|
||
Begin
|
||
sObj := GetSheetObj(sheet);
|
||
if ifObj(sObj) then sObj.InsertCol(col);
|
||
End;
|
||
|
||
Function InsertRow(sheet, row);
|
||
Begin
|
||
sObj := GetSheetObj(sheet);
|
||
if ifObj(sObj) then sObj.InsertRow(row);
|
||
End;
|
||
|
||
Function RemoveCol(sheet, col);
|
||
Begin
|
||
sObj := GetSheetObj(sheet);
|
||
if ifObj(sObj) then sObj.RemoveCol(col);
|
||
End;
|
||
|
||
Function RemoveRow(sheet, row);
|
||
Begin
|
||
sObj := GetSheetObj(sheet);
|
||
if ifObj(sObj) then sObj.RemoveRow(row);
|
||
End;
|
||
|
||
Function GetCharts(sheet);
|
||
Begin
|
||
ind := sheetIndexMap_[ LowerCase(sheet) ];
|
||
if not ifint(ind) then return array(-1, 'The sheet is not exist.');
|
||
//rid -> xl/worksheets/_rels/sheetN.xml.rels -> ="../drawings/drawingX.xml -> xl/drawings/_rels/drawingX.xml.rels -> charts
|
||
rid := sheetNames_[ind]['rid'];
|
||
id := rightstr(rid, length(rid)-3);
|
||
rels := 'xl/worksheets/_rels/sheet' + id + '.xml.rels';
|
||
if not FileIsExist(rels) then return array(0, array());
|
||
xmlfile := GetXmlFileObj(rels);
|
||
[rid2, target] := class(TSXml).FindRelationshipRid(xmlfile, '../drawings/drawing');
|
||
if target = '' then return array(0, array());
|
||
drawingFile := ReplaceStr(target, '..', 'xl');
|
||
drawingRels := 'xl/drawings/_rels/' + ExtractFileName(target) + '.rels';
|
||
if not FileIsExist(drawingRels) then return array(0, array());
|
||
xml := GetXmlFileObj(drawingRels);
|
||
charts := array();
|
||
node := xml.FirstChildElement('Relationships').FirstChildElement('Relationship');
|
||
|
||
while ifObj(node) do Begin
|
||
target := node.GetAttribute('Target');
|
||
if AnsiStartsText('../charts/chart', target) then Begin
|
||
chartFile := ReplaceStr(target, '..', 'xl');
|
||
chart := TOfficeObj('TChart');
|
||
chart.Rid := node.GetAttribute('Id'); //rid
|
||
chart.drawingFileName := drawingFile;
|
||
setChartInfo(chartFile, chart);
|
||
charts[i] := chart;
|
||
i++;
|
||
End;
|
||
node := node.NextElement();
|
||
End;
|
||
if length(charts) = 0 then return array(0, array());
|
||
chartNameMap := array();
|
||
xml := GetXmlFileObj(drawingFile);
|
||
node := xml.FirstChildElement('xdr:wsDr').FirstChildElement('xdr:twoCellAnchor');
|
||
while ifObj(node) do Begin
|
||
name := getNodeValue(node, 'xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr', 'name');
|
||
rid := getNodeValue(node, 'xdr:graphicFrame/a:graphic/a:graphicData/c:chart', 'r:id');
|
||
if rid <> '' and name <> '' then
|
||
chartNameMap[rid] := name;
|
||
node := node.NextElement('xdr:twoCellAnchor');
|
||
End;
|
||
for i:=0 to length(charts)-1 do Begin
|
||
charts[i].Name := chartNameMap[charts[i].Rid];
|
||
End;
|
||
return array(0, charts);
|
||
End;
|
||
|
||
Function GetSheetsCount();
|
||
Begin
|
||
return sheetsCount_;
|
||
End;
|
||
|
||
Function SetSheetVisible(sheet, visible);
|
||
Begin
|
||
workbook := GetXmlFileObj('xl/workbook.xml');
|
||
node := class(TSXml).GetNode(workbook, 'workbook/sheets/sheet');
|
||
if GetSheetsCount() = 1 then return "Only one sheet, can't set visible.";
|
||
sheet := lowercase(sheet);
|
||
default_sheet_name := lowercase(GetDefaultSheet());
|
||
if default_sheet_name = sheet and not visible then
|
||
begin
|
||
ind := sheetIndexMap_[LowerCase(default_sheet_name)];
|
||
default_name := ind = 0 ? sheetNames_[1]['name'] : sheetNames_[ind - 1]['name'];
|
||
SetDefaultSheet(default_name);
|
||
end
|
||
if visible then SetDefaultSheet(sheet);
|
||
state := visible ? "nohidden" : "hidden";
|
||
while ifObj(node) do
|
||
Begin
|
||
name := lowercase(node.GetAttribute('name'));
|
||
if name = sheet then
|
||
Begin
|
||
node.SetAttribute('state', state);
|
||
break;
|
||
End
|
||
node := node.NextElement();
|
||
End
|
||
return 'Can not find sheet: ' $ sheet;
|
||
End
|
||
|
||
Function GetSheetVisible(sheet);
|
||
Begin
|
||
sheet_file := GetSheetXmlFile(sheet);
|
||
if not ifObj(sheet_file) then return 0;
|
||
sheet := lowercase(sheet);
|
||
workbook := GetXmlFileObj('xl/workbook.xml');
|
||
node := class(TSXml).GetNode(workbook, 'workbook/sheets/sheet');
|
||
while ifObj(node) do
|
||
Begin
|
||
name := lowercase(node.GetAttribute('name'));
|
||
if name = sheet then
|
||
Begin
|
||
val := node.GetAttribute('state');
|
||
if val = 'hidden' then return 0;
|
||
return 1;
|
||
End
|
||
node := node.NextElement();
|
||
End
|
||
return 0;
|
||
End
|
||
|
||
Function SetRowVisible(sheet, row, visible)
|
||
Begin
|
||
hidden := visible = 1 ? 0 : 1;
|
||
sheet_obj := GetSheetObj(sheet);
|
||
is_exists := sheet_obj.RowIsExists(row);
|
||
if not is_exists then
|
||
begin
|
||
[err, cell] := CoordinatesToCellName(1, row);
|
||
sheet_obj.SetCellValue(cell, '');
|
||
end
|
||
sheet_obj.SetAttribute(row, array("hidden": hidden));
|
||
End
|
||
|
||
Function GetRowVisble(sheet, row)
|
||
Begin
|
||
sheet_obj := GetSheetObj(sheet);
|
||
if not ifObj(sheet_obj) then return class(ErrorMessage).SheetNotExist(sheet);
|
||
is_exists := sheet_obj.RowIsExists(row);
|
||
if is_exists then
|
||
begin
|
||
[err, hidden] := sheet_obj.GetAttribute(row, 'hidden');
|
||
if not err then
|
||
return array(0, hidden = '1' ? 0 : 1);
|
||
end
|
||
return array(0, 1);
|
||
End
|
||
|
||
Function SetColVisible(sheet, col, visible)
|
||
Begin
|
||
hidden := visible = 1 ? 0 : 1;
|
||
sheet_xml_file := GetSheetXmlFile(sheet);
|
||
if not ifObj(sheet_xml_file) then return 'The Sheet is not exist.';
|
||
work_node := sheet_xml_file.FirstChildElement('worksheet');
|
||
col_node := work_node.FirstChildElement('cols');
|
||
if not ifObj(col_node) and hidden then col_node := work_node.InsertAfterChild(work_node.FirstChildElement('sheetFormatPr'),'element', 'cols');
|
||
node := col_node.FirstChildElement('col');
|
||
while ifObj(node) do
|
||
Begin
|
||
min := strtoint(node.GetAttribute('min'));
|
||
max := strtoint(node.GetAttribute('max'));
|
||
val := trystrtoint(node.GetAttribute('hidden'), r) ? '' : r;
|
||
if col >= min and col <= max then
|
||
Begin
|
||
if hidden = val then return array(0, '');
|
||
else Begin
|
||
if col = min and col = max then
|
||
node.SetAttribute('hidden', hidden);
|
||
else if col = min then node.SetAttribute('min', col + 1);
|
||
else if col = max then node.SetAttribute('max', col - 1);
|
||
else Begin
|
||
node2 := col_node.InsertAfterChild(node, node.Marshal()[0]);
|
||
node.SetAttribute('max', col - 1);
|
||
node2.SetAttribute('min', col + 1);
|
||
End
|
||
return 'ok';
|
||
End
|
||
End
|
||
node := node.NextElement();
|
||
End
|
||
if hidden then
|
||
Begin
|
||
arr := array('type': 'element', 'name': 'col', 'attributes': ('min': col, 'max': col, 'width': 0, 'hidden': 1,
|
||
'customWidth': 1));
|
||
col_node.InsertEndChild(arr);
|
||
End
|
||
return 'ok';
|
||
End
|
||
|
||
Function GetColVisble(sheet, col);
|
||
Begin
|
||
sheet_xml_file := GetSheetXmlFile(sheet);
|
||
if not ifObj(sheet_xml_file) then return class(ErrorMessage).SheetNotExist();
|
||
work_node := sheet_xml_file.FirstChildElement('worksheet');
|
||
col_node := work_node.FirstChildElement('cols');
|
||
if not ifObj(col_node) then return array(0, 1);
|
||
node := col_node.FirstChildElement('col');
|
||
while ifObj(node) do
|
||
Begin
|
||
min := strtoint(node.GetAttribute('min'));
|
||
max := strtoint(node.GetAttribute('max'));
|
||
val := node.GetAttribute('hidden');
|
||
if col >= min and col <= max then
|
||
Begin
|
||
if val = '1' then return array(0, 0);
|
||
break;
|
||
End
|
||
node := node.NextElement();
|
||
End
|
||
return array(0, 1);
|
||
End
|
||
|
||
Function SetRowHeight(sheet, row, height);
|
||
Begin
|
||
obj := GetSheetObj(sheet);
|
||
obj.SetAttribute(row, array('ht': height, "customHeight": 1));
|
||
End
|
||
|
||
Function GetRowHeight(sheet, row)
|
||
Begin
|
||
obj := GetSheetObj(sheet);
|
||
ret := obj.GetAttribute(row, "ht");
|
||
if !ret[0] and trystrtofloat(ret[1], height) then return height;
|
||
sheet_xml_file := GetSheetXmlFile(sheet);
|
||
work_node := sheet_xml_file.FirstChildElement('worksheet');
|
||
default_ht := work_node.FirstChildElement('sheetFormatPr').GetAttribute('defaultRowHeight');
|
||
return strtofloat(default_ht);
|
||
End
|
||
|
||
Function SetColWidth(sheet, bCol, eCol, width);
|
||
Begin
|
||
startCol := bCol;
|
||
endCol := eCol;
|
||
startCol := ColumnNameToNumber(startCol)[1];
|
||
endCol := ColumnNameToNumber(endCol)[1];
|
||
if startCol > endCol then return;
|
||
sheet_xml_file := GetSheetXmlFile(sheet);
|
||
work_node := sheet_xml_file.FirstChildElement('worksheet');
|
||
col_node := class(TSXml).GetWorkSheetNode(work_node, 'cols');
|
||
node := col_node.FirstChildElement('col');
|
||
while ifObj(node) do
|
||
Begin
|
||
min := strtoint(node.GetAttribute('min'));
|
||
max := strtoint(node.GetAttribute('max'));
|
||
val := trystrtofloat(node.GetAttribute('width'), r) ? r : '';
|
||
if startCol = min and endCol = max then
|
||
begin
|
||
node.SetAttribute('width', width);
|
||
node.SetAttribute('customWidth', 1);
|
||
return;
|
||
end
|
||
else if startCol <= min and endCol >= max then
|
||
begin
|
||
node.SetAttribute('width', width);
|
||
node.SetAttribute('customWidth', 1);
|
||
node.SetAttribute('min', startCol);
|
||
node.SetAttribute('max', endCol);
|
||
node := node.NextElement();
|
||
while ifObj(node) do
|
||
begin
|
||
max := strtoint(node.GetAttribute('max'));
|
||
min := strtoint(node.GetAttribute('min'));
|
||
if max <= endCol and min <= endCol then
|
||
begin
|
||
delete_node := node;
|
||
node := node.NextElement();
|
||
col_node.DeleteChild(delete_node);
|
||
end
|
||
else node := node.NextElement();
|
||
end
|
||
return;
|
||
end
|
||
else if startCol >= min and endCol <= max then
|
||
begin
|
||
if width = val then return array(0, '');
|
||
if min = max then
|
||
Begin
|
||
node.SetAttribute('width', width);
|
||
node.SetAttribute('customWidth', 1);
|
||
return;
|
||
End
|
||
else Begin
|
||
insert_flag := 1;
|
||
node_new := col_node.InsertAfterChild(node, node.Marshal()[0]);
|
||
node.SetAttribute('max', startCol - 1);
|
||
node_new.SetAttribute('min', endCol + 1);
|
||
End
|
||
break;
|
||
end
|
||
node := node.NextElement();
|
||
End
|
||
arr := array('type': 'element', 'name': 'col', 'attributes': ('min': startCol, 'max': endCol, 'width': width,
|
||
'customWidth': 1));
|
||
if insert_flag then col_node.InsertAfterChild(node, arr);
|
||
else col_node.InsertEndChild(arr);
|
||
End;
|
||
|
||
Function GetColWidth(sheet, col);
|
||
Begin
|
||
sheet_xml_file := GetSheetXmlFile(sheet);
|
||
work_node := sheet_xml_file.FirstChildElement('worksheet');
|
||
col_node := work_node.FirstChildElement('cols');
|
||
default_width := work_node.FirstChildElement('sheetFormatPr').GetAttribute('defaultColWidth');
|
||
default_width := trystrtofloat(default_width, r) ? r: -1;
|
||
if not ifObj(col_node) then return array(0, default_width);
|
||
|
||
col_number := ColumnNameToNumber(col)[1];
|
||
node := col_node.FirstChildElement('col');
|
||
while ifObj(node) do
|
||
Begin
|
||
min := strtoint(node.GetAttribute('min'));
|
||
max := strtoint(node.GetAttribute('max'));
|
||
if col_number >= min and col_number <= max then
|
||
Begin
|
||
width := trystrtofloat(node.GetAttribute('width'), r) ? r : -1;
|
||
if width = -1 then break;
|
||
return width;
|
||
End
|
||
node := node.NextElement();
|
||
End
|
||
return default_width;
|
||
End;
|
||
|
||
Function SetCellStyle(sheet, topLeft, bottomRight, styleid);
|
||
Begin
|
||
o := GetSheetObj(sheet);
|
||
if ifObj(o) then return o.SetCellStyle(topLeft, bottomRight, styleid);
|
||
End;
|
||
|
||
Function GetCellStyle(sheet, axis);
|
||
Begin
|
||
sheet_obj := GetSheetObj(sheet);
|
||
if ifObj(sheet_obj) then
|
||
begin
|
||
[err, styleId] := sheet_obj.GetCellStyle(axis);
|
||
if not err then return styleId;
|
||
end
|
||
return '';
|
||
End;
|
||
|
||
Function MergeCell(sheet, hcell, vcell);
|
||
Begin
|
||
sheet_xml_file := GetSheetXmlFile(sheet);
|
||
if not ifObj(sheet_xml_file) then return 'The sheet is not exist.';
|
||
if hcell = vcell then return;
|
||
work_node := sheet_xml_file.FirstChildElement('worksheet');
|
||
merge_node := work_node.FirstChildElement('mergeCells');
|
||
if not ifObj(merge_node) then
|
||
Begin
|
||
merge_node := work_node.InsertAfterChild(work_node.FirstChildElement('sheetData'), 'element', 'mergeCells');
|
||
count := 0;
|
||
merge_node.SetAttribute('count', count);
|
||
End
|
||
else begin
|
||
count := trystrtoint(merge_node.GetAttribute('count'), r) ? r : 0;
|
||
end
|
||
node := merge_node.FirstChildElement('mergeCell');
|
||
hcell_ := SplitCellName(hcell);
|
||
vcell_ := SplitCellName(vcell);
|
||
hcell_int := ColumnNameToNumber(hcell_[1])[1];
|
||
vcell_int := ColumnNameToNumber(vcell_[1])[1];
|
||
while ifObj(node) do
|
||
Begin
|
||
ref := node.GetAttribute('ref');
|
||
position := pos(':', ref);
|
||
cell1 := SplitCellName(ref[1:position-1]);
|
||
cell2 := SplitCellName(ref[position+1:]);
|
||
cell1_int := ColumnNameToNumber(cell1[1])[1];
|
||
cell2_int := ColumnNameToNumber(cell2[1])[1];
|
||
if (hcell_[2] >= cell1[2] and hcell_[2] <= cell2[2] and hcell_int >= cell1_int and hcell_int <= cell2_int)
|
||
or (vcell_[2] >= cell1[2] and vcell_[2] <= cell2[2] and vcell_int >= cell1_int and vcell_int <= cell2_int)
|
||
then Begin
|
||
merge_node.DeleteChild(node);
|
||
break;
|
||
End
|
||
node := node.NextElement();
|
||
End
|
||
ref := hcell $ ":" $ vcell;
|
||
node := merge_node.InsertEndChild('element', 'mergeCell');
|
||
node.SetAttribute('ref', ref);
|
||
merge_node.SetAttribute('count', count + 1);
|
||
|
||
sheet_obj := GetSheetObj(sheet);
|
||
style_id := GetCellStyle(sheet, hcell);
|
||
sheet_obj.SetCellStyle(hcell, vcell, style_id = '' ? '0' : style_id);
|
||
End
|
||
|
||
Function UnMergeCell(sheet, hcell, vcell);
|
||
Begin
|
||
sheet_xml_file := GetSheetXmlFile(sheet);
|
||
if not ifObj(sheet_xml_file) then return 'The sheet is not exist';
|
||
work_node := sheet_xml_file.FirstChildElement('worksheet');
|
||
// mergeCells节点
|
||
merge_node := work_node.FirstChildElement('mergeCells');
|
||
if not ifObj(merge_node) then return '';
|
||
node := merge_node.FirstChildElement('mergeCell');
|
||
if not ifObj(node) then return '';
|
||
count := trystrtoint(merge_node.GetAttribute('count'), r) ? r : 0;
|
||
hcell_ := SplitCellName(hcell);
|
||
vcell_ := SplitCellName(vcell);
|
||
while ifObj(node) do
|
||
Begin
|
||
ref := node.GetAttribute('ref');
|
||
position := pos(':', ref);
|
||
cell1 := SplitCellName(ref[1:position-1]);
|
||
cell2 := SplitCellName(ref[position+1:]);
|
||
if ref[1:position-1] = hcell and ref[position+1:] = vcell
|
||
then Begin
|
||
merge_node.DeleteChild(node);
|
||
break;
|
||
End
|
||
node := node.NextElement();
|
||
End
|
||
if count - 1 <> 0 then
|
||
merge_node.SetAttribute('count', count - 1);
|
||
else
|
||
work_node.DeleteChild(merge_node);
|
||
End;
|
||
|
||
Function SetSheetDefaultColWidth(sheet, width);
|
||
Begin
|
||
sheet_xml_file := GetSheetXmlFile(sheet);
|
||
if not ifObj(sheet_xml_file) then return;
|
||
work_node := sheet_xml_file.FirstChildElement('worksheet');
|
||
node := work_node.FirstChildElement('sheetFormatPr');
|
||
node.SetAttribute('defaultColWidth', width);
|
||
End
|
||
|
||
Function GetSheetDefaultColWidth(sheet);
|
||
Begin
|
||
sheet_xml_file := GetSheetXmlFile(sheet);
|
||
if not ifObj(sheet_xml_file) then return nil;
|
||
work_node := sheet_xml_file.FirstChildElement('worksheet');
|
||
node := work_node.FirstChildElement('sheetFormatPr');
|
||
flag := trystrtofloat(node.GetAttribute('defaultColWidth'), width);
|
||
return flag ? width : nil;
|
||
End
|
||
|
||
Function SetDefaultSheet(sheet);
|
||
Begin
|
||
ind := sheetIndexMap_[ LowerCase(sheet) ];
|
||
if not ifint(ind) then return 'Can not find sheet: ' $ sheet;
|
||
for i:=0 to length(sheetnames_)-1 do
|
||
begin
|
||
name := sheetNames_[i]['name'];
|
||
file := sheetNames_[i]['file'];
|
||
xml_file := GetXmlFileObj(file);
|
||
if AnsiContainsText(file, 'chart') then root_node := xml_file.FirstChildElement('chartsheet');
|
||
else root_node := xml_file.FirstChildElement('worksheet');
|
||
sheet_node := class(TSXml).GetWorkSheetNode(root_node, 'sheetViews');
|
||
node := sheet_node.FirstChildElement('sheetView');
|
||
if not ifObj(node) then
|
||
begin
|
||
node := sheet_node.InsertFirstChild('element', 'sheetView');
|
||
node.SetAttribute('workbookViewId', 0);
|
||
end
|
||
if lowercase(name) = lowercase(sheet) then
|
||
Begin
|
||
node.SetAttribute('tabSelected', 1);
|
||
workbook := GetXmlFileObj('xl/workbook.xml');
|
||
view_node := class(TSXml).GetNode(workbook, 'workbook/bookViews/workbookView');
|
||
view_node.SetAttribute('activeTab', ind);
|
||
End
|
||
else
|
||
begin
|
||
node := root_node.FirstChildElement('sheetViews').FirstChildElement('sheetView');
|
||
node.SetAttribute('tabSelected', 0);
|
||
end
|
||
end
|
||
End
|
||
|
||
Function GetDefaultSheet();
|
||
Begin
|
||
for i:=0 to length(sheetnames_)-1 do
|
||
begin
|
||
name := sheetnames_[i]['name'];
|
||
file := sheetNames_[i]['file'];
|
||
xml_file := GetXmlFileObj(file);
|
||
if AnsiContainsText(file, 'chart') then root_node := xml_file.FirstChildElement('chartsheet');
|
||
else root_node := xml_file.FirstChildElement('worksheet');
|
||
sheet_node := root_node.FirstChildElement('sheetviews').FirstChildElement('sheetview');
|
||
if sheet_node.GetAttribute('tabSelected') = '1' then return name;
|
||
end
|
||
End
|
||
|
||
Function ProtectSheet(sheet, protect);
|
||
Begin
|
||
sheet_obj := GetSheetXmlfile(sheet);
|
||
work_node := sheet_obj.FirstChildElement('worksheet');
|
||
sheet_protection_node := work_node.FirstChildElement('sheetProtection');
|
||
if ifObj(sheet_protection_node) then work_node.DeleteChild(sheet_protection_node);
|
||
prev_node := class(TSXml).GetWorkSheetPrevNode(work_node, 'sheetProtection');
|
||
protect.Sheet := 1;
|
||
work_node.InsertAfterChild(prev_node, protect.Marshal());
|
||
End;
|
||
|
||
Function UnProtectSheet(sheet);
|
||
Begin
|
||
sheet_obj := GetSheetXmlfile(sheet);
|
||
work_node := sheet_obj.FirstChildElement('worksheet');
|
||
sheet_protection_node := work_node.FirstChildElement('sheetProtection');
|
||
if ifObj(sheet_protection_node) then work_node.DeleteChild(sheet_protection_node);
|
||
End;
|
||
|
||
Function GetXmlFileObj(n);
|
||
Begin
|
||
o := xmlFileObjMap_[ n ];
|
||
if not ifnil(o) then return o;
|
||
o := zipfile_.Get(n);
|
||
xmlFileObjMap_[ n ] := o;
|
||
return o;
|
||
End;
|
||
|
||
Function DeleteContentType(del_partname);
|
||
Begin
|
||
content := GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
|
||
types := content.FirstChildElement('Types');
|
||
element := types.FirstChildElement('Override');
|
||
while ifObj(element) do Begin
|
||
partname := element.GetAttribute('PartName');
|
||
if partname = del_partname then Begin
|
||
types.DeleteChild(element);
|
||
break;
|
||
End;
|
||
element := element.NextElement();
|
||
End;
|
||
//content.Print();
|
||
End;
|
||
|
||
Function GetRelationshipRid(sheet, prefix);
|
||
Begin
|
||
ind := sheetIndexMap_[ LowerCase(sheet) ];
|
||
file := 'xl/worksheets/_rels/' + ExtractFileName(sheetNames_[ind]['file']) + '.rels';
|
||
files := zipfile_.Files();
|
||
isexist := vselect thisrowindex from files where ['FileName']=file end;
|
||
if ifnil(isexist) then Begin
|
||
zipfile_.Add(file, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('sheet_rels'));
|
||
end
|
||
xmlfile := GetXmlFileObj(file);
|
||
r := class(TSXml).FindRelationshipRid(xmlfile, prefix);
|
||
r[2] := sheetNames_[ind]['file'];
|
||
r[3] := file;
|
||
return r;
|
||
End;
|
||
|
||
Function AddRelationshipRid(relsfile, target, type, rid);
|
||
Begin
|
||
xmlfile := GetXmlFileObj(relsfile);
|
||
class(TSXml).AddRelationshipRid(xmlfile, target, type, rid);
|
||
End;
|
||
|
||
Function GetFilesCount(prefix);
|
||
Begin
|
||
files := zipfile_.Files();
|
||
return vselect countof( ['FileName'] ) from files where AnsiStartsText(prefix, ['FileName']) end;
|
||
End;
|
||
|
||
Function FileIsExist(fname);
|
||
Begin
|
||
files := zipfile_.Files();
|
||
return vselect countof( ['FileName'] ) from files where ['FileName']=fname end;
|
||
End;
|
||
|
||
Function GetSheetRelsFile(sheet);
|
||
Begin
|
||
ind := sheetIndexMap_[LowerCase(sheet)];
|
||
file := 'xl/worksheets/_rels/' + ExtractFileName(sheetNames_[ind]['file']) + '.rels';
|
||
if not FileIsExist(file) then
|
||
zipfile_.Add(file, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('sheet_rels'));
|
||
return GetXmlFileObj(file);
|
||
End;
|
||
|
||
Function GetDrawingRelsFile(drawingId);
|
||
Begin
|
||
file := 'xl/drawings/_rels/drawing' + inttostr(drawingId) + '.xml.rels';
|
||
if not FileIsExist(drawing_rels) then
|
||
zipfile_.Add(file, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('drawing_rels'));
|
||
return GetXmlFileObj(file);
|
||
End;
|
||
|
||
Function GetSheetXmlFile(sheet);
|
||
Begin
|
||
ind := sheetIndexMap_[ LowerCase(sheet) ];
|
||
if not ifint(ind) then return 0;
|
||
return GetXmlFileObj(sheetNames_[ind]['file']);
|
||
End;
|
||
|
||
Function GetSheetObj(sheet);
|
||
Begin
|
||
o := sheetObjMap_[sheet];
|
||
if not ifnil(o) then return o;
|
||
|
||
ind := sheetIndexMap_[ LowerCase(sheet) ];
|
||
if not ifint(ind) then return 0;
|
||
f := GetXmlFileObj(sheetNames_[ind]['file']);
|
||
if not ifObj(f) then return 0;
|
||
o := f.Sheet();
|
||
sheetObjMap_[ sheet ] := o;
|
||
return o;
|
||
End;
|
||
|
||
Function GetSheetDrawing(sheet);
|
||
Begin
|
||
[rid, drawing_file_name, sheet_file_name, relsfile] := GetRelationshipRid(sheet, '../drawings/drawing');
|
||
if drawing_file_name = '' then
|
||
begin
|
||
rid ++;
|
||
drawing_rid := GetFilesCount('xl/drawings/drawing') + 1;
|
||
drawing_file_name := '../drawings/drawing' + inttostr(drawing_rid) + '.xml';
|
||
drawing_xl_file_name := 'xl/drawings/drawing' + inttostr(drawing_rid) + '.xml';
|
||
zipfile_.Add(drawing_xl_file_name, class(TSXml).XmlHeader() + '<xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"></xdr:wsDr>');
|
||
AddRelationshipRid(relsfile, drawing_file_name, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', 'rId' $ inttostr(rid));
|
||
content_xml := GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
|
||
class(TSXml).AddOverrideContentType(content_xml, '/' + drawing_xl_file_name, 'application/vnd.openxmlformats-officedocument.drawing+xml');
|
||
sheet_xml := GetXmlFileObj(sheet_file_name);
|
||
node := sheet_xml.FirstChildElement('worksheet');
|
||
prev_node := class(TSXml).GetWorkSheetPrevNode(node, 'drawing');
|
||
if ifObj(prev_node) then drawing_node := node.InsertAfterChild(prev_node, 'element', 'drawing');
|
||
else drawing_node := node.InsertEndChild('element', 'drawing');
|
||
drawing_node.SetAttribute('r:id', 'rId' + inttostr(rid));
|
||
end
|
||
else begin
|
||
drawing_xl_file_name := 'xl/drwaings/' + ExtractFileName(drawing_file_name);
|
||
s := RightStr(drawing_xl_file_name, length(drawing_xl_file_name) - 19);
|
||
drawing_rid := strtoint(LeftStr(s, length(s) - 4));
|
||
end
|
||
return drawing_rid;
|
||
End
|
||
|
||
Function InsertPageBreak(sheet, row);
|
||
Begin
|
||
if row <= 1 then return 'Row must be greater than 1.';
|
||
sheet_xml := GetSheetXmlFile(sheet);
|
||
worksheet := sheet_xml.FirstChildElement('worksheet');
|
||
page_node := worksheet.FirstChildElement('rowBreaks');
|
||
tbreak := TOfficeObj('TBreak');
|
||
tbreak.Id := row;
|
||
if not ifObj(page_node) then
|
||
begin
|
||
node := class(TSXml).GetWorkSheetPrevNode(worksheet, 'rowBreaks');
|
||
node := worksheet.InsertAfterChild(node, 'element', 'rowBreaks');
|
||
node.SetAttribute('count', 1);
|
||
node.SetAttribute('manualBreakCount', 1);
|
||
node.InsertFirstChild(tbreak.Marshal());
|
||
return '';
|
||
end
|
||
node := page_node.FirstChildElement('brk');
|
||
prev := nil;
|
||
prev_id := 0;
|
||
while ifObj(node) do
|
||
begin
|
||
id := strtoint(node.GetAttribute('id'));
|
||
if id = row then return array(0, '');
|
||
if row > prev_id and row < id then break;
|
||
prev_id := id;
|
||
prev := node;
|
||
node := node.NextElement();
|
||
end
|
||
if ifObj(prev) then page_node.InsertAfterChild(prev, tbreak.Marshal());
|
||
else page_node.InsertFirstChild(tbreak.Marshal());
|
||
count := strtoint(page_node.GetAttribute('count'));
|
||
manual_count := strtoint(page_node.GetAttribute('manualBreakCount'));
|
||
page_node.SetAttribute('count', count + 1);
|
||
page_node.SetAttribute('manualBreakCount', manual_count + 1);
|
||
|
||
return '';
|
||
End;
|
||
|
||
Function RemovePageBreak(sheet, row);
|
||
Begin
|
||
sheet_xml := GetSheetXmlFile(sheet);
|
||
page_node := sheet_xml.FirstChildElement('worksheet').FirstChildElement('rowBreaks');
|
||
if not ifObj(page_node) then return ;
|
||
node := page_node.FirstChildElement('brk');
|
||
while ifObj(node) do
|
||
begin
|
||
id := strtoint(node.GetAttribute('id'));
|
||
if id = row then
|
||
begin
|
||
page_node.DeleteChild(node);
|
||
return;
|
||
end
|
||
node := node.NextElement();
|
||
end
|
||
return;
|
||
End;
|
||
|
||
Function NewSheetPane();
|
||
Begin
|
||
workbook := GetXmlFileObj('xl/workbook.xml');
|
||
book_view_node := workbook.FirstChildElement('workbook').FirstChildElement('bookViews');
|
||
workbook_node := book_view_node.FirstChildElement('workbookView');
|
||
book_view_node.InsertEndChild(workbook_node.Marshal()[0]);
|
||
for i:=0 to length(sheetnames_)-1 do
|
||
begin
|
||
name := sheetNames_[i]['name'];
|
||
xml_file := GetXmlFileObj(sheetNames_[i]['file']);
|
||
sheet_node := xml_file.FirstChildElement('worksheet').FirstChildElement('sheetViews');
|
||
sheet_view := sheet_node.LastChildElement('sheetView');
|
||
view_id := strtoint(sheet_view.GetAttribute('workbookViewId')) + 1;
|
||
view_obj := TOfficeObj('TSheetView');
|
||
view_obj.WorkbookViewId := view_id;
|
||
sheet_node.InsertEndChild(view_obj.Marshal());
|
||
end
|
||
return view_id;
|
||
End;
|
||
|
||
Function SetDefaultFont(font);
|
||
Begin
|
||
style_xml := GetXmlFileObj('xl/styles.xml');
|
||
fonts_node := style_xml.FirstChildElement('styleSheet').FirstChildElement('fonts');
|
||
first_node := fonts_node.FirstChildElement('font');
|
||
marshal := font.Marshal();
|
||
class(TSXml).UpdateNode(first_node, marshal['attributes'], marshal['children']);
|
||
End;
|
||
|
||
Function GetDefaultFont();
|
||
Begin
|
||
style_xml := GetXmlFileObj('xl/styles.xml');
|
||
fonts_node := style_xml.FirstChildElement('styleSheet').FirstChildElement('fonts');
|
||
first_node := fonts_node.FirstChildElement('font');
|
||
tfont := TOfficeObj('TFont');
|
||
tfont.RootObj := first_node;
|
||
return tfont;
|
||
End;
|
||
|
||
Function SetCalcOptions(calcPr);
|
||
Begin
|
||
workbook_xml := GetXmlFileObj('xl/workbook.xml');
|
||
workbook_node := workbook_xml.FirstChildElement('workbook');
|
||
calc_node := workbook_node.FirstChildElement('calcPr');
|
||
marshal := calcPr.Marshal();
|
||
class(TSXml).UpdateNode(calc_node, marshal['attributes'], marshal['children']);
|
||
End;
|
||
|
||
Function GetCalcOptions();
|
||
Begin
|
||
workbook_xml := GetXmlFileObj('xl/workbook.xml');
|
||
node := workbook_xml.FirstChildElement('workbook').FirstChildElement('calcPr');
|
||
calcPr := TOfficeObj('TCalcPr');
|
||
calcPr.RootObj := node;
|
||
return calcPr;
|
||
End;
|
||
|
||
Function SetPageMargins(sheet, margins);
|
||
Begin
|
||
sheet_xml := GetSheetXmlFile(sheet);
|
||
work_node := sheet_xml.FirstChild('worksheet');
|
||
node := work_node.FirstChild('pageMargins');
|
||
if not ifObj(node) then
|
||
begin
|
||
prev_node := class(TSXml).GetWorkSheetPrevNode(work_node, 'pageMargins');
|
||
node := work_node.InsertAfterChild(prev_node, 'element', 'pageMargins');
|
||
end
|
||
marshal := margins.Marshal();
|
||
class(TSXml).UpdateNode(node, marshal['attributes'], marshal['children']);
|
||
End;
|
||
|
||
Function GetPageMargins(sheet);
|
||
Begin
|
||
sheet_xml := GetSheetXmlFile(sheet);
|
||
node := sheet_xml.FirstChild('worksheet').FirstChild('pageMargins');
|
||
margins := TOfficeObj('tmargins');
|
||
margins.RootObj := node;
|
||
return margins;
|
||
End;
|
||
|
||
Function SetRowOutlineLevel(sheet, row, level);
|
||
Begin
|
||
sheet_obj := GetSheetObj(sheet);
|
||
o := GetSheetObj(sheet);
|
||
if not sheet_obj.RowIsExists(row) then
|
||
begin
|
||
[err, cell] := CoordinatesToCellName(1, row);
|
||
sheet_obj.SetCellValue(cell, '');
|
||
end
|
||
sheet_obj.SetAttribute(row, array("outlineLevel": level));
|
||
End;
|
||
|
||
Function GetRowOutlineLevel(sheet, row);
|
||
Begin
|
||
sheet_obj := GetSheetObj(sheet);
|
||
o := GetSheetObj(sheet);
|
||
if not sheet_obj.RowIsExists(row) then return 0;
|
||
[err, level] := sheet_obj.GetAttribute(row, 'outlineLevel');
|
||
return level = '' ? 0 : strtoint(level);
|
||
End;
|
||
|
||
Function SetColOutlineLevel(sheet, col, level);
|
||
Begin
|
||
sheet_xml_file := GetSheetXmlFile(sheet);
|
||
if not ifObj(sheet_xml_file) then return 'The Sheet is not exist.';
|
||
work_node := sheet_xml_file.FirstChildElement('worksheet');
|
||
col_node := work_node.FirstChildElement('cols');
|
||
prev_node := class(TSXml).GetWorkSheetPrevNode(work_node, 'cols');
|
||
if not ifObj(col_node) then col_node := work_node.InsertAfterChild(prev_node,'element', 'cols');
|
||
node := col_node.FirstChildElement('col');
|
||
while ifObj(node) do
|
||
Begin
|
||
min := strtoint(node.GetAttribute('min'));
|
||
max := strtoint(node.GetAttribute('max'));
|
||
if col >= min and col <= max then
|
||
Begin
|
||
level_val := node.GetAttribute('outlineLevel');
|
||
if strtoint(level_val) = level then return;
|
||
else Begin
|
||
if col = min and col = max then node.SetAttribute('outlineLevel', level);
|
||
else begin
|
||
node2 := col_node.InsertAfterChild(node, node.Marshal()[0]);
|
||
if col = min then
|
||
begin
|
||
node.SetAttribute('max', col);
|
||
node.SetAttribute('outlineLevel', level);
|
||
node2.SetAttribute('min', col-1);
|
||
end
|
||
else if col = max then
|
||
begin
|
||
node.SetAttribute('max', col-1);
|
||
node2.SetAttribute('outlineLevel', level);
|
||
node2.SetAttribute('min', col);
|
||
end
|
||
else begin
|
||
node3 := col_node.InsertAfterChild(node, node.Marshal()[0]);
|
||
node.SetAttribute('max', col - 1);
|
||
node2.SetAttribute('min', col + 1);
|
||
node3.SetAttribute('min', col);
|
||
node3.SetAttribute('max', col);
|
||
node3.SetAttribute('outlineLevel', level);
|
||
end
|
||
end
|
||
return 'ok';
|
||
End
|
||
End
|
||
node := node.NextElement();
|
||
End
|
||
arr := array('type': 'element', 'name': 'col', 'attributes': ('min': col, 'max': col, 'outlineLevel': level, 'customWidth': 1, 'width': 9.06640625));
|
||
col_node.InsertEndChild(arr);
|
||
return 'ok';
|
||
End;
|
||
|
||
Function GetColOutlineLevel(sheet, col);
|
||
Begin
|
||
sheet_xml_file := GetSheetXmlFile(sheet);
|
||
if not ifObj(sheet_xml_file) then return "Sheet error";
|
||
work_node := sheet_xml_file.FirstChildElement('worksheet');
|
||
col_node := work_node.FirstChildElement('cols');
|
||
if not ifObj(col_node) then return 0;
|
||
node := col_node.FirstChildElement('col');
|
||
while ifObj(node) do
|
||
begin
|
||
min := strtoint(node.GetAttribute('min'));
|
||
max := strtoint(node.GetAttribute('max'));
|
||
val := node.GetAttribute('outlineLevel');
|
||
if col >= min and col <= max then return val = '' ? 0 : strtoint(val);
|
||
node := node.NextElement();
|
||
end
|
||
return 0;
|
||
End;
|
||
|
||
|
||
private
|
||
Function generateRow(c1, c2, r);
|
||
Begin
|
||
arr := array();
|
||
sr := inttostr(r);
|
||
for i:=c1 to c2 do
|
||
Begin
|
||
name := ColumnNumberToName(i);
|
||
if not name[0] then name := name[1];
|
||
name += sr;
|
||
arr union= array(('type': 'element', 'name': 'r', 'attributes': ('r': name, 's': '1')));
|
||
End
|
||
return arr;
|
||
End
|
||
|
||
Function getWorkbookRelsRid();
|
||
Begin
|
||
workbook_rels := GetXmlFileObj(class(TSXml).GetFileName('workbook_rels'));
|
||
[rId, find] := class(TSXml).FindRelationshipRid(workbook_rels, '');
|
||
rId ++;
|
||
return 'rId' $ rId;
|
||
End;
|
||
|
||
Function getTarget(i);
|
||
Begin
|
||
return 'worksheets/sheet' + inttostr(i) + '.xml';
|
||
End;
|
||
|
||
Function getNodeValue(nd, uri, key);
|
||
Begin
|
||
node := nd;
|
||
arr := str2array(uri, '/');
|
||
for i:=0 to length(arr)-1 do Begin
|
||
node := node.FirstChildElement(arr[i]);
|
||
if not ifObj(node) then return '';
|
||
End;
|
||
if key = '' then
|
||
return node.FirstChildElement().GetValue();
|
||
return node.GetAttribute(key);
|
||
End;
|
||
|
||
Function getC(chart);
|
||
Begin
|
||
return chart.C ? 'c:' : '';
|
||
End;
|
||
|
||
Function setChartInfo(chartFile, chart);
|
||
Begin
|
||
xml := GetXmlFileObj(chartFile);
|
||
chart.xmlObj := xml;
|
||
c := xml.FirstChildElement('c:chartSpace');
|
||
chart.C := ifObj(c) ? true : false;
|
||
if not ifObj(xml) then return;
|
||
chart.Title := getNodeValue(xml, chart.C ? 'c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:t' : 'chartSpace/chart/title/tx/rich/a:p/a:r/a:t', '');
|
||
chart.plotAreaNode := xml.FirstChildElement(getC(chart) + 'chartSpace').FirstChildElement(getC(chart) + 'chart').FirstChildElement(getC(chart) + 'plotArea');
|
||
End;
|
||
|
||
Function copyFile(obj, target, content);
|
||
Begin
|
||
file_name := ReplaceStr(target, '..', 'xl');
|
||
counts := GetFilesCount(ReplaceStrByReg(file_name, "\\d+.*ml", '')) + 1;
|
||
xml := GetXmlFileObj(file_name);
|
||
new_file_postfix := ReplaceStrByReg(file_name[3:], "\\d+", inttostr(counts));
|
||
zipfile_.Add('xl' + new_file_postfix, xml.Data());
|
||
obj.SetAttribute('Target', '..' + new_file_postfix);
|
||
|
||
if content then
|
||
begin
|
||
content_xml := GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
|
||
class(TSXml).AddOverrideContentType(content_xml, '/xl' + new_file_postfix, class(TSXml).GetTemplate(content));
|
||
end
|
||
return array(counts, 'xl' + new_file_postfix);
|
||
End;
|
||
|
||
sheetsCount_:integer;
|
||
sheetNames_;
|
||
sheetIndexMap_;
|
||
sheetPrefix_:string;
|
||
zipfile_;
|
||
xmlFileObjMap_; //XmlFile对象存储
|
||
sheetObjMap_; //XmlSheet对象存储
|
||
End;
|