diff --git a/Windows-X64/office_plugin.dll b/Windows-X64/office_plugin.dll index 49f994f..8fb3c48 100644 Binary files a/Windows-X64/office_plugin.dll and b/Windows-X64/office_plugin.dll differ diff --git a/funcext/TSOffice/TOfficeObj.tsf b/funcext/TSOffice/TOfficeObj.tsf index 8f4fd15..80e7744 100644 --- a/funcext/TSOffice/TOfficeObj.tsf +++ b/funcext/TSOffice/TOfficeObj.tsf @@ -1,4 +1,4 @@ -// Version 1.2.7 +// Version 1.2.8 Function TOfficeObj(n); Begin diff --git a/funcext/TSOffice/TSDocxFile.tsf b/funcext/TSOffice/TSDocxFile.tsf index eec34b3..06a1122 100644 --- a/funcext/TSOffice/TSDocxFile.tsf +++ b/funcext/TSOffice/TSDocxFile.tsf @@ -1,4 +1,4 @@ -// Version 1.2.7 +// Version 1.2.8 Type TSDocxFile = Class ///Version: V1.0 2022-09-20 diff --git a/funcext/TSOffice/TSExcelFile.tsf b/funcext/TSOffice/TSExcelFile.tsf index 0c6fa1f..7552431 100644 --- a/funcext/TSOffice/TSExcelFile.tsf +++ b/funcext/TSOffice/TSExcelFile.tsf @@ -1,4 +1,4 @@ -// Version 1.2.7 +// Version 1.2.8 Type TSExcelFile = Class ///Version: V1.0 2022-08-08 diff --git a/funcext/TSOffice/TSUtils/TSXml.tsf b/funcext/TSOffice/TSUtils/TSXml.tsf index 280d196..8218d22 100644 --- a/funcext/TSOffice/TSUtils/TSXml.tsf +++ b/funcext/TSOffice/TSUtils/TSXml.tsf @@ -261,7 +261,7 @@ Type TSXml = Class class Function GetWorkSheetPrevNode(workNode, nodeName); Begin - order_arr := array('dimension', 'sheetViews', 'sheetFormatPr', 'cols', 'sheetData', 'sheetProtection', 'mergeCells', 'phoneticPr', + order_arr := array('dimension', 'sheetPr', 'sheetViews', 'sheetFormatPr', 'cols', 'sheetData', 'sheetProtection', 'mergeCells', 'phoneticPr', 'hyperlinks', 'pageMargins', 'headerFooter', 'pageSetup', 'rowBreaks', 'colBreaks', 'drawing', 'legacyDrawing', 'picture'); for i:=0 to length(order_arr)-1 do begin @@ -271,6 +271,30 @@ Type TSXml = Class else prev := ifObj(current) ? current : prev; end End + + class Function GetWorkBookPrevNode(workNode, nodeName); + Begin + order_arr := array('fileVersion', 'workbookPr', 'bookViews'); + for i:=0 to length(order_arr)-1 do + begin + if order_arr[i] = nodeName then return prev; + current := workNode.FirstChild(order_arr[i]); + if i = 0 then prev := current; + else prev := ifObj(current) ? current : prev; + end + End + + class Function GetWorkSheetNode(workNode, nodeName); + Begin + node := workNode.FirstChildElement(nodeName); + if not ifObj(node) then + begin + prev_node := class(TSXml).GetWorkSheetPrevNode(workNode, nodeName); + if ifObj(prev_node) then node := workNode.InsertAfterChild(prev_node, 'element', nodeName); + else node := workNode.InsertFirstChild('element', nodeName); + end + return node; + End class Function GetDatetimeStr(v); Begin diff --git a/funcext/TSOffice/worksheet/xlsxHeaderFooter.tsf b/funcext/TSOffice/worksheet/xlsxHeaderFooter.tsf index e693e16..68513e3 100644 --- a/funcext/TSOffice/worksheet/xlsxHeaderFooter.tsf +++ b/funcext/TSOffice/worksheet/xlsxHeaderFooter.tsf @@ -21,12 +21,14 @@ Type xlsxHeaderFooter = Class node := xmlFile_.FirstChildElement('worksheet'); header_node := node.FirstChildElement('headerFooter'); if ifObj(header_node) then - node.DeleteChild(header_node); - page_node := node.FirstChildElement('pageMargins'); - if ifObj(page_node) then - node.InsertAfterChild(page_node, headerFooter.Marshal()); - else - node.InsertEndChild(headerFooter.Marshal()); + begin + marshal := headerFooter.Marshal(); + class(TSXml).UpdateNode(header_node, marshal['attributes'], marshal['children']); + end + else begin + prev_node := class(TSXml).GetWorkSheetPrevNode(node, 'headerFooter'); + node.InsertAfterChild(prev_node, headerFooter.Marshal()); + end End private diff --git a/funcext/TSOffice/worksheet/xlsxWorkBook.tsf b/funcext/TSOffice/worksheet/xlsxWorkBook.tsf index 03846af..a1ee763 100644 --- a/funcext/TSOffice/worksheet/xlsxWorkBook.tsf +++ b/funcext/TSOffice/worksheet/xlsxWorkBook.tsf @@ -238,7 +238,7 @@ Type xlsxWorkBook = Class begin if sheet_node.GetAttribute('name') = sourceSheet then begin - sheet_node := node.InsertAfterChild(sheet_node, 'element', 'sheet'); + sheet_node := node.InsertAfterChild(sheet_node, 'element', 'sheet'); sheet_node.SetAttribute('name', destSheet); sheet_node.SetAttribute('sheetId', sheetId); sheet_node.SetAttribute('r:id', rid); @@ -265,7 +265,7 @@ Type xlsxWorkBook = Class 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')); @@ -320,7 +320,7 @@ Type xlsxWorkBook = Class 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'); + 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); @@ -351,7 +351,7 @@ Type xlsxWorkBook = Class 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')); @@ -846,11 +846,6 @@ Type xlsxWorkBook = Class 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 @@ -874,17 +869,42 @@ Type xlsxWorkBook = Class 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'); + 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 + 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 @@ -899,7 +919,7 @@ Type xlsxWorkBook = Class node_new.SetAttribute('min', endCol + 1); End break; - End + end node := node.NextElement(); End arr := array('type': 'element', 'name': 'col', 'attributes': ('min': startCol, 'max': endCol, 'width': width, @@ -1056,14 +1076,11 @@ Type xlsxWorkBook = Class for i:=0 to length(sheetnames_)-1 do begin name := sheetNames_[i]['name']; - xml_file := GetXmlFileObj(sheetNames_[i]['file']); - work_node := xml_file.FirstChildElement('worksheet'); - sheet_node := work_node.FirstChildElement('sheetViews'); - if not ifObj(sheet_node) then - begin - prev_node := class(TSXml).GetWorkSheetPrevNode(work_node, 'sheetViews'); - sheet_node := work_node.InsertAfterChild(prev_node, 'element', 'sheetViews'); - end + 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 @@ -1074,12 +1091,24 @@ Type xlsxWorkBook = Class Begin 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); + workbook_node := workbook.FirstChildElement('workbook'); + book_view_node := workbook_node.FirstChildElement('bookViews'); + if not ifObj(book_view_node) then + begin + prev_node := class(TSXml).GetWorkBookPrevNode(workbook_node, 'bookViews'); + if not ifObj(prev_node) then book_view_node := workbook_node.InsertFirstChild('element', 'bookViews'); + else book_view_node := workbook_node.InsertAfterChild(prev_node, 'element', 'bookViews'); + end; + view_node := book_view_node.FirstChildElement('workbookView'); + if not ifObj(view_node) then + begin + view_node := book_view_node.InsertFirstChild('element', 'workbookView'); + end + view_node.SetAttribute('activeTab', ind); End else begin - node := xml_file.FirstChildElement('worksheet').FirstChildElement('sheetViews').FirstChildElement('sheetView'); + node := root_node.FirstChildElement('sheetViews').FirstChildElement('sheetView'); node.SetAttribute('tabselected', 0); end end @@ -1090,8 +1119,11 @@ Type xlsxWorkBook = Class 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'); + 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 diff --git a/更新日志.md b/更新日志.md index 042768e..37c5880 100644 --- a/更新日志.md +++ b/更新日志.md @@ -1,5 +1,13 @@ # 更新日志 +## 2023-3-31 + +### V1.2.8 + +#### excel + +1. 修复由.net客户端导出的excel兼容性问题,`SetColWidth`、`Set/GetDefaultSheet`、`SetSheetHeaderFooter` + ## 2023-3-23 ### V1.2.7