TSOffice/funcext/TSOffice/worksheet/xlsxWorkBook.tsf

1322 lines
45 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
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();
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 SetCellValue(sheet, axis, val, opt);
Begin
o := GetSheetObj(sheet);
if ifObj(o) then return o.SetCellValue(axis, val, opt);
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);
Begin
o := GetSheetObj(sheet);
if ifObj(o) then return o.Import(topLeft, bottomRight);
End;
///创建新sheet
///sheet: string工作表名称
Function NewSheet(sheet);overload;
Begin
lname := LowerCase(sheet);
if ifint(sheetIndexMap_[ lname ]) then return 'The sheet already exists.';
rid := getWorkbookRelsRid();
//添加文件xl/worksheets/sheetN.xml
sheetId := vselect maxof(['sheetId']) from sheetNames_ end;
sheetId := integer(sheetId) + 1;
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
zipfile_.Add(fname, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('sheet1'));
//设置 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);
//workbook_rels.Print;
//设置 xl/workbook.xml
workbook := GetXmlFileObj('xl/workbook.xml');
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').InsertEndChild('element','sheet');
node.SetAttribute('name', sheet);
node.SetAttribute('sheetId', sheetId);
node.SetAttribute('r:id', rid);
//workbook.Print();
//设置docProps/app.xml
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
//app.Print();
node := app.FirstChildElement('Properties').FirstChildElement('TitlesOfParts');
if not ifObj(node) then Begin
node := app.FirstChildElement('Properties').InsertEndChild('element','TitlesOfParts');
End;
vector := node.FirstChildElement('vt:vector');
if not ifObj(vector) then Begin
vector := node.InsertEndChild('element', 'vt:vector');
vector.SetAttribute('baseType', 'lpstr');
vector.SetAttribute('size', length(sheetNames_) + 1);
for i:=0 to length(sheetNames_)-1 do Begin
vector.InsertEndChild('element', 'vt:lpstr', sheetNames_[i]['name']);
End;
End
else
vector.SetAttribute('size', length(sheetNames_) + 1);
vector.InsertEndChild('element', 'vt:lpstr', sheet);
//app.Print();
//设置[Content_Types].xml
content_xml := GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
class(TSXml).AddOverrideContentType(content_xml, '/' + fname, class(TSXml).GetTemplate('sheetContentType'));
sheetNames_[sheetsCount_]['name'] := sheet;
sheetNames_[sheetsCount_]['sheetId'] := sheetId;
sheetNames_[sheetsCount_]['rid'] := rid;
sheetNames_[sheetsCount_]['file'] := fname;
sheetIndexMap_[ LowerCase(sheet) ] := sheetsCount_;
sheetsCount_ ++;
SetDefaultSheet(sheet);
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';
//添加文件xl/worksheets/sheetN.xml
sheetId := vselect maxof(['sheetId']) from sheetNames_ end;
sheetId := integer(sheetId) + 1;
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
zipfile_.Add(fname, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('sheet1'));
//设置 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);
//workbook_rels.Print;
//设置 xl/workbook.xml
workbook := GetXmlFileObj('xl/workbook.xml');
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets');
sheet_node := node.FirstChildElement('sheet');
while ifObj(sheet_node) do
begin
if sheet_node.GetAttribute('name') = sourceSheet then
begin
sheet_node := node.InsertAfterChild(sheet_node, 'element', 'sheet');
sheet_node.SetAttribute('name', destSheet);
sheet_node.SetAttribute('sheetId', sheetId);
sheet_node.SetAttribute('r:id', rid);
break;
end
sheet_node := sheet_node.NextElement();
end
//workbook.Print();
//设置docProps/app.xml
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
//app.Print();
node := app.FirstChildElement('Properties').FirstChildElement('TitlesOfParts');
vector := node.FirstChildElement('vt:vector');
vector.SetAttribute('size', length(sheetNames_) + 1);
lpstr := vector.FirstChildElement('vt:lpstr');
while ifObj(lpstr) do
begin
if LowerCase(lpstr.GetText()) = LowerCase(sourceSheet) then
begin
lpstr := vector.InsertAfterChild(lpstr, 'element', 'vt:lpstr');
lpstr.SetValue(destSheet);
break;
end
lpstr := lpstr.NextElement();
end
//设置[Content_Types].xml
content_xml := GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
class(TSXml).AddOverrideContentType(content_xml, '/' + fname, class(TSXml).GetTemplate('sheetContentType'));
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 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(destSheet) ];
if ifint(ind) then return destSheet $ ' already exists.';
ind := sheetIndexMap_[ LowerCase(sourceSheet) ];
if not ifint(ind) then return sourceSheet $ ' does not exists.';
//copy sheet
sheetId := vselect maxof(['sheetId']) from sheetNames_ end;
sheetId := integer(sheetId) + 1;
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
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
rels_name := 'xl/worksheets/_rels/' + 'sheet' + inttostr(sheetsCount_ + 1) + '.xml.rels';
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
//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
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', sheetId);
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
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 := workbook.FirstChildElement('workbook').FirstChildElement('sheets').FirstChildElement('sheet');
hidden := visible = 1 ? 0 : 1;
default_sheet_name := GetDefaultSheet();
if default_sheet_name = sheet then
begin
ind := sheetIndexMap_[LowerCase(default_sheet_name)];
if ind = 0 then default_name := sheetNames_[ind + 1]['name'];
else default_name := sheetNames_[ind - 1]['name'];
SetDefaultSheet(default_name);
end
while ifObj(node) do
Begin
name := node.GetAttribute('name');
if name = sheet then
Begin
if hidden then node.SetAttribute('state', 'hidden');
else node.DeleteAttribute('state');
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;
workbook := GetXmlFileObj('xl/workbook.xml');
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').FirstChildElement('sheet');
while ifObj(node) do
Begin
name := 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);
axis := CoordinatesToCellName(1, row, False)[1];
if not obj.CellIsExists(axis) then
begin
obj.SetCellValue(axis, '', array('t': 's'));
end
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, startCol, endCol, width);
Begin
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 := work_node.FirstChildElement('cols');
if not ifObj(col_node) 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 := trystrtofloat(node.GetAttribute('width'), r) ? r : '';
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 := 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 >= min and col <= 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 -1;
work_node := sheet_xml_file.FirstChildElement('worksheet');
node := work_node.FirstChildElement('sheetFormatPr');
flag := trystrtofloat(node.GetAttribute('defaultColWidth'), width);
return flag ? width : -1;
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'];
xml_file := GetXmlFileObj(sheetNames_[i]['file']);
sheet_node := xml_file.FirstChildElement('worksheet').FirstChildElement('sheetViews').FirstChildElement('sheetView');
if name = sheet then
Begin
sheet_node.SetAttribute('tabselected', 1);
workbook := GetXmlFileObj('xl/workbook.xml');
book_view_node := workbook.FirstChildElement('workbook').FirstChildElement('bookViews').FirstChildElement('workbookView');
book_view_node.SetAttribute('activeTab', ind);
End
else sheet_node.SetAttribute('tabselected', 0);
end
End
Function GetDefaultSheet();
Begin
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').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');
fonts_node.DeleteChild(first_node);
fonts_node.InsertFirstChild(font.Marshal());
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');
sheet_node := workbook_node.FirstChildElement('sheets');
if ifObj(calc_node) then workbook_node.DeleteChild(calc_node);
calcPr.calcId := "191029";
workbook_node.InsertAfterChild(sheet_node, calcPr.Marshal());
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;