diff --git a/ExcelFile使用帮助.xlsx b/ExcelFile使用帮助.xlsx index 2adfd74..177cc91 100644 Binary files a/ExcelFile使用帮助.xlsx and b/ExcelFile使用帮助.xlsx differ diff --git a/funcext/TSOffice/TOfficeObj.tsf b/funcext/TSOffice/TOfficeObj.tsf index 619c9bb..c41dbb5 100644 --- a/funcext/TSOffice/TOfficeObj.tsf +++ b/funcext/TSOffice/TOfficeObj.tsf @@ -1,4 +1,4 @@ -// Version 1.1.8 +// Version 1.1.9 Function TOfficeObj(n); Begin diff --git a/funcext/TSOffice/TSDocxFile.tsf b/funcext/TSOffice/TSDocxFile.tsf index 265de7c..3e40e8c 100644 --- a/funcext/TSOffice/TSDocxFile.tsf +++ b/funcext/TSOffice/TSDocxFile.tsf @@ -1,4 +1,4 @@ -// Version 1.1.8 +// Version 1.1.9 Type TSDocxFile = Class ///Version: V1.0 2022-09-20 diff --git a/funcext/TSOffice/TSExcelFile.tsf b/funcext/TSOffice/TSExcelFile.tsf index 1aa8f83..18b92b5 100644 --- a/funcext/TSOffice/TSExcelFile.tsf +++ b/funcext/TSOffice/TSExcelFile.tsf @@ -1,4 +1,4 @@ -// Version 1.1.8 +// Version 1.1.9 Type TSExcelFile = Class ///Version: V1.0 2022-08-08 @@ -141,7 +141,7 @@ Type TSExcelFile = Class return workbook_.NewSheet(class(TSXml).CurCodePageToUtf8(sheet)); End; - ///在指定sheet之前插入新sheet + ///在指定sheet之后插入新sheet ///sourceSheet: string,指定工作表名称 ///destSheet: string,目的工作表名称 Function NewSheet(sourceSheet, destSheet);overload; @@ -149,6 +149,14 @@ Type TSExcelFile = Class return workbook_.NewSheet(class(TSXml).CurCodePageToUtf8(sourceSheet), class(TSXml).CurCodePageToUtf8(destSheet)); End; + ///在指定sheet之前插入新sheet + ///sourceSheet: string,指定工作表名称 + ///destSheet: string,目的工作表名称 + Function InsertSheet(sourceSheet, destSheet); + Begin + return workbook_.InsertSheet(class(TSXml).CurCodePageToUtf8(sourceSheet), class(TSXml).CurCodePageToUtf8(destSheet)); + End; + ///删除sheet ///sheet: string,工作表名称 Function DeleteSheet(sheet); diff --git a/funcext/TSOffice/worksheet/xlsxWorkBook.tsf b/funcext/TSOffice/worksheet/xlsxWorkBook.tsf index 1ae43fa..333145c 100644 --- a/funcext/TSOffice/worksheet/xlsxWorkBook.tsf +++ b/funcext/TSOffice/worksheet/xlsxWorkBook.tsf @@ -281,6 +281,92 @@ Type xlsxWorkBook = Class 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'; + + //添加文件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'); + prev_node := nil; + while ifObj(sheet_node) do + begin + if LowerCase(sheet_node.GetAttribute('name')) = LowerCase(sourceSheet) then + begin + if ifnil(prev_node) then sheet_node := node.InsertFirstChild('element', 'sheet'); + else sheet_node := node.InsertAfterChild(prev_node, 'element', 'sheet'); + sheet_node.SetAttribute('name', destSheet); + sheet_node.SetAttribute('sheetId', sheetId); + sheet_node.SetAttribute('r:id', rid); + break; + end + prev_node := sheet_node; + 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'); + pstr := nil; + while ifObj(lpstr) do + begin + if LowerCase(lpstr.GetText()) = LowerCase(sourceSheet) then + begin + if ifnil(pstr) then vector.InsertFirstChild('element', 'vt:lpstr'); + else lpstr := vector.InsertAfterChild(pstr, 'element', 'vt:lpstr'); + lpstr.SetValue(destSheet); + break; + end + pstr := lpstr; + 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+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.'; diff --git a/更新日志.md b/更新日志.md index 828b2ae..f97d1f3 100644 --- a/更新日志.md +++ b/更新日志.md @@ -2,6 +2,12 @@ ## 2023-2-22 +### V1.1.9 + +#### excel + +1. 新增`InsertSheet` + ### V1.1.8 #### excel