TSOffice/funcext/TSOffice/worksheet/xlsxTable.tsf

133 lines
4.6 KiB
Plaintext

Type xlsxTable = Class
///缺省构造函数
Function Create(sheet, excel); overload;
Begin
excel_ := excel;
sheetName_ := sheet;
zipfile_ := excel.Zip();
End;
class Function NewObject(sheet, excel);
Begin
excel_ := excel;
o := excel_.WorkBook().GetSheetObj(sheet);//sheet存在
if not ifObj(o) then return 0;
return new xlsxTable(sheet, excel);
End;
Function AddTable(topLeft, bottomRight, format, includeHeader);
Begin
[rid, table_id, table_name] := addTableXmlFileAndRelation();
table := TOfficeObj('TExcelTable');
table.Xmlns := 'http://schemas.openxmlformats.org/spreadsheetml/2006/main';
table.Mc := 'http://schemas.openxmlformats.org/markup-compatibility/2006';
table.Ignorable := 'xr xr3';
table.Xr := 'http://schemas.microsoft.com/office/spreadsheetml/2014/revision';
table.Xr3 := 'http://schemas.microsoft.com/office/spreadsheetml/2016/revision3';
table.Id := table_id;
table.Name := '表' $ table_id;
table.DisplayName := class(xlsxTable).GenerateValidDisplayName(format.TableName, tableid);
table.Ref := topLeft $ ':' $ bottomRight;
table.HeaderRowCount := format.HeaderRowCount ? '1' : nil;
table.TotalsRowShown := format.TotalsRowShown ? '1' : '0';
table.AutoFilter := table.Ref;
format.TableName := nil;
format.HeaderRowCount := nil;
format.TotalsRowShown := nil;
// <tableColumns />
[err1, col1, row1] := excel_.CellNameToCoordinates(topLeft);
[err2, col2, row2] := excel_.CellNameToCoordinates(bottomRight);
table_str := getTableColumnsXmlString(col1, col2, row1, includeHeader);
table_xml := excel_.WorkBook().GetXmlFileObj(table_name);
table_node := table_xml.FirstChild('table');
marshal := table.Marshal();
class(TSXml).UpdateNode(table_node, marshal['attributes'], marshal['children']);
table_node.InsertEndChild(table_str);
table_node.InsertEndChild(format.Marshal());
//sheetN.xml
sheet_xml := excel_.WorkBook().GetSheetXmlFile(sheetName_);
worksheet_node := sheet_xml.FirstChildElement('worksheet');
table_part := worksheet_node.FirstChildElement('tableParts');
if not ifObj(table_part) then
begin
table_part := worksheet_node.InsertEndChild('element', 'tableParts');
count := 1;
end
else begin
count := strtoint(table_part.GetAttribute('count')) + 1;
end
node := table_part.InsertEndChild('element', 'tablePart');
node.SetAttribute('r:id', 'rId' $ rid);
table_part.SetAttribute('count', count);
End
class Function GenerateValidDisplayName(name, nameId);
Begin
if ifnil(name) then name := '表' $ nameId;
if TOfficeApi().Get('Table-' $ name) then
begin
new_name := '表' $ nameId;
while TOfficeApi().Get('Table-' $ new_name) do new_name := '表' $ ++nameId;
TOfficeApi().Set('Table-' $ new_name, true);
return new_name;
end
TOfficeApi().Set('Table-' $ name, true);
return name;
End
private
Function getTableColumnsXmlString(begCol, endCol, row, includeHeader);
Begin
table_str := '<tableColumns count="' $ (endCol - begCol + 1) $ '">';
id := 1;
col_index := 1;
if not includeHeader then excel_.WorkBook().InsertRow(sheetName_, row);
for i:=begCol to endCol do
begin
[err, cell] := excel_.CoordinatesToCellName(i, row, false);
if includeHeader then
begin
[err, name] := excel_.WorkBook().GetCellValue(sheetName_, cell);
name := "列" $ col_index++;
if err then excel_.WorkBook().SetCellValue(sheetName_, cell, name);
end
else begin
name := "列" $ col_index++;
excel_.WorkBook().SetCellValue(sheetName_, cell, name);
end
table_str += fmt('<tableColumn id="{}" name="{}" />', id++, name);
end
table_str += "</tableColumns>";
return table_str;
End
Function addTableXmlFileAndRelation();
Begin
sheet_rels_file := excel_.WorkBook().GetSheetRelsFile(sheetName_);
[rid, target] := class(TSXml).FindRelationshipRid(sheet_rels_file, '');
rid ++;
table_id := excel_.WorkBook().GetFilesCount('xl/tables/') + 1;
table_name := 'xl/tables/table' + inttostr(table_id) + '.xml';
table_target := '../tables/table' + inttostr(table_id) + '.xml';
excel_.zip().Add(table_name, class(TSXml).XmlHeader() + "<table />");
class(TSXml).AddRelationshipRid(sheet_rels_file, table_target, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/table', 'rId' $ rid);
content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
class(TSXml).AddOverrideContentType(content_xml, '/' + table_name, class(TSXml).GetTemplate('tableContentType'));
return array(rid, table_id, table_name);
End
private
sheetName_:string; //sheet名称
excel_;//TSExcelFile对象
zipfile_;
tableXmlFile_;
End;