diff --git a/Demo/excel_demo.tsl b/Demo/excel_demo.tsl index 486a0e9..d270b1f 100644 --- a/Demo/excel_demo.tsl +++ b/Demo/excel_demo.tsl @@ -1,4 +1,4 @@ -class(xlsxXml).CodePage('中文'); +TOfficeApi().CodePage('中文'); testCount := 0; sheetName := "你好"; @@ -207,10 +207,6 @@ End; [err, col, row] := excel.SplitCellName("AK47"); if not err then println("[success] {} = col : {}, row = {}", "SplitCellName", col, row); -// JoinCellName -[err, errmsg] := excel.JoinCellName("AK", 47); -PrintInfo("JoinCellName", err, errmsg); - // ColumnNameToNumber [err, errmsg] := excel.ColumnNameToNumber("AK"); PrintInfo("ColumnNameToNumber", err, errmsg); @@ -224,12 +220,12 @@ PrintInfo("ColumnNumberToName", err, errmsg); if not err then println("[success] {} = col : {}, row = {}", "CellNameToCoordinates", col, row); // RGBToHSL -[err, h, s, l] := excel.RGBToHSL(255, 15, 33); -if not err then println("[success] {} = {}, {}, {}", "RGBToHSL", h, s, l); +[h, s, l] := excel.RGBToHSL(255, 15, 33); +println("[success] {} = {}, {}, {}", "RGBToHSL", h, s, l); // HSLToRGB -[err, r, g, b] := excel.HSLToRGB(h, s, l); -if not err then println("[success] {} = {}, {}, {}", "HSLToRGB", h, s, l); +[r, g, b] := excel.HSLToRGB(h, s, l); +println("[success] {} = {}, {}, {}", "HSLToRGB", r, g, b); // NewStyle style := TOfficeObj('TStyle'); @@ -380,11 +376,11 @@ println("[success] GetDefaultSheet = {}", sheet); // SetCellHyperLink link := TOfficeObj('THyperLink'); -link.LinkType := "Location"; +link.LinkType := "location"; link.LinkUrl := sheetName $ "!A1"; excel.SetCellHyperLink(sheetName2, 'A1', link); link := TOfficeObj('THyperLink'); -link.LinkType := "External"; +link.LinkType := "external"; link.LinkUrl := "https://www.baidu.com"; link.Tooltip := "超链接悬浮提示"; excel.SetCellValue(sheetName2, 'A2', '超链接'); @@ -393,7 +389,7 @@ println("[success] SetCellHyperLink"); // GetCellHyperLink hyperlink := excel.GetCellHyperLink(sheetName2, 'A2'); -println("[success] GetCellHyperLink LinkType = {}, LinkUrl = {}, Tooltip = {}", hyperlink.Value('LinkType'), hyperlink.Value('LinkUrl'), hyperlink.Value('Tooltip')); +println("[success] GetCellHyperLink LinkType = {}, LinkUrl = {}, Tooltip = {}", hyperlink.LinkType, hyperlink.LinkUrl, hyperlink.Tooltip); // SetSheetBackground ret := readfile(rwBinary(), "", "C:\\Users\\csh05\\Pictures\\Saved Pictures\\1.jpg", 0, 1024000, data); @@ -454,11 +450,10 @@ core.Title := "标题"; core.Subject := "主题"; core.Creator := "作者"; excel.SetCoreProps(core); -println("[success] SetCoreProps"); // GetCoreProps core := excel.GetCoreProps(); -println("[success] GetCoreProps Title = {}, subject = {}, Creator = {}", core.Value("Title"), core.Value("Subject"), core.Value("Creator")); +println("[success] GetCoreProps Title = {}, subject = {}, Creator = {}", core.Title, core.Subject, core.Creator); // SetAppProps appProps := TOfficeObj('TAppProperty'); @@ -476,7 +471,7 @@ println("[success] SetAppProps"); // GetAppProps app_props := excel.GetAppProps(); -println("[success] GetAppProps Manager = {}, Company = {}, Application = {}", app_props.Value('Manager'), app_props.Value('Company'), app_props.Value('Application')); +println("[success] GetAppProps Manager = {}, Company = {}, Application = {}", app_props.Manager, app_props.Company, app_props.Application); [err, errmsg] := excel.saveas("", "d:\\temp\\test.xlsx"); println("saveas : {}", err); diff --git a/Demo/wordHelp.tsl b/Demo/wordHelp.tsl index 3d01418..24921a7 100644 --- a/Demo/wordHelp.tsl +++ b/Demo/wordHelp.tsl @@ -56,6 +56,9 @@ _13_TNumbering(docx); ///TDocxChart _14_TDocxChart(docx); +///TOfficeApi +_15_TOfficeApi(docx); + ///附注 _Annotation(docx); @@ -790,6 +793,20 @@ Begin println(' >>OK\n'); End; +///TOfficeApi +Function _15_TOfficeApi(docx); +Begin + paragraph := sysparams['Test']; + _PrintMsg('TOfficeApi接口'); + _AddTitle(docx, 'TOfficeApi', 1); + + _AddTitle(docx, 'TOfficeApi接口', 2); + conf := _LoadClassInfo(docx.GetPath() + '\\funcext\\TSOffice\\TSUtils\\TOffice.tsf', 'TOffice'); + _AddFunctionHelpInfo(docx, '' $ paragraph $ '.1.', conf, 3); + + println(' >>OK\n'); +End; + Function _AddTitle(docx, subject, level); Begin leftIndent := array((0,0), (425,425), (453,850), (708,1508)); diff --git a/DocxFile使用帮助.docx b/DocxFile使用帮助.docx index 0fa8cce..9916bc0 100644 Binary files a/DocxFile使用帮助.docx and b/DocxFile使用帮助.docx differ diff --git a/ExcelFile使用帮助.xlsx b/ExcelFile使用帮助.xlsx index 6423e22..ea858fc 100644 Binary files a/ExcelFile使用帮助.xlsx and b/ExcelFile使用帮助.xlsx differ diff --git a/Linux-aarch64/liboffice_plugin.so b/Linux-aarch64/liboffice_plugin.so index 6c4ca59..7c1e097 100644 Binary files a/Linux-aarch64/liboffice_plugin.so and b/Linux-aarch64/liboffice_plugin.so differ diff --git a/Linux-x86_64/liboffice_plugin.so b/Linux-x86_64/liboffice_plugin.so index 1c98a02..dec4ee4 100644 Binary files a/Linux-x86_64/liboffice_plugin.so and b/Linux-x86_64/liboffice_plugin.so differ diff --git a/Windows-X64/office_plugin.dll b/Windows-X64/office_plugin.dll index e69f938..1ef1804 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 f9deab7..3abc8ac 100644 --- a/funcext/TSOffice/TOfficeObj.tsf +++ b/funcext/TSOffice/TOfficeObj.tsf @@ -1,4 +1,4 @@ -// Version 1.0.5 +// Version 1.0.6 Function TOfficeObj(n); Begin @@ -361,7 +361,7 @@ type TFont=class(NodeInfo) Property Name write writeName; Function writeName(n); Begin - nName := class(xlsxXml).CurCodePageToUtf8(n); + nName := class(TSXml).CurCodePageToUtf8(n); FontName := nName; End; @@ -415,14 +415,14 @@ type TComment=class(NodeInfo) Function readCommentText(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('CommentText')); + return class(TSXml).Utf8ToCurCodePage(Value('CommentText')); else return CommentText; End; Function writeCommentText(str); Begin - CommentText := class(xlsxXml).CurCodePageToUtf8(str); + CommentText := class(TSXml).CurCodePageToUtf8(str); End; Function GetAttrs(); override; @@ -1120,9 +1120,15 @@ type TChartImpl=class(NodeInfo) ,("field":"ShowBlanksAs","name":"ShowBlanksAs","obj":ShowBlanksAs,"attrEx":"","nodeType":"","attrName":"", "desc":"此元素指定如何在图表上绘制空白单元格。", "class":"") ,("field":"plotVisOnly","name":"plotVisOnly","obj":plotVisOnly,"attrEx":"","nodeType":"","attrName":"", "desc":"此元素指定如何在图表上绘制空白单元格。", "class":"") ,("field":"ChartNode","name":"ChartNode","obj":ChartNode,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") + ,("field":"plotAreaNode","name":"plotAreaNode","obj":plotAreaNode,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") ,("field":"C","name":"C","obj":C,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") ,("field":"xmlObj","name":"xmlObj","obj":xmlObj,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") ,("field":"Rid","name":"Rid","obj":Rid,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") + ,("field":"pNode","name":"pNode","obj":pNode,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") + ,("field":"DisableExcel","name":"DisableExcel","obj":DisableExcel,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") + ,("field":"Excel","name":"Excel","obj":Excel,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") + ,("field":"chartFileName","name":"chartFileName","obj":chartFileName,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") + ,("field":"excelFileName","name":"excelFileName","obj":excelFileName,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") ) union ExtNodes; End; @@ -1156,9 +1162,15 @@ type TChartImpl=class(NodeInfo) ShowBlanksAs; plotVisOnly; ChartNode; + plotAreaNode; C; xmlObj; Rid; + pNode; + DisableExcel; + Excel; + chartFileName; + excelFileName; End; /////////////////////////////////////////////////////////////// @@ -3680,38 +3692,52 @@ type THyperLink=class(NodeInfo) //TODO... End; + Property LinkUrl read readLinkLinkUrl write writeLinkLinkUrl; + Function readLinkLinkUrl(); + Begin + if ifObj(Root()) then + return class(TSXml).Utf8ToCurCodePage(Value('LinkLinkUrl')); + else + return LinkLinkUrl; + End; + + Function writeLinkLinkUrl(str); + Begin + LinkLinkUrl := class(TSXml).CurCodePageToUtf8(str); + End; + Property Display read readLinkDisplay write writeLinkDisplay; Function readLinkDisplay(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('LinkDisplay')); + return class(TSXml).Utf8ToCurCodePage(Value('LinkDisplay')); else return LinkDisplay; End; Function writeLinkDisplay(str); Begin - LinkDisplay := class(xlsxXml).CurCodePageToUtf8(str); + LinkDisplay := class(TSXml).CurCodePageToUtf8(str); End; Property Tooltip read readLinkTooltip write writeLinkTooltip; Function readLinkTooltip(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('LinkTooltip')); + return class(TSXml).Utf8ToCurCodePage(Value('LinkTooltip')); else return LinkTooltip; End; Function writeLinkTooltip(str); Begin - LinkTooltip := class(xlsxXml).CurCodePageToUtf8(str); + LinkTooltip := class(TSXml).CurCodePageToUtf8(str); End; Function GetAttrs(); override; Begin HandleAttrs(); - return array(("LinkType", "linkType", LinkType, ""),("LinkUrl", "linkUrl", LinkUrl, ""),("Axis", "ref", Axis, ""),("LinkDisplay", "display", LinkDisplay, ""),("LinkTooltip", "tooltip", LinkTooltip, ""),("RId", "r:id", RId, ""),("Location", "location", Location, "")) union ExtAttr; + return array(("LinkType", "linkType", LinkType, ""),("LinkLinkUrl", "linkUrl", LinkLinkUrl, ""),("Axis", "ref", Axis, ""),("LinkDisplay", "display", LinkDisplay, ""),("LinkTooltip", "tooltip", LinkTooltip, ""),("RId", "r:id", RId, ""),("Location", "location", Location, "")) union ExtAttr; End; Function GetChildren(); override; @@ -3722,7 +3748,7 @@ type THyperLink=class(NodeInfo) //Attributes LinkType; - LinkUrl; + LinkLinkUrl; Axis; LinkDisplay; LinkTooltip; @@ -3846,14 +3872,14 @@ type TAppProperty=class(NodeInfo) Function readAppApplication(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('AppApplication')); + return class(TSXml).Utf8ToCurCodePage(Value('AppApplication')); else return AppApplication; End; Function writeAppApplication(str); Begin - AppApplication := class(xlsxXml).CurCodePageToUtf8(str); + AppApplication := class(TSXml).CurCodePageToUtf8(str); End; Property DocSecurity read readAppDocSecurity write writeAppDocSecurity; @@ -3888,14 +3914,14 @@ type TAppProperty=class(NodeInfo) Function readAppManager(); Begin if ifObj(Root()) then - return Value('AppManager'); + return class(TSXml).Utf8ToCurCodePage(Value('AppManager')); else return AppManager; End; Function writeAppManager(str); Begin - AppManager := str; + AppManager := class(TSXml).CurCodePageToUtf8(str); End; Property Company read readAppCompany write writeAppCompany; @@ -3944,14 +3970,14 @@ type TAppProperty=class(NodeInfo) Function readAppHyperlinkBase(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('AppHyperlinkBase')); + return class(TSXml).Utf8ToCurCodePage(Value('AppHyperlinkBase')); else return AppHyperlinkBase; End; Function writeAppHyperlinkBase(str); Begin - AppHyperlinkBase := class(xlsxXml).CurCodePageToUtf8(str); + AppHyperlinkBase := class(TSXml).CurCodePageToUtf8(str); End; Property HyperlinksChanged read readAppHyperlinksChanged write writeAppHyperlinksChanged; @@ -3972,14 +3998,14 @@ type TAppProperty=class(NodeInfo) Function readAppVersion(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('AppVersion')); + return class(TSXml).Utf8ToCurCodePage(Value('AppVersion')); else return AppVersion; End; Function writeAppVersion(str); Begin - AppVersion := class(xlsxXml).CurCodePageToUtf8(str); + AppVersion := class(TSXml).CurCodePageToUtf8(str); End; Function GetAttrs(); override; @@ -4043,126 +4069,126 @@ type TCoreProperty=class(NodeInfo) Function readCoreTitle(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('CoreTitle')); + return class(TSXml).Utf8ToCurCodePage(Value('CoreTitle')); else return CoreTitle; End; Function writeCoreTitle(str); Begin - CoreTitle := class(xlsxXml).CurCodePageToUtf8(str); + CoreTitle := class(TSXml).CurCodePageToUtf8(str); End; Property Subject read readCoreSubject write writeCoreSubject; Function readCoreSubject(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('CoreSubject')); + return class(TSXml).Utf8ToCurCodePage(Value('CoreSubject')); else return CoreSubject; End; Function writeCoreSubject(str); Begin - CoreSubject := class(xlsxXml).CurCodePageToUtf8(str); + CoreSubject := class(TSXml).CurCodePageToUtf8(str); End; Property Creator read readCoreCreator write writeCoreCreator; Function readCoreCreator(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('CoreCreator')); + return class(TSXml).Utf8ToCurCodePage(Value('CoreCreator')); else return CoreCreator; End; Function writeCoreCreator(str); Begin - CoreCreator := class(xlsxXml).CurCodePageToUtf8(str); + CoreCreator := class(TSXml).CurCodePageToUtf8(str); End; Property Keywords read readCoreKeywords write writeCoreKeywords; Function readCoreKeywords(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('CoreKeywords')); + return class(TSXml).Utf8ToCurCodePage(Value('CoreKeywords')); else return CoreKeywords; End; Function writeCoreKeywords(str); Begin - CoreKeywords := class(xlsxXml).CurCodePageToUtf8(str); + CoreKeywords := class(TSXml).CurCodePageToUtf8(str); End; Property Description read readCoreDescription write writeCoreDescription; Function readCoreDescription(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('CoreDescription')); + return class(TSXml).Utf8ToCurCodePage(Value('CoreDescription')); else return CoreDescription; End; Function writeCoreDescription(str); Begin - CoreDescription := class(xlsxXml).CurCodePageToUtf8(str); + CoreDescription := class(TSXml).CurCodePageToUtf8(str); End; Property LastModifiedBy read readCoreLastModifiedBy write writeCoreLastModifiedBy; Function readCoreLastModifiedBy(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('CoreLastModifiedBy')); + return class(TSXml).Utf8ToCurCodePage(Value('CoreLastModifiedBy')); else return CoreLastModifiedBy; End; Function writeCoreLastModifiedBy(str); Begin - CoreLastModifiedBy := class(xlsxXml).CurCodePageToUtf8(str); + CoreLastModifiedBy := class(TSXml).CurCodePageToUtf8(str); End; Property LastPrinted read readCoreLastPrinted write writeCoreLastPrinted; Function readCoreLastPrinted(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('CoreLastPrinted')); + return class(TSXml).Utf8ToCurCodePage(Value('CoreLastPrinted')); else return CoreLastPrinted; End; Function writeCoreLastPrinted(str); Begin - CoreLastPrinted := class(xlsxXml).CurCodePageToUtf8(str); + CoreLastPrinted := class(TSXml).CurCodePageToUtf8(str); End; Property Category read readCoreCategory write writeCoreCategory; Function readCoreCategory(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('CoreCategory')); + return class(TSXml).Utf8ToCurCodePage(Value('CoreCategory')); else return CoreCategory; End; Function writeCoreCategory(str); Begin - CoreCategory := class(xlsxXml).CurCodePageToUtf8(str); + CoreCategory := class(TSXml).CurCodePageToUtf8(str); End; Property ContentStatus read readCoreContentStatus write writeCoreContentStatus; Function readCoreContentStatus(); Begin if ifObj(Root()) then - return class(xlsxXml).Utf8ToCurCodePage(Value('CoreContentStatus')); + return class(TSXml).Utf8ToCurCodePage(Value('CoreContentStatus')); else return CoreContentStatus; End; Function writeCoreContentStatus(str); Begin - CoreContentStatus := class(xlsxXml).CurCodePageToUtf8(str); + CoreContentStatus := class(TSXml).CurCodePageToUtf8(str); End; Function GetAttrs(); override; @@ -4339,8 +4365,8 @@ type TwrPr=class(NodeInfo) Function writeName(n); Begin nName := n; - if not class(xlsxXml).IsUtf8() then - nName := class(xlsxXml).CurCodePageToUtf8(n); + if not class(TSXml).IsUtf8() then + nName := class(TSXml).CurCodePageToUtf8(n); rFont.cs := nName; rFont.eastAsia := nName; rFont.hAnsi := nName; @@ -7797,7 +7823,7 @@ type TTableStyle=class(NodeInfo) Property TableName read Name write writeName; Function writeName(n); Begin - Name := class(xlsxXml).CurCodePageToUtf8(n); + Name := class(TSXml).CurCodePageToUtf8(n); End; //Attributes @@ -7899,8 +7925,8 @@ Type TRange = Class arr := rPr_.Marshal(); if length(arr['attributes']) or length(arr['children']) then Begin for i:=0 to length(RunArr_)-1 do Begin - rPr := class(xlsxXml).GetNode(RunArr_[i]['rNode'], 'w:rPr', 'first'); - class(xlsxXml).UpdateNode(rPr, arr['attributes'], arr['children']); + rPr := class(TSXml).GetNode(RunArr_[i]['rNode'], 'w:rPr', 'first'); + class(TSXml).UpdateNode(rPr, arr['attributes'], arr['children']); End; End; End; @@ -7985,10 +8011,10 @@ Type DocObject = Class obj.name_ := obj.NodeName; tmpAuthor := obj.Author; tmpTxt := obj.InsText; - if not class(xlsxXml).IsUtf8() then Begin + if not class(TSXml).IsUtf8() then Begin if ifstring(obj.Author) then - obj.Author := class(xlsxXml).CurCodePageToUtf8(obj.Author); - obj.InsText := class(xlsxXml).CurCodePageToUtf8(obj.InsText); + obj.Author := class(TSXml).CurCodePageToUtf8(obj.Author); + obj.InsText := class(TSXml).CurCodePageToUtf8(obj.InsText); End; r := _split_range(obj.sPos, 0); if length(r) then Begin @@ -8024,8 +8050,8 @@ Type DocObject = Class Function DelRevision(obj); Begin tmpAuthor := obj.Author; - if ifstring(obj.Author) and not class(xlsxXml).IsUtf8() then - obj.Author := class(xlsxXml).CurCodePageToUtf8(obj.Author); + if ifstring(obj.Author) and not class(TSXml).IsUtf8() then + obj.Author := class(TSXml).CurCodePageToUtf8(obj.Author); r := _split_range(obj.sPos, obj.SelectLength); for i:=0 to length(r)-1 do Begin rNode := r[i]['rNode']; @@ -8067,8 +8093,8 @@ Type DocObject = Class return _text(r); End; - ///所有文字信息(包括位置信息) - ///返回:table(包括w:r节点) + //所有文字信息(包括位置信息) + //返回:table(包括w:r节点) Function TextArray();virtual; Begin r := array(); @@ -8095,7 +8121,7 @@ Type DocObject = Class else Begin rNode := node_.InsertEndChild('element','w:r'); p := new TParagraph(node_); - p.CopyFormat(false, rNode); + p.CopyRunFormat(false, rNode); End; run := new TRun(rNode); run.SetText(txt); @@ -8146,7 +8172,7 @@ Type DocObject = Class for i:=0 to length(r)-1 do Begin run := new TRun(r[i]['rNode']); txt := run.Text(); - if class(xlsxXml).IsUtf8() then + if class(TSXml).IsUtf8() then txt := UTF8ToAnsi(txt); txtLen := lengthW(txt); if rangeLength >= 0 and sPos + rangeLength <= rSize then Begin @@ -8299,7 +8325,7 @@ Type TRevision = Class(DocObject, TRevisionImpl) name_ := node_.GetName(); paragraph_ := new TParagraph(node_); End; - Date := class(xlsxXml).GetDatetimeStr(now()); + Date := class(TSXml).GetDatetimeStr(now()); Class(TRevisionImpl).Create(nil, name_); End; @@ -8371,7 +8397,7 @@ Type TDocComment = Class(TDocCommentImpl) Begin node_ := node; name_ := 'w:comment'; - Date := class(xlsxXml).GetDatetimeStr(now()); + Date := class(TSXml).GetDatetimeStr(now()); Class(TDocCommentImpl).Create(nil, name_); End; @@ -8470,6 +8496,11 @@ Type TParagraph = Class(DocObject, TParagraphImpl) End; Function Create(node);overload; + Begin + Init(node); + End; + + Function Init(node); Begin node_ := node; name_ := 'w:p'; @@ -8497,8 +8528,8 @@ Type TParagraph = Class(DocObject, TParagraphImpl) Function Apply(); override; Begin arr := Marshal(); - class(xlsxXml).UpdateNode(node_, arr['attributes'], arr['children']); - CopyFormat(false, nil); + class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']); + CopyRunFormat(false, nil); End; ///修改段落内容 @@ -8592,6 +8623,14 @@ Type TParagraph = Class(DocObject, TParagraphImpl) return o; End; + ///在段落对象后面追加TRun对象 + ///返回TRun对象 + Function AppendRun(); + Begin + node := node_.InsertEndChild('element','w:r'); + return new TRun(node); + End; + ///段落中全部的修改标记(修订删除、修订插入) ///返回:TRevision对象列表,array(TRevision...); Function Revisions();overload; @@ -8614,9 +8653,9 @@ Type TParagraph = Class(DocObject, TParagraphImpl) r := array(); runs := GetRuns(); for i:=0 to length(runs)-1 do Begin - node := class(xlsxXml).GetNode(runs[i].node_, 'mc:AlternateContent/mc:Fallback/w:pict/v:shape/v:textbox/w:txbxContent'); + node := class(TSXml).GetNode(runs[i].node_, 'mc:AlternateContent/mc:Fallback/w:pict/v:shape/v:textbox/w:txbxContent'); if ifObj(node) then Begin - nodeEx := class(xlsxXml).GetNode(runs[i].node_, 'mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:txbx/wps:txbxContent'); + nodeEx := class(TSXml).GetNode(runs[i].node_, 'mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:txbx/w:txbxContent'); box := new TTextBox(node); box.Init(node_, nodeEx); r[length(r)] := box; @@ -8667,31 +8706,33 @@ Type TParagraph = Class(DocObject, TParagraphImpl) return name; End; - Function CopyFormat(del, therNode); + Function CopyRunFormat(del, toRunNode); Begin - rPr := class(xlsxXml).GetNode(node_, 'w:pPr/w:rPr'); - r := ifObj(rPr) ? rPr.Marshal() : array(); - if ifObj(therNode) then Begin - _copyFormat(therNode, r, del); + rPr := class(TSXml).GetNode(node_, 'w:pPr/w:rPr'); + dom := ifObj(rPr) ? rPr.Marshal() : array(); + if ifObj(toRunNode) then Begin + _copyRunFormat(toRunNode, dom, del); return; End; //复制到所有run runs := GetRuns(); for i:=0 to length(runs)-1 do - _copyFormat(runs[i].node_, r, del); + _copyRunFormat(runs[i].node_, dom, del); End; - Function _copyFormat(rNode, r, del); + //不能复用TRun::CopyFontFormat(),该函数是完全替换字体属性 + //本函数是追加、修改字体属性 + Function _copyRunFormat(toRunNode, dom, del); Begin - tNode := rNode.FirstChildElement('w:t'); - rPr2 := rNode.FirstChildElement('w:rPr'); + tNode := toRunNode.FirstChildElement('w:t'); + rPr2 := toRunNode.FirstChildElement('w:rPr'); if del and ifObj(rPr2) then rPr2.node_.DeleteChildren(); else if ifObj(tNode) and not ifObj(rPr2) then - rPr2 := class(xlsxXml).GetNode(rNode, 'w:rPr', 'first'); - if istable(r) and ifObj(rPr2) then - class(xlsxXml).UpdateNode(rPr2, r[0]['attributes'], r[0]['children']); + rPr2 := class(TSXml).GetNode(toRunNode, 'w:rPr', 'first'); + if istable(dom) and ifObj(rPr2) then + class(TSXml).UpdateNode(rPr2, dom[0]['attributes'], dom[0]['children']); End; End; @@ -8763,7 +8804,7 @@ Type TTabStops = Class(DocObject, TTabStopsImpl) End; if ifObj(a['node']) then Begin arr := tab.Marshal(); - class(xlsxXml).UpdateNode(a['node'], arr['attributes'], arr['children']); + class(TSXml).UpdateNode(a['node'], arr['attributes'], arr['children']); End; return tab; End; @@ -8790,7 +8831,7 @@ Type TTabStops = Class(DocObject, TTabStopsImpl) if ifObj(node_) then Begin for i:=0 to length(Tabs)-1 do Begin arr := Tabs[i]['obj'].Marshal(); - class(xlsxXml).UpdateNode(Tabs[i]['node'], arr['attributes'], arr['children']); + class(TSXml).UpdateNode(Tabs[i]['node'], arr['attributes'], arr['children']); End; End; End; @@ -8805,9 +8846,7 @@ Type TRun = Class(DocObject, TRunImpl) Function Create(node);overload; Begin - node_ := node; - name_ := 'w:r'; - Class(TRunImpl).Create(nil, 'w:r'); + Init(node); End; Function Create(pNode, name);overload; @@ -8815,6 +8854,13 @@ Type TRun = Class(DocObject, TRunImpl) Class(TRunImpl).Create(nil, 'w:r'); End; + Function Init(node); + Begin + node_ := node; + name_ := 'w:r'; + Class(TRunImpl).Create(nil, 'w:r'); + End; + Property Font read readFont; Function readFont(); Begin @@ -8825,7 +8871,7 @@ Type TRun = Class(DocObject, TRunImpl) Function Apply(); override; Begin arr := Marshal(); - class(xlsxXml).UpdateNode(node_, arr['attributes'], arr['children']); + class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']); End; ///添加tab @@ -8839,8 +8885,8 @@ Type TRun = Class(DocObject, TRunImpl) Function AddText(txt, isUtf8); Begin str := txt; - if not isUtf8 and not class(xlsxXml).IsUtf8() then - str := class(xlsxXml).CurCodePageToUtf8(txt); + if not isUtf8 and not class(TSXml).IsUtf8() then + str := class(TSXml).CurCodePageToUtf8(txt); if ifObj(node_) then Begin _insertText(str, false); return; @@ -8862,8 +8908,8 @@ Type TRun = Class(DocObject, TRunImpl) Function SetText(txt, isUtf8); Begin str := txt; - if not isUtf8 and not class(xlsxXml).IsUtf8() then - str := class(xlsxXml).CurCodePageToUtf8(txt); + if not isUtf8 and not class(TSXml).IsUtf8() then + str := class(TSXml).CurCodePageToUtf8(txt); if ifObj(node_) then Begin ClearText();//删除原来文字 _insertText(str, false);//添加文字 @@ -8914,8 +8960,8 @@ Type TRun = Class(DocObject, TRunImpl) // txt += '\n'; tNode := tNode.NextElement(); End; - if not class(xlsxXml).IsUtf8() then - return class(xlsxXml).Utf8ToCurCodePage(txt); + if not class(TSXml).IsUtf8() then + return class(TSXml).Utf8ToCurCodePage(txt); return txt; End; @@ -8926,6 +8972,17 @@ Type TRun = Class(DocObject, TRunImpl) if ifObj(rPr) then node_.DeleteChild(rPr); End; + + Function CopyFontFormat(fromRun); + Begin + ClearFormat(); + rPr := fromRun.node_.FirstChildElement('w:rPr'); + if not ifObj(rPr) then + return; + + data := rPr.Marshal(); + node_.InsertFirstChild(data[0]); + End; ///清除全部文字内容 Function ClearText(); @@ -8949,6 +9006,11 @@ Type TPicture = Class(DocObject, TPictureImpl) End; Function Create(node);overload; + Begin + Init(node); + End; + + Function Init(node); Begin node_ := node; name_ := 'w:p'; @@ -8964,10 +9026,29 @@ Type TPicture = Class(DocObject, TPictureImpl) End; ///修改图片格式 - Function Apply(); override; + ///[docx]:当前文档对象,为空指当前文档 + Function Apply(docx); override; Begin + document := docx; + if not ifObj(document) then Begin + document := TOfficeApi().GetDocument(); + if not ifObj(document) then + return; + End; arr := Marshal(); - class(xlsxXml).UpdateNode(node_, arr['attributes'], arr['children']); + class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']); + if ifBinary(Image) then Begin //修改图片内容 + node := class(TSXml).GetNode(node_,'w:r/w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip'); + if ifObj(node) then + rid := node.GetAttribute('r:embed'); + xml := document.ZipObject().Get('word/_rels/document.xml.rels'); + picFileName := class(TSXml).FindRelationshipTarget(xml, rid); + if ifstring(picFileName) then Begin + pic := document.ZipObject().Get('word/' + picFileName); + if ifObj(pic) then + pic.Data := Image; + End; + End; End; Function ScaledDimensions(image); @@ -9032,24 +9113,38 @@ Type TChart = Class(TChartImpl) Function Create(node);overload; Begin Class(TChartImpl).Create(nil, 'w:p'); - ChartNode := node; + pNode := node; + self.C := true; End; - Function Init(docx, pNode, cNode); + Function Init(docx, node, cNode); Begin - pNode_ := pNode; + pNode := node; if not ifObj(cNode) then return; rId := cNode.GetAttribute('r:id'); relsObj := docx.ZipObject().Get('word/_rels/document.xml.rels'); - ridNode := class(xlsxXml).FindRelationship(relsObj, rId); - if not ifObj(ridNode) then + Target := class(TSXml).FindRelationshipTarget(relsObj, rId); + if ifNil(Target) then return; - chartFileName := getChartFileName(ridNode.GetAttribute('Target')); + chartFileName := getChartFileName(Target); xmlObj := docx.ZipObject().Get(chartFileName); if not ifObj(xmlObj) then return; - chartNode := class(xlsxXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:plotArea'); + plotAreaNode := class(TSXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:plotArea'); + if ifObj(plotAreaNode) then Begin + child := plotAreaNode.FirstChildElement(); + while ifObj(child) do Begin + nodename := child.GetName(); + if rightstr(nodename,5) = 'Chart' then Begin + if leftstr(nodename,2) = 'c:' then + self.C := true; + ChartNode := child; + break; + End; + child := child.NextElement(); + End; + End; End; Function Serialize(isWord); @@ -9107,15 +9202,15 @@ Type TChart = Class(TChartImpl) Begin SerName := name; catArr := Categories; - if not class(xlsxXml).IsUtf8() then Begin + if not class(TSXml).IsUtf8() then Begin if name and ifstring(name) then - SerName := class(xlsxXml).CurCodePageToUtf8(name); + SerName := class(TSXml).CurCodePageToUtf8(name); if ifstring(catArr) then - catArr := class(xlsxXml).CurCodePageToUtf8(catArr); + catArr := class(TSXml).CurCodePageToUtf8(catArr); else if istable(catArr) then Begin for i:=0 to length(catArr)-1 do Begin if ifstring(catArr[i]) then - catArr[i] := class(xlsxXml).CurCodePageToUtf8(catArr[i]); + catArr[i] := class(TSXml).CurCodePageToUtf8(catArr[i]); End; End; End; @@ -9143,52 +9238,71 @@ Type TChart = Class(TChartImpl) return length(Series); End; + Function NewExcelFile(); + Begin + Excel := new TSExcelFile(); + [err, errmsg] := Excel.NewFile(); + if err then + Excel := nil; + End; + ///更新图表 - Function Apply(); + Function Apply(docx); Begin if not ifObj(ChartNode) then return; if ifstring(Title) and Title <> '' then - UpdateTitle(Title); - if length(Series) then Begin //删除已经存在Series - ser := Chart.C ? 'c:ser' : 'ser'; - node := ChartNode.FirstChildElement(ser); - while ifObj(node) do Begin - ChartNode.DeleteChild(node); - node := ChartNode.FirstChildElement(ser); + UpdateTitle(class(TSXml).CurCodePageToUtf8(Title)); + return; + //不同的图表,数据区较复杂 + if not istable(Series) then return; + ser := self.C ? 'c:ser' : 'ser'; + serNode := ChartNode.FirstChildElement(ser); + if not ifObj(serNode) then return;//没有缺省数据 + //存在Excel扩展数据文件 + node := xmlObj.FirstChildElement('c:chartSpace').FirstChildElement('c:externalData'); + if ifObj(node) then Begin + rId := node.GetAttribute('r:id'); + fName := ExtractFileName(chartFileName); + rels := 'word/charts/_rels/' + fName + '.rels'; + relsObj := docx.ZipObject().Get(rels); + if ifObj(relsObj) then Begin + target := FindRelationshipTarget(relsObj, rId);//../embeddings/Workbook2.xlsx + excelFileName := ReplaceStr(target, '..','word'); + excelObj := docx.ZipObject().Get(excelFileName); + if ifObj(excelObj) then + NewExcelFile(); End; End; - Plotarea := new TPlotarea(); - Serialize(); - //以下数据不更新,只更新Series - Plotarea.Layout := nil; - Plotarea.CatAx := new TcAxs(Plotarea, 'c:catAx'); - Plotarea.ValAx := new TcAxs(Plotarea, 'c:valAx'); - Plotarea.SerAx := new TcAxs(Plotarea, 'c:serAx'); - Plotarea.SpPr := new TspPr(Plotarea, 'c:spPr'); - tmp := Plotarea.Chart.ExtNodes; - Plotarea.Chart := new TcCharts(); - Plotarea.Chart.ExtNodes := tmp; - class(xlsxXml).UpdateNode(ChartNode, Plotarea.Marshal()); + for i:=0 to length(Series)-1 do Begin + // + End; + + //删除多余的 + node := serNode.NextElement(ser); + while ifObj(node) do Begin + ChartNode.DeleteChild(node); + node := ChartNode.NextElement(ser); + End; End; ///修改图表标题 Function UpdateTitle(t); Begin task := array('c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:t', 'pcdata', t); - class(xlsxXml).SetNodeValue(ChartNode.Root(), task); + class(TSXml).SetNodeValue(ChartNode.Root(), task); End; ///显示数据表 ///b:bool型,是否显示数据表 Function ShowDataTable(b); Begin - if not ifObj(ChartNode) then + if not ifObj(plotAreaNode) then return; - node := ChartNode.FirstChildElement('c:dTable'); + node := plotAreaNode.FirstChildElement('c:dTable'); if ifObj(node) then - ChartNode.DeleteChild(node); + plotAreaNode.DeleteChild(node); if not b then return; xmlStr := ' @@ -9213,7 +9327,7 @@ Type TChart = Class(TChartImpl) '; - ChartNode.InsertEndChild(xmlStr); + plotAreaNode.InsertEndChild(xmlStr); End; private Function getChartFileName(f); @@ -9224,6 +9338,8 @@ private return 'word/' + f[4:]; if f[1] = '/' then return f[2:]; + if leftstr(f,7) = 'charts/' then + return 'word/' + f; return f; End; @@ -9232,7 +9348,7 @@ private for i:=0 to length(task)-1 do Begin if not C then task[i][0] := ReplaceStr(task[i][0], 'c:', ''); - class(xlsxXml).SetNodeValue(xmlObj_, task[i]); + class(TSXml).SetNodeValue(xmlObj_, task[i]); End; End; @@ -9560,7 +9676,7 @@ private SerArr union= array(('name':'c:ser','obj':ser,'attrEx':'','nodeType':'','attrName':'')); ser.IDx := i + Ord; ser.Ord := i + Ord; - setTx(ser.Tx.StrRef, Series[i]['Name']); + setTx(ser.Tx.StrRef, Series[i]['Name'], i); setSpPr(ser.SpPr, i); setMarker(ser.Marker, i); setDpt(ser, i); @@ -9576,16 +9692,26 @@ private o.chart.Ser := SerArr; End; - Function setTx(strRef, name); + Function _setExcelCellVal(cell, v); + Begin + //v is utf8 + if ifObj(Excel) then Begin + Excel.SetCellValue('Sheet1', cell, class(TSXml).Utf8ToCurCodePage(v)); + End; + End; + + Function setTx(strRef, name, i); Begin if not IsWord_ then Begin strRef.F := name; return; End; - strRef.F := 'Sheet1!$B$1'; + [err, col] := ColumnNumberToName(2*i + 2); + strRef.F := 'Sheet1!$' $ col $ '$1'; strRef.strCache.ptCount := 1; strRef.strCache.pt.IDx := 0; strRef.strCache.pt.V := name; + _setExcelCellVal(col $ '1', name); End; Function setBubble3D(ser, i); @@ -9633,6 +9759,8 @@ private Tpt := TOfficeObj('Tpt'); Tpt.IDx := i; Tpt.V := data[i]; + [err,cell] := CoordinatesToCellName(2*ind+2, i+2); + _setExcelCellVal(cell, data[i]); Val.NumRef.NumCache.NewChildNode( array("field":"", "name":"c:pt", "obj":Tpt, "attrEx":"", "nodeType":"") ); End; End; @@ -9648,7 +9776,7 @@ private Begin Categories := Series[ind]['Categories']; if ifstring(Categories) then - cat.StrRef.F := Categories; //excel图表(Sheet1!$B$2:$B$6) + cat.StrRef.F := Categories; //excel图表(Sheet1!$A$2:$A$6) else if istable(Categories) then Begin //word 图表 cnt := length(Categories); [err, axis] := ColumnNumberToName(2 * ind + 1); @@ -9658,6 +9786,8 @@ private Tpt := TOfficeObj('Tpt'); Tpt.IDx := i; Tpt.V := Categories[i]; + [err,cell] := CoordinatesToCellName(2*ind+1, i+2); + _setExcelCellVal(cell, Tpt.V); cat.StrRef.StrCache.NewChildNode( array("field":"", "name":"c:pt", "obj":Tpt, "attrEx":"", "nodeType":"") ); End; End; @@ -10003,10 +10133,10 @@ Type TSectPr = Class top := pgMar.GetAttribute('w:top'); bottom := pgMar.GetAttribute('w:bottom'); End; - PageWidth := Class(xlsxXml).SafeStrToIntDef(w, 11906)-Class(xlsxXml).SafeStrToIntDef(left,1800)-Class(xlsxXml).SafeStrToIntDef(right,1800); - PageHeight := Class(xlsxXml).SafeStrToIntDef(h, 16838)-Class(xlsxXml).SafeStrToIntDef(top,1440)-Class(xlsxXml).SafeStrToIntDef(bottom,1440); + PageWidth := Class(TSXml).SafeStrToIntDef(w, 11906)-Class(TSXml).SafeStrToIntDef(left,1800)-Class(TSXml).SafeStrToIntDef(right,1800); + PageHeight := Class(TSXml).SafeStrToIntDef(h, 16838)-Class(TSXml).SafeStrToIntDef(top,1440)-Class(TSXml).SafeStrToIntDef(bottom,1440); docGrid := node.FirstChildElement('w:docGrid'); - LinePitch := ifObj(docGrid) ? Class(xlsxXml).SafeStrToIntDef(docGrid.GetAttribute('w:linePitch'), 312) : 312; + LinePitch := ifObj(docGrid) ? Class(TSXml).SafeStrToIntDef(docGrid.GetAttribute('w:linePitch'), 312) : 312; PageLine := new TPageLine(PageWidth); if istable(ContentArr) then Begin //计算当前章节页码 //w:p;w:tbl @@ -10069,7 +10199,7 @@ Type TSectPr = Class defaultPpr := docx_.StyleObject().defaultPpr_;//缺省段落 defaultRpr := docx_.StyleObject().defaultRpr_;//缺省字体 - pPr := Class(xlsxXml).ReadPprFormat(p.node_); + pPr := Class(TSXml).ReadPprFormat(p.node_); //存在段落样式 StyleId := p.pPr.Value('StyleId'); if StyleId then Begin @@ -10080,8 +10210,8 @@ Type TSectPr = Class pPr := stylePpr; End else - Class(xlsxXml).CopyPprFormat(pPr, stylePpr); - //Class(xlsxXml).CopyPprFormat(pPr, defaultPpr); + Class(TSXml).CopyPprFormat(pPr, stylePpr); + //Class(TSXml).CopyPprFormat(pPr, defaultPpr); defaultRpr := oStyle.ReadRprFormat(); //读段落字体属性(缓存到StyleObject中) End; @@ -10091,7 +10221,7 @@ Type TSectPr = Class pPr := defaultPpr; End else - Class(xlsxXml).CopyPprFormat(pPr, defaultPpr); + Class(TSXml).CopyPprFormat(pPr, defaultPpr); End; LineRatio := 1.0; @@ -10113,18 +10243,18 @@ Type TSectPr = Class runs := p.GetRuns(); for i:=0 to length(runs)-1 do Begin run := runs[i]; - rPr := Class(xlsxXml).ReadRprFormat(run.node_); + rPr := Class(TSXml).ReadRprFormat(run.node_); if not ifObj(rPr) then rPr := defaultRpr; else - Class(xlsxXml).CopyRprFormat(rPr, defaultRpr); + Class(TSXml).CopyRprFormat(rPr, defaultRpr); //_dumpRpr(rpr); RunLineHeight := _GetHeightRatio(pPr, rPr, LineRatio) * defaultLineHeight; //缺省段落高度 pic := run.node_.FirstChildElement('w:drawing/wp:inline/wp:extent');//图片 if not ifObj(pic) then pic := run.node_.FirstChildElement('mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:extent');//文本框 if ifObj(pic) then Begin - cy := Class(xlsxXml).SafeStrToIntDef(pic.GetAttribute('cy'), LinePitch); + cy := Class(TSXml).SafeStrToIntDef(pic.GetAttribute('cy'), LinePitch); height := cy / ETU / 0.0325; _addLine(startPage, curPageNo, curLinePos, height, before, linesCnt ? false : true, txt); //加入一行 linesCnt ++; @@ -10185,9 +10315,9 @@ Type TSectPr = Class startPage := page; curPageNo := page; curLinePos := lpos; - topH := Class(xlsxXml).SafeStrToIntDef(tbl.tblPr.Borders.Top.Value('Val'), 4); //缺省0.5磅,一磅=20点 - bottomH := Class(xlsxXml).SafeStrToIntDef(tbl.tblPr.Borders.bottom.Value('Val'), 4); //缺省0.5磅 - insideVH := Class(xlsxXml).SafeStrToIntDef(tbl.tblPr.Borders.insideV.Value('Val'), 4); //缺省0.5磅 + topH := Class(TSXml).SafeStrToIntDef(tbl.tblPr.Borders.Top.Value('Val'), 4); //缺省0.5磅,一磅=20点 + bottomH := Class(TSXml).SafeStrToIntDef(tbl.tblPr.Borders.bottom.Value('Val'), 4); //缺省0.5磅 + insideVH := Class(TSXml).SafeStrToIntDef(tbl.tblPr.Borders.insideV.Value('Val'), 4); //缺省0.5磅 iRow := 0; trNode := tbl.node_.FirstChildElement('w:tr'); while ifObj(trNode) do Begin @@ -10195,7 +10325,7 @@ Type TSectPr = Class maxLinePos := curLinePos; tr := new TwTr(nil, 'w:tr'); tr.RootObj := trNode; - vh := Class(xlsxXml).SafeStrToIntDef(tr.tblPrEx.Borders.insideV.Value('Val'), insideVH); //行的上边框 + vh := Class(TSXml).SafeStrToIntDef(tr.tblPrEx.Borders.insideV.Value('Val'), insideVH); //行的上边框 tcNode := trNode.FirstChildElement('w:tc'); while ifObj(tcNode) do Begin //计算每一个单元格占用页面 tcPageNo := curPageNo; @@ -10351,7 +10481,7 @@ Type TDocumentBody = Class(DocObject) p.node_ := paragraph.node_; p.name_ := 'w:p'; //复制段落字体属性 - p.CopyFormat(false); + p.CopyRunFormat(false, nil); _set_lastParagraph_(p.node_);//设置最后一个段落 return p; End; @@ -10406,8 +10536,8 @@ Type TDocumentBody = Class(DocObject) return AddParagraph(paragraph, posOpt); End; - ///word文档所有内容的文本串数组,包含段落信息 - ///返回:array(("pNode":nodeObj, "pIndex":p, "rNode":nodeObj, "rIndex":r)) + //word文档所有内容的文本串数组,包含段落信息 + //返回:array(("pNode":nodeObj, "pIndex":p, "rNode":nodeObj, "rIndex":r)) Function TextArray();override; Begin r := array(); @@ -10433,6 +10563,13 @@ Type TDocumentBody = Class(DocObject) return length(t); End; + ///word文档所有表格 + ///返回:TTable对象数组 + Function Tables(); + Begin + return getDocumentObjects(node_, 'w:tbl'); + End; + ///word文档指定表格 ///n: int 第n个表格 ///返回:TTable对象 @@ -10530,20 +10667,20 @@ Type TDocumentBody = Class(DocObject) Function InsertTable(tbl, posOpt); Begin addPart(posOpt, tbl); - tblBorders := class(xlsxXml).GetNode(tbl.node_, 'w:tblPr/w:tblBorders'); - tblCellMar := class(xlsxXml).GetNode(tbl.node_, 'w:tblPr/w:tblCellMar'); + tblBorders := class(TSXml).GetNode(tbl.node_, 'w:tblPr/w:tblBorders'); + tblCellMar := class(TSXml).GetNode(tbl.node_, 'w:tblPr/w:tblCellMar'); if ifObj(tblBorders) or ifObj(tblCellMar) then Begin borders := ifObj(tblBorders) ? tblBorders.Marshal() : nil; cellmar := ifObj(tblCellMar) ? tblCellMar.Marshal() : nil; tr := tbl.node_.FirstChildElement('w:tr'); while ifObj(tr) do Begin if ifObj(tblCellMar) then Begin - c := class(xlsxXml).GetNode(tr, 'w:tblPrEx/w:tblCellMar', 'first'); - class(xlsxXml).UpdateNode(c, cellmar[0]['attributes'], cellmar[0]['children']); + c := class(TSXml).GetNode(tr, 'w:tblPrEx/w:tblCellMar', 'first'); + class(TSXml).UpdateNode(c, cellmar[0]['attributes'], cellmar[0]['children']); End; if ifObj(tblBorders) then Begin - b := class(xlsxXml).GetNode(tr, 'w:tblPrEx/w:tblBorders', 'first'); - class(xlsxXml).UpdateNode(b, borders[0]['attributes'], borders[0]['children']); + b := class(TSXml).GetNode(tr, 'w:tblPrEx/w:tblBorders', 'first'); + class(TSXml).UpdateNode(b, borders[0]['attributes'], borders[0]['children']); End; tr := tr.NextElement('w:tr'); End; @@ -10576,27 +10713,26 @@ Type TDocumentBody = Class(DocObject) for i:=0 to length(files)-1 do Begin if zipfile_.Diff(files[i], picture.Image) = 0 then Begin prefix := ReplaceStr(files[i], 'word/', ''); - [rid, imageFile] := class(xlsxXml).FindRelationshipRid(xml, prefix); + [maxRid, imageFile, rid] := class(TSXml).FindRelationshipRid(xml, prefix); End; End; if rid = 0 then Begin imageCnt := length(files) + 1; imageFile := 'media/image' $ imageCnt $ '.' $ image.ExtFileName; - [rid, target] := class(xlsxXml).FindRelationshipRid(xml, ''); + [rid, target] := class(TSXml).FindRelationshipRid(xml, ''); rid ++; - class(xlsxXml).AddRelationshipRid(xml, imageFile, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid); + class(TSXml).AddRelationshipRid(xml, imageFile, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid); zipfile_.Add('word/' + imageFile, picture.Image); contentXml := zipfile_.Get('[Content_Types].xml'); - class(xlsxXml).AddDefaultContentType(contentXml, image.ExtFileName, 'image/' $ image.ExtFileName); + class(TSXml).AddDefaultContentType(contentXml, image.ExtFileName, 'image/' $ image.ExtFileName); End; [cx, cy] := picture.ScaledDimensions(image);//extent 元素通过其属性指定此对象的高度和宽度为 [cx,cy] ETU (英语公制单位) //println('cx={},cy={},w={},h={}',cx,cy,image.px_width,image.px_height); picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.BlipFill.blip.Embed := 'rId' $ rid; picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.BlipFill.Stretch.FillRect := 1; picId := getPictureMaxId() + 1; - picture.Run.Drawing.WInline.ID := picId; picture.Run.Drawing.WInline.Name := '图片 ' $ picId; - picture.Run.Drawing.WInline.Descr := class(xlsxXml).CurCodePageToUtf8(picture.Descr); + picture.Run.Drawing.WInline.Descr := class(TSXml).CurCodePageToUtf8(picture.Descr); picture.Run.Drawing.WInline.cNvGraphicFramePr.xmlns := 'http://schemas.openxmlformats.org/drawingml/2006/main'; picture.Run.Drawing.WInline.cNvGraphicFramePr.noChangeAspect := 1; picture.Run.Drawing.WInline.Graphic.xmlns := 'http://schemas.openxmlformats.org/drawingml/2006/main'; @@ -10677,7 +10813,7 @@ Type TDocumentBody = Class(DocObject) r[length(r)] := section; End else if name = 'w:p' then Begin - child := class(xlsxXml).GetNode(node, 'w:pPr/w:sectPr', false); + child := class(TSXml).GetNode(node, 'w:pPr/w:sectPr', false); if ifObj(child) then Begin section := new TDocSection(node, index++, zipfile_); r[length(r)] := section; @@ -10717,6 +10853,302 @@ Type TDocumentBody = Class(DocObject) return new TDocSection(p.node_.FirstChildElement('w:sectPr'), -2, zipfile_); End; + Function ExecInnerTSL(docx); + Begin + //表格 + t := array(); + tslFuncCount := 0; + errArr := array(); + tArr := Tables(); + for i:=0 to length(tArr)-1 do Begin + col := tArr[i].Cols(); + row := tArr[i].Rows(); + for r:= 1 to row do Begin + for c:=1 to col do Begin + cell := tArr[i].Cell(r, c); + [err, cnt, err] := cell.ExecInnerTSL(docx);//递归 + tslFuncCount += cnt; + errArr union= err; + End; + End; + End; + + //文本框 + ps := Paragraphs(); + for i:=0 to length(ps)-1 do Begin + boxs := ps[i].TextBoxs(); + for j:=0 to length(boxs)-1 do Begin + [err, cnt, err] := boxs[j].ExecInnerTSL(docx);//递归 + if cnt then + boxs[j].Apply(); + tslFuncCount += cnt; + errArr union= err; + End; + End; + + //页脚、页眉 + sArr := Sections(); + tpArr := array('default','even','first'); + for i:=0 to length(sArr)-1 do Begin + for k, name in tpArr do Begin + h := sArr[i].Header(name); + if ifObj(h) then Begin + [err, cnt, err] := h.ExecInnerTSL(docx);//递归 + tslFuncCount += cnt; + errArr union= err; + End; + + f := sArr[i].Footer(name); + if ifObj(f) then Begin + [err, cnt, err] := f.ExecInnerTSL(docx);//递归 + tslFuncCount += cnt; + errArr union= err; + End; + End; + End; + + [err, cnt, err] := ExecInnerTSLImpl(docx); + tslFuncCount += cnt; + errArr union= err; + return array(length(errArr), tslFuncCount, errArr); + End; + + Function ExecInnerTSLImpl(docx); + Begin + tslFuncCount := 0; + errArr := array(); + tslArr := array(); + tArr := TextArray(); + flag := ''; + code := nil; + begParagraphIndex := -1; + begPos := 0; + begTxtLen := 0; + for i:=0 to length(tArr)-1 do Begin + txt := ''; + if ifObj(tArr[i]['rNode']) then Begin + run := new TRun(tArr[i]['rNode']); + txt := run.Text(); + if class(TSXml).IsUtf8() then + txt := UTF8ToAnsi(txt); + End; + k := 1; + wz := 1; + txtLen := length(txt); + while k <= txtLen do Begin + c := txt[k]; + case flag of + '': + if c = '[' then Begin + flag := '['; + begParagraphIndex := i; + begPos := wz; + begTxtLen := txtLen; + End; + '[': + if c = 'T' or c = 't' then + flag := '[T'; + else + flag := ''; + '[T': + if c = 'S' or c = 's' then + flag := '[TS'; + else + flag := ''; + '[TS': + if c = 'L' or c = 'l' then + flag := '[TSL'; + else + flag := ''; + '[TSL': + if c = ']' then Begin + flag := '[TSL]'; + tslArr := tArr[begParagraphIndex:i,:]; + code := ''; + k++; + wz++; + continue; + End + else + flag := ''; + '[TSL]': + if c = '[' then + flag := '[TSL]['; + '[TSL][': + if c = '/' then + flag := '[TSL][/'; + else + flag := '[TSL]'; + '[TSL][/': + if c = 'T' or c='t' then + flag := '[TSL][/T'; + else + flag := '[TSL]'; + '[TSL][/T': + if c = 'S' or c='s' then + flag := '[TSL][/TS'; + else + flag := '[TSL]'; + '[TSL][/TS': + if c = 'L' or c='l' then + flag := '[TSL][/TSL'; + else + flag := '[TSL]'; + '[TSL][/TSL': + if c = ']' then Begin + curParagraphNode := tslArr[0]['pNode']; + ind := length(tslArr) - 1; + if tslArr[ind]['pIndex'] <> tArr[i]['pIndex'] or tslArr[ind]['rIndex'] <> tArr[i]['rIndex'] then Begin + ind ++; + tslArr[ind] := tArr[i]; + End; + if begPos > 1 then Begin //函数前分割为新的w:r + prevRun := run._duplicate_r(tArr[begParagraphIndex]['rNode']); + run._adjust_r(tArr[begParagraphIndex]['rNode'], 0, begPos - 1); + tslArr[0]['rNode'] := prevRun; + End; + if k < txtLen then Begin //函数后面分割为新的w:r + oldNode := run.node_; + if begParagraphIndex = i and begPos > 1 then + oldNode := prevRun; + tArr[i]['rNode'] := run._duplicate_r(oldNode); + run._adjust_r(tArr[i]['rNode'], wz, txtLen); + i--; + End; + curRunNode := tslArr[0]['rNode']; + curRun := new TRun(curRunNode); + curRun.ClearText(); + rmvPara := array(); + for m := 1 to length(tslArr) - 1 do Begin + if ifObj(tslArr[m]['rNode']) then Begin + tslArr[m]['pNode'].DeleteChild(tslArr[m]['rNode']); + hasrNode := tslArr[m]['pNode'].FirstChildElement('w:r'); + if not ifObj(hasrNode) then + rmvPara[ tslArr[m]['pIndex'] ] := tslArr[m]['pNode']; + End + else + rmvPara[ tslArr[m]['pIndex'] ] := tslArr[m]['pNode']; + End; + for index, pNode in rmvPara do Begin + pNode.Parent().DeleteChild(pNode); + End; + //run inner tsl + code := leftstr(code, lengthW(code) - 5); + CodePage := TOfficeApi().Get('CodePage'); + TOfficeApi().Set('Docx', docx); + TOfficeApi().Set('CurrentParagraph', curParagraphNode); + TOfficeApi().Set('CurrentRun', curRunNode); + TOfficeApi().Set('CodePage', 'gbk'); + try + tslFuncCount ++; + if code <> '' then + str := eval(&code); + except + println('run code={},err={}', code, ExceptObject.ErrInfo); + errArr[ length(errArr) ] := array('code':code, 'err':ExceptObject.ErrInfo); + str := ''; + End; + tNode := curRun.node_.FirstChildElement('w:t'); + if not ifObj(tNode) then Begin //没有在外部插入文字 + if not ifstring(str) or str = '' then Begin //删除w:r + curParagraphNode.DeleteChild(curRunNode); + hasrNode := curParagraphNode.FirstChildElement('w:r'); + if not ifObj(hasrNode) then Begin//删除空段落 + curParagraphNode.Parent().DeleteChild(curParagraphNode); + curParagraphNode := nil; + End; + End + else Begin + str := AnsiToUTF8(str); + lines := str2array(str, '\r\n'); + lineCnt := length(lines); + if lineCnt = 1 then Begin //单行 + curRun.SetText(str, true); + End + else Begin //多行 + curRun.SetText(lines[0], true); + nextRun := curRun.node_.NextElement('w:r'); + if ifObj(nextRun) then Begin //段落炸裂 + curLine := 0; + prevRNode := curRunNode; + while ifObj(prevRNode) do Begin + curLine ++; + prevRNode := prevRNode.PrevElement('w:r'); + End; + data := curParagraphNode.Marshal(); + LastParagraphNode := curParagraphNode.Parent().InsertAfterChild(curParagraphNode, data[0]);//复制段落 + rmvArr := array(); + cnt := 0; + rNode := LastParagraphNode.FirstChildElement('w:r'); + while ifObj(rNode) do Begin + cnt ++; + if cnt < curLine then + rmvArr[rmvN++] := rNode; + else if cnt = curLine then Begin + rNode.ClearText(); + rNode.SetText(lines[lineCnt-1], true); + lineCnt--; + End; + rNode := rNode.NextElement('w:r'); + End; + cnt := 0; + rNode := curParagraphNode.FirstChildElement('w:r'); + while ifObj(rNode) do Begin + cnt ++; + if cnt > curLine then + rmvArr[rmvN++] := rNode; + rNode := rNode.NextElement('w:r'); + End; + //删除重复的run + for rmvN := 0 to rmvN < length(rmvArr)-1 do begin + rmvArr[rmvN].Parent().DeleteChild(rmvArr[rmvN]); + End; + End;//段落炸裂 + curParagraph := new TParagraph(curParagraphNode); + prev := curParagraph; + for nP:=1 to lineCnt - 1 do Begin //新段落 + if lines[nP]='' then continue; + p := new TParagraph(); + p.Run.SetText(lines[nP], true); + prev := docx.AddParagraph(p, prev.Node()); + docx.CopyFormat(curParagraph, prev);//格式刷 + End; + End; + End; + End; + TOfficeApi().Set('CodePage', CodePage); + + flag := ''; + code := nil; + tslArr := array(); + continue; + End + else + flag := '[TSL]'; + End; + if Ord(c) > 127 then Begin + if ifstring(code) then + code += txt[k:k+1]; + k ++; + End + else if ifstring(code) then + code += c; + k ++; + wz ++; + End; + if length(tslArr) then Begin + //println('pIndex={},txt={},i={}',tArr[i]['pIndex'], txt, i); + if i and i < length(tArr) and tArr[i]['pIndex'] <> tArr[i+1]['pIndex'] then Begin + code += ' \n'; + End; + ind := length(tslArr) - 1; + if tslArr[ind]['pIndex'] <> tArr[i]['pIndex'] or tslArr[ind]['rIndex'] <> tArr[i]['rIndex'] then + tslArr[ind + 1] := tArr[i]; + End; + End; + return array(length(errArr), tslFuncCount, errArr); + End; + Function GetHeadingListImpl(docx, posOpt, UpperHeadingLevel, LowerHeadingLevel, numIds, bHeadList); Begin r := array(); @@ -10745,7 +11177,7 @@ Type TDocumentBody = Class(DocObject) numId := p.Format.NumPr.Value('numId'); lvlStr := p.Format.NumPr.Value('Level'); if numId and lvlStr then Begin - ilvl := Class(xlsxXml).SafeStrToIntDef(lvlStr, -1); + ilvl := Class(TSXml).SafeStrToIntDef(lvlStr, -1); if ilvl >= 0 and ilvl < 10 then Begin if not istable(numIds[numId]) then numIds[numId] := array(0,0,0,0,0,0,0,0,0,0); @@ -10765,7 +11197,7 @@ Type TDocumentBody = Class(DocObject) obj := docx.StyleObject().GetStyleById(styleId); if ifObj(obj) then Begin level := obj.HeadingLevel(); - iLevel := Class(xlsxXml).SafeStrToIntDef(level, -1); + iLevel := Class(TSXml).SafeStrToIntDef(level, -1); if iLevel+1 >= UpperHeadingLevel and iLevel+1 <= LowerHeadingLevel then Begin r[ind]['Level'] := strtoint(level); r[ind]['Paragraph'] := p; @@ -10783,7 +11215,7 @@ Type TDocumentBody = Class(DocObject) End else if ifarray(numIds) and name = 'w:tbl' then Begin tbl := TOfficeObj('TTable'); - tbl.InitNode(pNode); + tbl.Init(pNode); sectPr.Append(tbl); rows := tbl.Rows(); cols := tbl.Cols(); @@ -10812,7 +11244,7 @@ Type TDocumentBody = Class(DocObject) while ifObj(pNode) do Begin rNode := pNode.FirstChildElement('w:r'); while ifObj(rNode) do Begin - node := class(xlsxXml).GetNode(rNode, 'w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blibFill/a:blib'); + node := class(TSXml).GetNode(rNode, 'w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blibFill/a:blib'); if ifObj(node) then Begin v := node.GetAttribute('r:embed'); if v <> '' then Begin @@ -10830,7 +11262,7 @@ Type TDocumentBody = Class(DocObject) Function addPart(posOpt, o); Begin node := posOpt; - if ifObj(posOpt) and (not posOpt is Class(XmlNode)) then + if ifObj(posOpt) and not (posOpt is Class(XmlNode)) then node := posOpt.Node(); node := findNode(node, true); nodeArr := o.Marshal(); @@ -10948,34 +11380,34 @@ Type TDocHeaderFooter = Class(TDocumentBody) if txt <> '' then r[ cnt++ ] := txt; p := TOfficeObj('TParagraph'); - class(xlsxXml).CopyRprFormat(p.pPr.rPr, font); + class(TSXml).CopyRprFormat(p.pPr.rPr, font); for i:=0 to length(r)-1 do Begin run := p.AddRun(); if r[i] = '{0}' then Begin //页码 run.fldCharType := 'begin'; - class(xlsxXml).CopyRprFormat(run.rPr, font); + class(TSXml).CopyRprFormat(run.rPr, font); PageNo := p.AddRun(); PageNo.InstrText := ' PAGE \\* MERGEFORMAT '; PageNo.InstrTextSpace := 'preserve'; - class(xlsxXml).CopyRprFormat(PageNo.rPr, font); + class(TSXml).CopyRprFormat(PageNo.rPr, font); run := p.AddRun(); run.fldCharType := 'end'; - class(xlsxXml).CopyRprFormat(run.rPr, font); + class(TSXml).CopyRprFormat(run.rPr, font); End else if r[i] = '{1}' then Begin //总页数 run.fldCharType := 'begin'; - class(xlsxXml).CopyRprFormat(run.rPr, font); + class(TSXml).CopyRprFormat(run.rPr, font); TotalPageNo := p.AddRun(); TotalPageNo.InstrText := ' NUMPAGES \\* MERGEFORMAT '; TotalPageNo.InstrTextSpace := 'preserve'; - class(xlsxXml).CopyRprFormat(TotalPageNo.rPr, font); + class(TSXml).CopyRprFormat(TotalPageNo.rPr, font); run := p.AddRun(); run.fldCharType := 'end'; - class(xlsxXml).CopyRprFormat(run.rPr, font); + class(TSXml).CopyRprFormat(run.rPr, font); End else Begin run.SetText( r[i] ); - class(xlsxXml).CopyRprFormat(Run.rPr, font); + class(TSXml).CopyRprFormat(Run.rPr, font); End; End; return AddParagraph(p, -1, nil); @@ -11008,7 +11440,7 @@ Type TDocSection = Class(DocObject, TDocSectionImpl) End; ///返回指定页眉 - ///type:页眉类型,(default、evet、first) + ///type:页眉类型,(default、even、first) ///default, Header for odd pages or all if no even header. ///first, Header for first page of section. ///even, Header for even pages of recto/verso section. @@ -11018,7 +11450,7 @@ Type TDocSection = Class(DocObject, TDocSectionImpl) End; ///返回指定页脚 - ///type:页眉类型,(default、evet、first) + ///type:页眉类型,(default、even、first) ///default, Header for odd pages or all if no even header. ///first, Header for first page of section. ///even, Header for even pages of recto/verso section. @@ -11028,7 +11460,7 @@ Type TDocSection = Class(DocObject, TDocSectionImpl) End; ///添加页眉 - ///type:页眉类型,(default、evet、first) + ///type:页眉类型,(default、even、first) ///default, Header for odd pages or all if no even header. ///first, Header for first page of section. ///even, Header for even pages of recto/verso section. @@ -11038,7 +11470,7 @@ Type TDocSection = Class(DocObject, TDocSectionImpl) End; ///添加页脚 - ///type:页眉类型,(default、evet、first) + ///type:页眉类型,(default、even、first) ///default, Header for odd pages or all if no even header. ///first, Header for first page of section. ///even, Header for even pages of recto/verso section. @@ -11065,15 +11497,15 @@ Type TDocSection = Class(DocObject, TDocSectionImpl) End if ifObj(obj) then return obj; rels := zipfile_.Get('word/_rels/document.xml.rels'); - [rid, target] := class(xlsxXml).FindRelationshipRid(rels, '');//最大rId + [rid, target] := class(TSXml).FindRelationshipRid(rels, '');//最大rId rid ++; files := sselect ['FileName'] from zipfile_.Files() where AnsiStartsText('word/' $ headerFooter, ['FileName']) end; fid := length(files) + 1;//文件ID号 target := headerFooter $ fid $ '.xml'; - class(xlsxXml).AddRelationshipRid(rels, target, type, 'rId'$rid, nil);//添加rId + class(TSXml).AddRelationshipRid(rels, target, type, 'rId'$rid, nil);//添加rId PartName := '/word/' $ headerFooter $ fid $ '.xml'; contentXml := zipfile_.Get('[Content_Types].xml'); - class(xlsxXml).AddOverrideContentType(contentXml, partName, contentType);//添加Contet_Types + class(TSXml).AddOverrideContentType(contentXml, partName, contentType);//添加Contet_Types fname := 'word/' $ headerFooter $ fid $ '.xml'; zipfile_.Add(fname, fileContent);//创建页脚、页眉文件 node := node_.InsertFirstChild('element', headerFooter = 'header' ? 'w:headerReference' : 'w:footerReference'); @@ -11103,7 +11535,7 @@ Type TDocSection = Class(DocObject, TDocSectionImpl) rid := _getRid(key, type); if rid='' then return nil; rels := zipfile_.Get('word/_rels/document.xml.rels'); - theNode := class(xlsxXml).FindRelationship(rels, rid); + theNode := class(TSXml).FindRelationship(rels, rid); if not ifObj(theNode) then return nil; fname := 'word/' $ theNode.GetAttribute('Target'); @@ -11146,7 +11578,7 @@ Type TTextBox = Class(TDocumentBody, TTextBoxImpl) Begin data := node_.Marshal(); NodeEx_.DeleteChildren(); - class(xlsxXml).UpdateNode(NodeEx_, data[0]['attributes'], data[0]['children']); + class(TSXml).UpdateNode(NodeEx_, data[0]['attributes'], data[0]['children']); End; pNode_;// @@ -11176,7 +11608,7 @@ Type TRow = Class(DocObject, TwTr) Function Apply();virtual; Begin arr := Marshal(); - class(xlsxXml).UpdateNode(node_, arr['attributes'], arr['children']); + class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']); End; End; @@ -11215,14 +11647,14 @@ Type TCell = Class(TDocumentBody, TWTc) Function Apply(); override; Begin arr := Marshal(); - class(xlsxXml).UpdateNode(node_, arr['attributes'], arr['children']); + class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']); arr := pPr_.Marshal(); if length(arr['attributes']) or length(arr['children']) then Begin pNode := node_.FirstChildElement('w:p'); while ifObj(pNode) do Begin - pPr := class(xlsxXml).GetNode(pNode, 'w:pPr', 'first'); - class(xlsxXml).UpdateNode(pPr, arr['attributes'], arr['children']); + pPr := class(TSXml).GetNode(pNode, 'w:pPr', 'first'); + class(TSXml).UpdateNode(pPr, arr['attributes'], arr['children']); pNode := pNode.NextElement(); End; End; @@ -11292,7 +11724,7 @@ Type TTable = Class(DocObject, TTableImpl) name_ := 'w:tbl'; Class(TTableImpl).Create(nil, 'w:tbl'); if ifObj(node) then - InitNode(node); + Init(node); End; Function Root();override; @@ -11300,7 +11732,7 @@ Type TTable = Class(DocObject, TTableImpl) return node_; End; - Function InitNode(node); + Function Init(node); Begin node_ := node; cells_ := array(); @@ -11345,7 +11777,7 @@ Type TTable = Class(DocObject, TTableImpl) Function Apply(); override; Begin arr := Marshal(); - class(xlsxXml).UpdateNode(node_, arr['attributes'], arr['children']); + class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']); End; ///列数 @@ -11431,9 +11863,9 @@ Type TTable = Class(DocObject, TTableImpl) for row:=top2 to bottom2 do Begin c := Cell(row, left2); c.mergeSpan_ := val; - gridSpan := class(xlsxXml).GetNode(c.node_, 'w:tcPr/w:gridSpan', true); + gridSpan := class(TSXml).GetNode(c.node_, 'w:tcPr/w:gridSpan', true); gridSpan.SetAttribute('w:val', val); - node := class(xlsxXml).GetNode(c.node_, 'w:tcPr/w:vMerge', true); + node := class(TSXml).GetNode(c.node_, 'w:tcPr/w:vMerge', true); node.SetAttribute('w:val', row=top2 ? 'restart' : 'continue'); if row <> top2 then Begin if not del then @@ -11521,9 +11953,9 @@ Type TTable = Class(DocObject, TTableImpl) Function _getVSpan(node); Begin - vMerge := class(xlsxXml).GetNode(node, 'w:tcPr/w:vMerge'); + vMerge := class(TSXml).GetNode(node, 'w:tcPr/w:vMerge'); if ifObj(vMerge) and vMerge.GetAttribute('w:val') in array('restart', 'continue') then Begin - nSpan := class(xlsxXml).GetNode(node, 'w:tcPr/w:gridSpan'); + nSpan := class(TSXml).GetNode(node, 'w:tcPr/w:gridSpan'); if ifObj(nSpan) then Begin return strtoint(nSpan.GetAttribute('w:val')); End; @@ -11605,9 +12037,9 @@ private Function propValue(k); Begin - node := class(xlsxXml).GetNode(node_, k); + node := class(TSXml).GetNode(node_, k); if not ifObj(node) then return ''; - return class(xlsxXml).Utf8ToCurCodePage( node.GetText() ); + return class(TSXml).Utf8ToCurCodePage( node.GetText() ); End; Function propNode(k); @@ -11619,57 +12051,57 @@ private Function writeAuthor(v); Begin - return propNode('dc:creator').SetValue(class(xlsxXml).CurCodePageToUtf8(v)); + return propNode('dc:creator').SetValue(class(TSXml).CurCodePageToUtf8(v)); End; Function writeCategory(v); Begin - return propNode('cp:category').SetValue(class(xlsxXml).CurCodePageToUtf8(v)); + return propNode('cp:category').SetValue(class(TSXml).CurCodePageToUtf8(v)); End; Function writeDescription(v); Begin - return propNode('dc:description').SetValue(class(xlsxXml).CurCodePageToUtf8(v)); + return propNode('dc:description').SetValue(class(TSXml).CurCodePageToUtf8(v)); End; Function writeSubject(v); Begin - return propNode('dc:subject').SetValue(class(xlsxXml).CurCodePageToUtf8(v)); + return propNode('dc:subject').SetValue(class(TSXml).CurCodePageToUtf8(v)); End; Function writeTitle(v); Begin - return propNode('dc:title').SetValue(class(xlsxXml).CurCodePageToUtf8(v)); + return propNode('dc:title').SetValue(class(TSXml).CurCodePageToUtf8(v)); End; Function writeVersion(v); Begin - return propNode('cp:version').SetValue(class(xlsxXml).CurCodePageToUtf8(v)); + return propNode('cp:version').SetValue(class(TSXml).CurCodePageToUtf8(v)); End; Function writeRversion(v); Begin - return propNode('cp:rversion').SetValue(class(xlsxXml).CurCodePageToUtf8(v)); + return propNode('cp:rversion').SetValue(class(TSXml).CurCodePageToUtf8(v)); End; Function writeKeyWords(v); Begin - return propNode('cp:keywords').SetValue(class(xlsxXml).CurCodePageToUtf8(v)); + return propNode('cp:keywords').SetValue(class(TSXml).CurCodePageToUtf8(v)); End; Function writeLastModifiedBy(v); Begin - return propNode('cp:lastModifiedBy').SetValue(class(xlsxXml).CurCodePageToUtf8(v)); + return propNode('cp:lastModifiedBy').SetValue(class(TSXml).CurCodePageToUtf8(v)); End; Function writeCreated(v); Begin - return propNode('dcterms:created').SetValue(class(xlsxXml).GetDatetimeStr(v)); + return propNode('dcterms:created').SetValue(class(TSXml).GetDatetimeStr(v)); End; Function writeModified(v); Begin - return propNode('dcterms:modified').SetValue(class(xlsxXml).GetDatetimeStr(v)); + return propNode('dcterms:modified').SetValue(class(TSXml).GetDatetimeStr(v)); End; End; @@ -11710,7 +12142,7 @@ Type TDocxStyle = Class(TDocxStyleImpl) ///显示大纲级别 Function HeadingLevel(); Begin - node := class(xlsxXml).GetNode(node_, 'w:pPr/w:outlineLvl'); + node := class(TSXml).GetNode(node_, 'w:pPr/w:outlineLvl'); if ifObj(node) then return node.GetAttribute('w:val'); return ''; @@ -11720,7 +12152,7 @@ Type TDocxStyle = Class(TDocxStyleImpl) Begin if ifObj(pPr_) then return pPr_; - pPr_ := Class(xlsxXml).ReadPprFormat(node_); + pPr_ := Class(TSXml).ReadPprFormat(node_); return pPr_; End; @@ -11728,7 +12160,7 @@ Type TDocxStyle = Class(TDocxStyleImpl) Begin if ifObj(rPr_) then return rPr_; - rPr_ := Class(xlsxXml).ReadRprFormat(node_); + rPr_ := Class(TSXml).ReadRprFormat(node_); return rPr_; End; @@ -11737,14 +12169,14 @@ Type TDocxStyle = Class(TDocxStyleImpl) if ifObj(rPr_) then Begin arr := rPr_.Marshal(); if length(arr['attributes']) or length(arr['children']) then Begin - class(xlsxXml).UpdateNode(rPr_.Root(), arr['attributes'], arr['children']); + class(TSXml).UpdateNode(rPr_.Root(), arr['attributes'], arr['children']); End; End; if ifObj(pPr_) then Begin arr := pPr_.Marshal(); if length(arr['attributes']) or length(arr['children']) then Begin - class(xlsxXml).UpdateNode(pPr_.Root(), arr['attributes'], arr['children']); + class(TSXml).UpdateNode(pPr_.Root(), arr['attributes'], arr['children']); End; End; End; @@ -11774,7 +12206,7 @@ Type TNumStyle = Class(TNumStyleImpl) typeNode := node.FirstChildElement('w:multiLevelType'); if ifObj(typeNode) then multiLevelType := typeNode.GetAttribute('w:val'); - fmtNode := class(xlsxXml).GetNode(node, 'w:lvl/w:numFmt'); + fmtNode := class(TSXml).GetNode(node, 'w:lvl/w:numFmt'); if ifObj(fmtNode) then numFmt := fmtNode.GetAttribute('w:val'); End; @@ -11803,7 +12235,7 @@ Type TNumStyle = Class(TNumStyleImpl) startObj := node.FirstChildElement('w:start'); fmtObj := node.FirstChildElement('w:numFmt'); textObj := node.FirstChildElement('w:lvlText'); - start := ifObj(startObj) ? Class(xlsxXml).SafeStrToIntDef(startObj.GetAttribute('w:val'), 1) : 1; + start := ifObj(startObj) ? Class(TSXml).SafeStrToIntDef(startObj.GetAttribute('w:val'), 1) : 1; fmt := ifObj(fmtObj) ? fmtObj.GetAttribute('w:val') : ''; lvlText := ifObj(textObj) ? textObj.GetAttribute('w:val') : ''; levels_[length(levels_)] := array('node':node, 'text':lvlText, 'numFmt':fmt, 'start':start); diff --git a/funcext/TSOffice/TSDocxFile.tsf b/funcext/TSOffice/TSDocxFile.tsf index dcb976a..4279f8c 100644 --- a/funcext/TSOffice/TSDocxFile.tsf +++ b/funcext/TSOffice/TSDocxFile.tsf @@ -1,4 +1,4 @@ -// Version 1.0.5 +// Version 1.0.6 Type TSDocxFile = Class ///Version: V1.0 2022-09-20 @@ -27,8 +27,9 @@ Type TSDocxFile = Class Function init(); Begin + DocPrId_ := -1; zipfile_ := new ZipFile(); - xml_ := new xlsxXml(); + xml_ := new TSXml(); End; ///打开docx文件 @@ -94,7 +95,7 @@ Type TSDocxFile = Class ///返回TParagraph对象 Function AddParagraph(paragraph, posOpt, styleId); Begin - return document_.Body().AddParagraph(paragraph, posOpt, styleId); + return document_.Body().AddParagraph(paragraph, getPosNode(posOpt), styleId); End; ///添加标题 @@ -108,7 +109,7 @@ Type TSDocxFile = Class style := StyleObject().GetStyle(styleName); if not ifObj(style) and ifInt(level) and level >= 0 and level <= 9 then style := StyleObject().AddDefaultStyle(GetPath(), styleName); - return document_.Body().AddHeading(title, posOpt, ifObj(style) ? style.StyleId : nil); + return document_.Body().AddHeading(title, getPosNode(posOpt), ifObj(style) ? style.StyleId : nil); End; ///插入分页符 @@ -116,7 +117,7 @@ Type TSDocxFile = Class ///返回TParagraph对象 Function AddPageBreak(posOpt); Begin - return document_.Body().AddBreak(posOpt, 'page'); + return document_.Body().AddBreak(getPosNode(posOpt), 'page'); End; ///插入换行符 @@ -124,7 +125,7 @@ Type TSDocxFile = Class ///返回TParagraph对象 Function AddLineBreak(posOpt); Begin - return document_.Body().AddBreak(posOpt, ''); + return document_.Body().AddBreak(getPosNode(posOpt), ''); End; ///插入分栏符 @@ -132,7 +133,7 @@ Type TSDocxFile = Class ///返回TParagraph对象 Function AddColumnBreak(posOpt); Begin - return document_.Body().AddBreak(posOpt, 'column'); + return document_.Body().AddBreak(getPosNode(posOpt), 'column'); End; ///删除指定段落 @@ -140,7 +141,7 @@ Type TSDocxFile = Class ///返回:true Function DelParagraph(posOpt); Begin - return document_.Body().DelParagraph(posOpt); + return document_.Body().DelParagraph(getPosNode(posOpt)); End; ///word文档所有内容的文本串 @@ -150,8 +151,8 @@ Type TSDocxFile = Class return document_.Body().Text(); End; - ///word文档所有内容的文本串数组,包含段落信息 - ///返回:array(("pNode":nodeObj, "pIndex":p, "rNode":nodeObj, "rIndex":r)) + //word文档所有内容的文本串数组,包含段落信息 + //返回:array(("pNode":nodeObj, "pIndex":p, "rNode":nodeObj, "rIndex":r)) Function TextArray(); Begin return document_.Body().TextArray(); @@ -193,7 +194,7 @@ Type TSDocxFile = Class ///返回: TTable对象 Function InsertTable(tbl, posOpt); Begin - return document_.Body().InsertTable(tbl, posOpt); + return document_.Body().InsertTable(tbl, getPosNode(posOpt)); End; ///返回CoreProperties对象 @@ -225,7 +226,7 @@ Type TSDocxFile = Class ///返回:TDocSection对象 Function AddSection(session, posOpt);overload; Begin - return document_.Body().AddSection(session, posOpt); + return document_.Body().AddSection(session, getPosNode(posOpt)); End; ///插入图片 @@ -234,7 +235,8 @@ Type TSDocxFile = Class ///返回:TPicture对象 Function AddPicture(picture, posOpt); Begin - return document_.Body().AddPicture(picture, posOpt); + picture.Run.Drawing.WInline.ID := GetDocPrId(); + return document_.Body().AddPicture(picture, getPosNode(posOpt)); End; ///插入图表 @@ -246,9 +248,9 @@ Type TSDocxFile = Class o := new TDocxChart(self, chart); p := TOfficeObj('TParagraph'); p.Format.rPr.Lang := 'zh-CN'; - p := AddParagraph(p, posOpt, nil); - chart.ChartNode := p.node_; - p.Node.InsertEndChild(o.GetInnerXml()); + p := AddParagraph(p, getPosNode(posOpt), nil); + chart.pNode := p.node_; + p.Node().InsertEndChild(o.GetInnerXml()); return chart; End; @@ -260,7 +262,7 @@ Type TSDocxFile = Class uri := 'w:p/w:r/w:drawing/wp:inline/a:graphic/a:graphicData/c:chart'; ps := Paragraphs(); for i:=0 to length(ps)-1 do Begin - node := class(xlsxXml).GetNode(ps[i].node_, uri); + node := class(TSXml).GetNode(ps[i].node_, uri); if ifObj(node) then Begin chart := TOfficeObj('TChart'); chart.Init(self, ps[i].node_, node); @@ -289,11 +291,11 @@ Type TSDocxFile = Class '); rels := 'word/_rels/document.xml.rels'; xmlfile := zipfile_.Get(rels); - [rId, target] := class(xlsxXml).FindRelationshipRid(xmlfile, ''); + [rId, target] := class(TSXml).FindRelationshipRid(xmlfile, ''); rId ++; - class(xlsxXml).AddRelationshipRid(xmlfile, 'comments.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', 'rId' $ rId); + class(TSXml).AddRelationshipRid(xmlfile, 'comments.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', 'rId' $ rId); contentType := zipfile_.Get('[Content_Types].xml'); - class(xlsxXml).AddOverrideContentType(contentType, '/word/comments.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml'); + class(TSXml).AddOverrideContentType(contentType, '/word/comments.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml'); End xmlfile := zipfile_.Get(file); id := 0; @@ -307,35 +309,56 @@ Type TSDocxFile = Class c := TOfficeObj('TDocComment'); c.p.Run.SetText( txt ); c.Author := author; - if author and not class(xlsxXml).IsUtf8() then - c.Author := class(xlsxXml).CurCodePageToUtf8(author); + if author and not class(TSXml).IsUtf8() then + c.Author := class(TSXml).CurCodePageToUtf8(author); c.ID := id; xmlfile.FirstChildElement('w:comments').InsertEndChild(c.Marshal()); return c; End; - ///格式刷:复制段落格式(包括字体格式) + ///格式刷:段落格式 + 字体格式 ///fromParagraph:源段落 ///toParagraph:目标段落 Function CopyFormat(fromParagraph, toParagraph); Begin toParagraph.ClearFormat();//清除目标段落格式、字体格式 + CopyParagraphFormat(fromParagraph, toParagraph);//段落格式 + //字体格式 + if not ifObj(fromParagraph) then + return; + fromRun := fromParagraph.GetRun(0); + if ifObj(fromRun) then Begin + runs := toParagraph.GetRuns(); + for i:=0 to length(runs)-1 do Begin + runs[i].CopyFontFormat(fromRun); + End; + End; + End; + + ///格式刷:仅段落格式 + ///fromParagraph:源段落 + ///toParagraph:目标段落 + Function CopyParagraphFormat(fromParagraph, toParagraph); + Begin + pPr := toParagraph.node_.FirstChildElement('w:pPr'); + //清除段落格式 + if ifObj(pPr) then + toParagraph.node_.DeleteChild(pPr); pPr := ifObj(fromParagraph) ? fromParagraph.node_.FirstChildElement('w:pPr') : nil; if ifObj(pPr) then Begin //复制段落格式 - pPr2 := toParagraph.node_.InsertFirstChild('element', 'w:pPr'); arr := pPr.Marshal(); - class(xlsxXml).UpdateNode(pPr2, arr[0]['attributes'], arr[0]['children']); - End; - //复制字体格式 - rPr := ifObj(fromParagraph) ? class(xlsxXml).GetNode(fromParagraph.node_, 'w:r/w:rPr') : nil; - if ifObj(rPr) then Begin - r := rPr.Marshal(); - runs := toParagraph.GetRuns(); - for i:=0 to length(runs)-1 do - toParagraph._copyFormat(runs[i].node_, r, false); + toParagraph.node_.InsertFirstChild(arr[0]); End; End; + ///格式刷:仅字体格式 + ///fromRun:源段落 + ///toRun:目标段落 + Function CopyFontFormat(fromRun, toRun); + Begin + toRun.CopyFontFormat(fromRun); + End; + ///添加目录 ///[posOpt: 段落位置],在posOpt之后新添加目录(否则在首页添加) ///UpperHeadingLevel:标题最高级别 @@ -346,9 +369,7 @@ Type TSDocxFile = Class Begin content := new TTableContent(self); content.SetDefaultFormat(); //缺省目录格式 - node := posOpt; - if ifObj(posOpt) and not (posOpt is Class(XmlNode)) then - node := posOpt.Node(); + node := getPosNode(posOpt); content.Add(node, UpperHeadingLevel, LowerHeadingLevel); //标题级别 if ifObj(node) then content.node_ := document_.Body().node_.InsertAfterChild(node, content.Marshal()); @@ -389,6 +410,13 @@ Type TSDocxFile = Class return numberingObj_; End; + ///执行word文档内嵌tsl代码 + ///返回:[err,tslFuncCount,errArr]: err 执行错误TSL代码段次数,tslFuncCount TSL代码段总数,errArr 执行TSL错误信息(包括代码、错误信息) + Function ExecInnerTSL(); + Begin + return Body().ExecInnerTSL(self); + End; + Function ZipObject(); Begin return zipfile_; @@ -398,10 +426,40 @@ Type TSDocxFile = Class Begin return ExtractFileDir(ExtractFileDir(PluginPath())); End; + + Function GetDocPrId(); + Begin + if DocPrId_ < 0 then Begin + DocPrId_ := 0; + ps := Paragraphs(); + for i:=0 to length(ps)-1 do Begin + node := class(TSXml).GetNode(ps[i].node_, 'w:r/w:drawing/wp:inline/wp:docPr'); + if not ifObj(node) then + node := class(TSXml).GetNode(ps[i].node_, 'w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:docPr'); + if ifObj(node) then Begin + id := class(TSXml).SafeStrToIntDef(node.GetAttribute('id'), 0); + if id > DocPrId_ then + DocPrId_ := id; + break; + End; + End; + End; + DocPrId_ ++; + return DocPrId_; + End; +private + Function getPosNode(posOpt); + Begin + node := posOpt; + if ifObj(node) and not (node is Class(XmlNode)) then + node := node.Node(); + return node; + End; private zipfile_; //压缩文件对象 document_; //Document对象 - xml_; //xlsxXml对象 + xml_; //TSXml对象 styleObj_; numberingObj_; + DocPrId_; End; diff --git a/funcext/TSOffice/TSExcelFile.tsf b/funcext/TSOffice/TSExcelFile.tsf index e334ffb..e5536dd 100644 --- a/funcext/TSOffice/TSExcelFile.tsf +++ b/funcext/TSOffice/TSExcelFile.tsf @@ -1,4 +1,4 @@ -// Version 1.0.5 +// Version 1.0.6 Type TSExcelFile = Class ///Version: V1.0 2022-08-08 @@ -90,7 +90,7 @@ Type TSExcelFile = Class sheets := workbook_.GetSheets(); for i:=0 to length(sheets)-1 do begin - sheets[i] := class(xlsxXml).Utf8ToCurCodePage(sheets[i]); + sheets[i] := class(TSXml).Utf8ToCurCodePage(sheets[i]); end return sheets; End; @@ -108,30 +108,29 @@ Type TSExcelFile = Class Function GetSheetName(index); Begin name := workbook_.GetSheetName(index); - return class(xlsxXml).Utf8ToCurCodePage(name); + return class(TSXml).Utf8ToCurCodePage(name); End; ///创建新sheet ///sheet: string,工作表名称 Function NewSheet(sheet); Begin - return workbook_.NewSheet(class(xlsxXml).CurCodePageToUtf8(sheet)); + return workbook_.NewSheet(class(TSXml).CurCodePageToUtf8(sheet)); End; ///删除sheet ///sheet: string,工作表名称 Function DeleteSheet(sheet); Begin - return workbook_.DeleteSheet(class(xlsxXml).CurCodePageToUtf8(sheet)); + return workbook_.DeleteSheet(class(TSXml).CurCodePageToUtf8(sheet)); End; ///设置工作表名 ///sourceName: string, 原工作表名 ///destName: string,目标工作表名 - ///返回: [err, errinfo] Function SetSheetName(sourceName, destName); Begin - return workbook_.SetSheetName(class(xlsxXml).CurCodePageToUtf8(sourceName), class(xlsxXml).CurCodePageToUtf8(destName)); + return workbook_.SetSheetName(class(TSXml).CurCodePageToUtf8(sourceName), class(TSXml).CurCodePageToUtf8(destName)); End; ///获取总列数 @@ -139,7 +138,7 @@ Type TSExcelFile = Class ///返回: int Function TotalCols(sheet); Begin - return workbook_.TotalCols(class(xlsxXml).CurCodePageToUtf8(sheet)); + return workbook_.TotalCols(class(TSXml).CurCodePageToUtf8(sheet)); End; ///获取总行数 @@ -147,7 +146,7 @@ Type TSExcelFile = Class ///返回: int Function TotalRows(sheet); Begin - return workbook_.TotalRows(class(xlsxXml).CurCodePageToUtf8(sheet)); + return workbook_.TotalRows(class(TSXml).CurCodePageToUtf8(sheet)); End; ///获取单元格的值 @@ -156,8 +155,8 @@ Type TSExcelFile = Class ///返回: [err, value:string] Function GetCellValue(sheet, axis); Begin - [err, value] := workbook_.GetCellValue(class(xlsxXml).CurCodePageToUtf8(sheet), axis); - if not err then return array(err, class(xlsxXml).Utf8ToCurCodePage(value)); + [err, value] := workbook_.GetCellValue(class(TSXml).CurCodePageToUtf8(sheet), axis); + if not err then return array(err, class(TSXml).Utf8ToCurCodePage(value)); return array(err, value); End; @@ -173,8 +172,8 @@ Type TSExcelFile = Class /// 属性s:单元格样式 Function SetCellValue(sheet, axis, val, opt); Begin - sheet_name := class(xlsxXml).CurCodePageToUtf8(sheet); - value := class(xlsxXml).CurCodePageToUtf8(val); + sheet_name := class(TSXml).CurCodePageToUtf8(sheet); + value := class(TSXml).CurCodePageToUtf8(val); return workbook_.SetCellValue(sheet_name, axis, value, opt); End; @@ -184,9 +183,9 @@ Type TSExcelFile = Class ///返回: [err, richtxt:string],参见SetCellRichText Function GetCellRichText(sheet, axis); Begin - [err, str] := workbook_.GetCellRichText(class(xlsxXml).CurCodePageToUtf8(sheet), axis); + [err, str] := workbook_.GetCellRichText(class(TSXml).CurCodePageToUtf8(sheet), axis); if err then return array(err, str); - else return array(err, class(xlsxXml).Utf8ToCurCodePage(str)); + else return array(err, class(TSXml).Utf8ToCurCodePage(str)); End; ///设置富文本格式 @@ -195,13 +194,13 @@ Type TSExcelFile = Class ///richtext: string,xml串或富文本对象TSOfficeObj('TRichText') Function SetCellRichText(sheet, axis, richtext); Begin - o := workbook_.GetSheetObj(class(xlsxXml).CurCodePageToUtf8(sheet)); + o := workbook_.GetSheetObj(class(TSXml).CurCodePageToUtf8(sheet)); if ifObj(o) then begin xml := richtext; if ifObj(richtext) then - xml := class(xlsxXml).Dom2Xml(richtext.Marshal()); - return o.SetCellValue(axis, class(xlsxXml).CurCodePageToUtf8(xml), array('t':'s'), 'RichText'); + xml := class(TSXml).Dom2Xml(richtext.Marshal()); + return o.SetCellValue(axis, xml, array('t':'s'), 'RichText'); end End; @@ -214,7 +213,7 @@ Type TSExcelFile = Class /// 用法3:ClearCell('A5', 'D8'); //Clear矩形区间所有单元格 Function ClearCell(sheet, topLeft, bottomRight); Begin - return workbook_.ClearCell(class(xlsxXml).CurCodePageToUtf8(sheet), topLeft, bottomRight); + return workbook_.ClearCell(class(TSXml).CurCodePageToUtf8(sheet), topLeft, bottomRight); End; ///设置公式 @@ -223,7 +222,7 @@ Type TSExcelFile = Class ///formula: string,公式 Function SetCellFormula(sheet, axis, formula); Begin - return workbook_.SetCellFormula(class(xlsxXml).CurCodePageToUtf8(sheet), axis, formula); + return workbook_.SetCellFormula(class(TSXml).CurCodePageToUtf8(sheet), axis, formula); End; ///获取公式 @@ -232,7 +231,7 @@ Type TSExcelFile = Class ///返回: [err, formula:string] Function GetCellFormula(sheet, axis); Begin - return workbook_.GetCellFormula(class(xlsxXml).CurCodePageToUtf8(sheet), axis); + return workbook_.GetCellFormula(class(TSXml).CurCodePageToUtf8(sheet), axis); End; ///按行赋值 @@ -305,7 +304,7 @@ Type TSExcelFile = Class ///返回: table Function GetTable(sheet, topLeft, bottomRight); Begin - return workbook_.GetTable(class(xlsxXml).CurCodePageToUtf8(sheet), topLeft, bottomRight); + return workbook_.GetTable(class(TSXml).CurCodePageToUtf8(sheet), topLeft, bottomRight); End; ///插入列,在指定列前插入空白列 @@ -313,7 +312,7 @@ Type TSExcelFile = Class ///col: string 列名,如: "D" Function InsertCol(sheet, col); Begin - return workbook_.InsertCol(class(xlsxXml).CurCodePageToUtf8(sheet), col); + return workbook_.InsertCol(class(TSXml).CurCodePageToUtf8(sheet), col); End; ///插入行,在指定行前插入空白行 @@ -321,7 +320,7 @@ Type TSExcelFile = Class ///row: int Function InsertRow(sheet, row); Begin - return workbook_.InsertRow(class(xlsxXml).CurCodePageToUtf8(sheet), row); + return workbook_.InsertRow(class(TSXml).CurCodePageToUtf8(sheet), row); End; ///删除列 @@ -329,7 +328,7 @@ Type TSExcelFile = Class ///col: string,如: "D" Function RemoveCol(sheet, col); Begin - return workbook_.RemoveCol(class(xlsxXml).CurCodePageToUtf8(sheet), col); + return workbook_.RemoveCol(class(TSXml).CurCodePageToUtf8(sheet), col); End; ///删除行 @@ -337,7 +336,7 @@ Type TSExcelFile = Class ///row: int Function RemoveRow(sheet, row); Begin - return workbook_.RemoveRow(class(xlsxXml).CurCodePageToUtf8(sheet), row); + return workbook_.RemoveRow(class(TSXml).CurCodePageToUtf8(sheet), row); End; ///设置行高度 @@ -346,7 +345,7 @@ Type TSExcelFile = Class ///height: double,行高[0-409] Function SetRowHeight(sheet, row, height); Begin - return workbook_.SetRowHeight(class(xlsxXml).CurCodePageToUtf8(sheet), row, height); + return workbook_.SetRowHeight(class(TSXml).CurCodePageToUtf8(sheet), row, height); End; ///获取行高度 @@ -355,7 +354,7 @@ Type TSExcelFile = Class ///返回: double Function GetRowHeight(sheet, row); Begin - return workbook_.GetRowHeight(class(xlsxXml).CurCodePageToUtf8(sheet), row); + return workbook_.GetRowHeight(class(TSXml).CurCodePageToUtf8(sheet), row); End; ///设置列宽度 @@ -365,7 +364,7 @@ Type TSExcelFile = Class ///width: double,列宽[0-255] Function SetColWidth(sheet, startCol, endCol, width); Begin - return workbook_.SetColWidth(class(xlsxXml).CurCodePageToUtf8(sheet), startCol, endCol, width); + return workbook_.SetColWidth(class(TSXml).CurCodePageToUtf8(sheet), startCol, endCol, width); End; ///获取列宽度 @@ -374,7 +373,7 @@ Type TSExcelFile = Class ///返回: double Function GetColWidth(sheet, col); Begin - return workbook_.GetColWidth(class(xlsxXml).CurCodePageToUtf8(sheet), col); + return workbook_.GetColWidth(class(TSXml).CurCodePageToUtf8(sheet), col); End; ///设置工作表默认列宽 @@ -382,7 +381,7 @@ Type TSExcelFile = Class ///width: double Function SetSheetDefaultColWidth(sheet, width); Begin - return workbook_.SetSheetDefaultColWidth(class(xlsxXml).CurCodePageToUtf8(sheet), width); + return workbook_.SetSheetDefaultColWidth(class(TSXml).CurCodePageToUtf8(sheet), width); End; ///获取工作表默认列宽 @@ -390,7 +389,7 @@ Type TSExcelFile = Class ///返回: double Function GetSheetDefaultColWidth(sheet); Begin - return workbook_.GetSheetDefaultColWidth(class(xlsxXml).CurCodePageToUtf8(sheet)); + return workbook_.GetSheetDefaultColWidth(class(TSXml).CurCodePageToUtf8(sheet)); End; ///添加批注 @@ -419,7 +418,7 @@ Type TSExcelFile = Class ///返回: [err, ChartList] Function GetCharts(sheet); Begin - return workbook_.GetCharts(class(xlsxXml).CurCodePageToUtf8(sheet)); + return workbook_.GetCharts(class(TSXml).CurCodePageToUtf8(sheet)); End; ///单元格坐标切分 @@ -500,7 +499,7 @@ Type TSExcelFile = Class ///styleid: string,样式Id Function SetCellStyle(sheet, topLeft, bottomRight, styleid); Begin - return workbook_.SetCellStyle(class(xlsxXml).CurCodePageToUtf8(sheet), topLeft, bottomRight, styleid); + return workbook_.SetCellStyle(class(TSXml).CurCodePageToUtf8(sheet), topLeft, bottomRight, styleid); End; ///获取单元格样式Id,获取到的Id可以在复制单元格样式时,作为调用 SetCellValue、或SetCellStyle 函数的参数使用。 @@ -509,7 +508,7 @@ Type TSExcelFile = Class ///返回: styleId: string Function GetCellStyle(sheet, axis); Begin - return workbook_.GetCellStyle(class(xlsxXml).CurCodePageToUtf8(sheet), axis); + return workbook_.GetCellStyle(class(TSXml).CurCodePageToUtf8(sheet), axis); End; ///设置工作表页眉页脚 @@ -526,7 +525,7 @@ Type TSExcelFile = Class ///visible: boolean Function SetSheetVisible(sheet, visible); Begin - return workbook_.SetSheetVisible(class(xlsxXml).CurCodePageToUtf8(sheet), visible); + return workbook_.SetSheetVisible(class(TSXml).CurCodePageToUtf8(sheet), visible); End; ///获取工作表可见性 @@ -534,7 +533,7 @@ Type TSExcelFile = Class ///visibility: boolean Function GetSheetVisible(sheet); Begin - return workbook_.GetSheetVisible(class(xlsxXml).CurCodePageToUtf8(sheet)); + return workbook_.GetSheetVisible(class(TSXml).CurCodePageToUtf8(sheet)); End; ///设置行可见性 @@ -543,7 +542,7 @@ Type TSExcelFile = Class ///visible: boolean Function SetRowVisible(sheet, row, visible) Begin - return workbook_.SetRowVisible(class(xlsxXml).CurCodePageToUtf8(sheet), row, visible); + return workbook_.SetRowVisible(class(TSXml).CurCodePageToUtf8(sheet), row, visible); End; ///获取工作表行可见性 @@ -552,7 +551,7 @@ Type TSExcelFile = Class ///返回: [err, visible:boolean] Function GetRowVisble(sheet, row); Begin - return workbook_.GetRowVisble(class(xlsxXml).CurCodePageToUtf8(sheet), row); + return workbook_.GetRowVisble(class(TSXml).CurCodePageToUtf8(sheet), row); End; ///设置列可见性 @@ -563,7 +562,7 @@ Type TSExcelFile = Class Begin [err, col] := ColumnNameToNumber(col); if err then return "Col error."; - return workbook_.SetColVisible(class(xlsxXml).CurCodePageToUtf8(sheet), col, visible); + return workbook_.SetColVisible(class(TSXml).CurCodePageToUtf8(sheet), col, visible); End; ///获取列可见性 @@ -574,7 +573,7 @@ Type TSExcelFile = Class Begin [err, col] := ColumnNameToNumber(col); if err then return array(-1, col); - return workbook_.GetColVisble(class(xlsxXml).CurCodePageToUtf8(sheet), col); + return workbook_.GetColVisble(class(TSXml).CurCodePageToUtf8(sheet), col); End; ///设置工作表页边距 @@ -602,7 +601,7 @@ Type TSExcelFile = Class ///vcell: string,右下角坐标 Function MergeCell(sheet, hcell, vcell); Begin - return workbook_.MergeCell(class(xlsxXml).CurCodePageToUtf8(sheet), hcell, vcell); + return workbook_.MergeCell(class(TSXml).CurCodePageToUtf8(sheet), hcell, vcell); End; ///取消合并单元格 @@ -611,7 +610,7 @@ Type TSExcelFile = Class ///vcell: string,右下角坐标 Function UnMergeCell(sheet, hcell, vcell); Begin - return workbook_.UnMergeCell(class(xlsxXml).CurCodePageToUtf8(sheet), hcell, vcell); + return workbook_.UnMergeCell(class(TSXml).CurCodePageToUtf8(sheet), hcell, vcell); End; ///设置工作表视图属性 @@ -641,7 +640,7 @@ Type TSExcelFile = Class Function SetPageLayout(sheet, pageLayout); Begin o := getOj(sheet, 'xlsxPageLayout'); - if ifObj(o) then return o.SetPageLayout(class(xlsxXml).CurCodePageToUtf8(sheet), pageLayout); + if ifObj(o) then return o.SetPageLayout(class(TSXml).CurCodePageToUtf8(sheet), pageLayout); End; ///获取工作表页面设置 @@ -657,7 +656,7 @@ Type TSExcelFile = Class ///sheet: string,工作表名称 Function SetDefaultSheet(sheet); Begin - return workbook_.SetDefaultSheet(class(xlsxXml).CurCodePageToUtf8(sheet)); + return workbook_.SetDefaultSheet(class(TSXml).CurCodePageToUtf8(sheet)); End; ///获取默认工作表 @@ -665,7 +664,7 @@ Type TSExcelFile = Class Function GetDefaultSheet(); Begin sheet := workbook_.GetDefaultSheet(); - return class(xlsxXml).Utf8ToCurCodePage(sheet); + return class(TSXml).Utf8ToCurCodePage(sheet); End; ///设置超链接 @@ -737,7 +736,7 @@ Type TSExcelFile = Class ///row: int,行号 Function InsertPageBreak(sheet, row); Begin - return workbook_.InsertPageBreak(class(xlsxXml).CurCodePageToUtf8(sheet), row); + return workbook_.InsertPageBreak(class(TSXml).CurCodePageToUtf8(sheet), row); End; ///删除指定行分页符 @@ -745,7 +744,7 @@ Type TSExcelFile = Class ///row: int,行号 Function RemovePageBreak(sheet, row); Begin - return workbook_.RemovePageBreak(class(xlsxXml).CurCodePageToUtf8(sheet), row); + return workbook_.RemovePageBreak(class(TSXml).CurCodePageToUtf8(sheet), row); End; ///添加形状 @@ -805,7 +804,7 @@ Type TSExcelFile = Class private Function getOj(sheet, objname); Begin - sheetname := class(xlsxXml).CurCodePageToUtf8(sheet); + sheetname := class(TSXml).CurCodePageToUtf8(sheet); if not ifarray(objMgr_) then objMgr_:= array(); k := sheetname + '.' + objname; o := objMgr_[ k ]; diff --git a/funcext/TSOffice/TSUtils/NodeInfo.tsf b/funcext/TSOffice/TSUtils/NodeInfo.tsf index 9a40686..23abb26 100644 --- a/funcext/TSOffice/TSUtils/NodeInfo.tsf +++ b/funcext/TSOffice/TSUtils/NodeInfo.tsf @@ -20,7 +20,7 @@ public if ifObj(RootObj) then Begin arr := Marshal(); if length(arr['attributes']) or length(arr['children']) then Begin - class(xlsxXml).UpdateNode(RootObj, arr['attributes'], arr['children']); + class(TSXml).UpdateNode(RootObj, arr['attributes'], arr['children']); End; End; End; @@ -166,7 +166,7 @@ public lName := lowerCase(name); r := sselect * from attrs where lName = lowerCase([0]) end; if istable(r) then Begin - node := class(xlsxXml).GetNode(rootNode, uri); + node := class(TSXml).GetNode(rootNode, uri); if not ifObj(node) then return nil; return node.GetAttribute(r[1]); End; @@ -176,7 +176,7 @@ public if istable(r) then Begin r := r[0]; uri := (uri='' ? '' : uri + '/') + r['name']; - node := class(xlsxXml).GetNode(rootNode, uri); + node := class(TSXml).GetNode(rootNode, uri); if not ifObj(node) then return nil; if r['nodeType'] = 'empty' then return true; diff --git a/funcext/TSOffice/TSUtils/TOfficeApi.tsf b/funcext/TSOffice/TSUtils/TOfficeApi.tsf new file mode 100644 index 0000000..222b8fe --- /dev/null +++ b/funcext/TSOffice/TSUtils/TOfficeApi.tsf @@ -0,0 +1,194 @@ +Function TOfficeApi(); +Begin + if not ifObj(sysparams['TOffice sys api']) then + sysparams['TOffice sys api'] := new TOffice(); + return sysparams['TOffice sys api']; +End; + +Type TOffice = Class + Function Create(); + Begin + hash_ := array(); + End; + + ///检测当前环境字符集 + ///调用规范:TOfficeApi().CodePage('中文'); + Function CodePage(zw); + Begin + cp := 'utf8';//默认环境为UTF8格式 + str := StrToBase64(zw); + case str of + '1tDOxA==': + cp := 'gbk'; + '5Lit5paH': + cp := 'utf8'; + 'pKSk5Q==': + cp := 'big5'; + End; + hash_['CodePage'] := cp; + End; + + ///当前环境是否UTF8 + Function IsUtf8(); + Begin + if ifnil(hash_['CodePage']) or hash_['CodePage'] = 'utf8' then + return true; + return false; + End; + + ///获得当前文档对象:TDocxFile对象 + Function GetDocument(); + Begin + return hash_['Docx']; + End; + + ///设置当前段落标签 + ///name:string 标签名称 + Function SetParagraphTag(name); + Begin + hash_['Paragraph-Node-' + name] := hash_['CurrentParagraph']; + End; + + ///获取当前TSL代码段所在段落 + ///返回:TParagraph对象 + Function GetCurrentParagraph(); + Begin + node := hash_['CurrentParagraph']; + if not ifObj(node) then + return nil; + p := TOfficeObj('TParagraph'); + p.Init(node); + return p; + End; + + ///获取当前TSL代码段所在段落的w:r元素 + ///返回:TRun对象 + Function GetCurrentRun(); + Begin + node := hash_['CurrentRun']; + if not ifObj(node) then + return nil; + p := TOfficeObj('TRun'); + p.Init(node); + return p; + End; + + ///获取指定标签段落 + ///name:string 标签名称 + ///返回:TParagraph对象 + Function GetParagraph(name); + Begin + node := hash_['Paragraph-Node-' + name]; + if not ifObj(node) then + return nil; + p := TOfficeObj('TParagraph'); + p.Init(node); + return p; + End; + + ///获取当前TSL代码段上一个表格 + ///[p]:可选参数,为Nil指当前段落 + ///返回:TTable对象 + Function GetPrevTable(p); + Begin + return getTableImpl(p, false); + End; + + ///获取当前TSL代码段下一个表格 + ///[p]:可选参数,为Nil指当前段落 + ///返回:TTable对象 + Function GetNextTable(p); + Begin + return getTableImpl(p, true); + End; + + ///获取当前TSL代码段上一张图片 + ///[p]:可选参数,为Nil指当前段落 + ///返回:TPicture对象 + Function GetPrevPicture(p); + Begin + return getPictureImpl(p, false); + End; + + ///获取当前TSL代码段下一张图片 + ///[p]:可选参数,为Nil指当前段落 + ///返回:TPicture对象 + Function GetNextPicture(p); + Begin + return getPictureImpl(p, true); + End; + + ///获取当前TSL代码段上一个Chart图 + ///[p]:可选参数,为Nil指当前段落 + ///返回:TChart对象 + Function GetPrevChart(p); + Begin + return getChartImpl(p, false); + End; + + ///获取当前TSL代码段下一个Chart图 + ///[p]:可选参数,为Nil指当前段落 + ///返回:TChart对象 + Function GetNextChart(p); + Begin + return getChartImpl(p, true); + End; + + Function Set(k, v); + Begin + hash_[k] := v; + End; + + Function Get(k); + Begin + return hash_[k]; + End; +private + Function getTableImpl(p, next); + Begin + if not ifObj(p) then + p := GetCurrentParagraph(); + node := next ? p.node_.NextElement('w:tbl') : p.node_.PrevElement('w:tbl'); + if not ifObj(node) then + return nil; + tbl := TOfficeObj('TTable'); + tbl.Init(node); + return tbl; + End; + + Function getPictureImpl(p, next); + Begin + if not ifObj(p) then + p := GetCurrentParagraph(); + node := next ? p.node_.NextElement('w:p') : p.node_.PrevElement('w:p'); + while ifObj(node) do Begin + draw := class(TSXml).GetNode(node, 'w:r/w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic'); + if ifObj(draw) then Begin + p := TOfficeObj('TPicture'); + p.Init(node); + return p; + End; + node := next ? p.node.NextElement('w:p') : p.node.PrevElement('w:p'); + End; + return nil; + End; + + Function getChartImpl(p, next); + Begin + if not ifObj(p) then + p := GetCurrentParagraph(); + node := next ? p.node_.NextElement('w:p') : p.node_.PrevElement('w:p'); + while ifObj(node) do Begin + chartNode := class(TSXml).GetNode(node, 'w:r/w:drawing/wp:inline/a:graphic/a:graphicData/c:chart'); + if ifObj(chartNode) then Begin + p := TOfficeObj('TChart'); + p.Init(hash_['Docx'], node, chartNode); + return p; + End; + node := next ? p.node.NextElement('w:p') : p.node.PrevElement('w:p'); + End; + return nil; + End; + + hash_; +End; \ No newline at end of file diff --git a/funcext/TSOffice/TSUtils/TSChart.tsf b/funcext/TSOffice/TSUtils/TSChart.tsf index ce07197..bf61f9e 100644 --- a/funcext/TSOffice/TSUtils/TSChart.tsf +++ b/funcext/TSOffice/TSUtils/TSChart.tsf @@ -103,7 +103,7 @@ Type TSChart = Class Function Apply(xmlObj); Begin chartData_.Serialize(IsWord()); //初始化图表数据 - task := array(('c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:t', 'pcdata', class(xlsxXml).CurCodePageToUtf8(chartData_.Title)), + task := array(('c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:t', 'pcdata', class(TSXml).CurCodePageToUtf8(chartData_.Title)), ('c:chartSpace/c:chart/c:plotVisOnly', 'val', chartData_.plotVisOnly), ('c:chartSpace/c:chart/c:dispBlanksAs', 'val', chartData_.ShowBlanksAs), ('c:chartSpace/c:chart/c:legend', 'Del', ifnil(chartData_.Legend)), @@ -111,16 +111,16 @@ Type TSChart = Class ('c:chartSpace/c:chart/c:view3D', 'unmarshal', getview3D().Marshal()) ); for i:=0 to length(task)-1 do Begin - class(xlsxXml).SetNodeValue(xmlObj, task[i]); + class(TSXml).SetNodeValue(xmlObj, task[i]); End; if ifObj(chartData_.Legend) then Begin - node := class(xlsxXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:legend'); + node := class(TSXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:legend'); if ifObj(node) then Begin arr := chartData_.Legend.Marshal(); - class(xlsxXml).UpdateNode(node, arr['attributes'], arr['children']); + class(TSXml).UpdateNode(node, arr['attributes'], arr['children']); End; End; - chartData_.ChartNode := class(xlsxXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:plotArea'); + chartData_.plotAreaNode := class(TSXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:plotArea'); if chartData_.DataTable then chartData_.ShowDataTable(true); End; diff --git a/funcext/TSOffice/TSUtils/xlsxXml.tsf b/funcext/TSOffice/TSUtils/TSXml.tsf similarity index 97% rename from funcext/TSOffice/TSUtils/xlsxXml.tsf rename to funcext/TSOffice/TSUtils/TSXml.tsf index 9dd9706..ed5730f 100644 --- a/funcext/TSOffice/TSUtils/xlsxXml.tsf +++ b/funcext/TSOffice/TSUtils/TSXml.tsf @@ -1,4 +1,4 @@ -Type xlsxXml = Class +Type TSXml = Class class Function XmlHeader(); Begin return ' \n'; @@ -28,14 +28,14 @@ Type xlsxXml = Class class Function GetFileName(key); Begin - map := class(xlsxXml).GetMap(); + map := class(TSXml).GetMap(); if ifarray(map[key]) then return map[key]['FileName']; return ''; End; class Function GetTemplate(key); Begin - map := class(xlsxXml).GetMap(); + map := class(TSXml).GetMap(); if ifarray(map[key]) then return map[key]['Template']; return ''; End; @@ -106,7 +106,7 @@ Type xlsxXml = Class if children[i]['type'] = 'pcdata' then child.SetValue(children[i]['value']); else - class(xlsxXml).UpdateNode(child, children[i]['attributes'], children[i]['children']); + class(TSXml).UpdateNode(child, children[i]['attributes'], children[i]['children']); End; End; @@ -166,7 +166,7 @@ Type xlsxXml = Class End; node := node.NextElement(); End; - return array(rID, findtarget); + return array(rID, findtarget, i); End; class Function FindRelationship(xmlfile, rid); @@ -180,6 +180,14 @@ Type xlsxXml = Class return nil; End; + class Function FindRelationshipTarget(xmlfile, rid); + Begin + node := class(TSXml).FindRelationship(xmlfile, rid); + if ifObj(node) then + return node.GetAttribute('Target'); + return nil; + End; + class Function AddRelationshipRid(xmlfile, target, type, rid, targetMode); Begin node := xmlfile.FirstChildElement('Relationships').InsertEndChild('element', 'Relationship'); @@ -306,36 +314,24 @@ Type xlsxXml = Class class Function CodePage(zw); Begin - cp := 'utf8';//默认环境为UTF8格式 - str := StrToBase64(zw); - case str of - '1tDOxA==': - cp := 'gbk'; - '5Lit5paH': - cp := 'utf8'; - 'pKSk5Q==': - cp := 'big5'; - End; - sysparams['CodePage'] := cp; + TOfficeApi().CodePage(zw); End; class Function IsUtf8(); Begin - if ifnil(sysparams['CodePage']) or sysparams['CodePage'] = 'utf8' then - return true; - return false; + return TOfficeApi().IsUtf8(); End; class Function Utf8ToCurCodePage(str); Begin - if ifstring(str) and not class(xlsxXml).IsUtf8() then + if ifstring(str) and not class(TSXml).IsUtf8() then return UTF8ToAnsi(str); return str; End; class Function CurCodePageToUtf8(str); Begin - if ifstring(str) and not class(xlsxXml).IsUtf8() then + if ifstring(str) and not class(TSXml).IsUtf8() then return AnsiToUTF8(str); return str; End; diff --git a/funcext/TSOffice/document/TDocxChart.tsf b/funcext/TSOffice/document/TDocxChart.tsf index a4802e6..3715ac5 100644 --- a/funcext/TSOffice/document/TDocxChart.tsf +++ b/funcext/TSOffice/document/TDocxChart.tsf @@ -2,23 +2,28 @@ Type TDocxChart = Class(TSChart) ///缺省构造函数 Function Create(docx, chartData); overload; Begin + docx_ := docx; class(TSChart).Create(chartData); //chartN.xml chartId_ := 1 + vselect countof( ['FileName'] ) from docx.ZipObject().Files() where AnsiStartsText('word/charts/chart', ['FileName']) end; - chartFile := 'word/charts/chart' $ chartId_ $ '.xml'; + targetFileName := 'charts/chart' $ chartId_ $ '.xml'; + chartFile := 'word/' + targetFileName; docx.ZipObject().Add(chartFile, GetDefaultXml()); - xmlObj := docx.ZipObject().Get(chartFile); - Apply(xmlObj); + xmlObj_ := docx.ZipObject().Get(chartFile); + if not chartData_.DisableExcel and istable(chartData.Series) and istable(chartData.Series[0]['Categories']) and istable(chartData.Series[0]['Values']) then Begin + //chartData_.NewExcelFile(); + End; + Apply(xmlObj_); + addExternalData(); //Relationship relsObj := docx.ZipObject().Get('word/_rels/document.xml.rels'); - [rId_, target] := class(xlsxXml).FindRelationshipRid(relsObj, ''); + [rId_, target] := class(TSXml).FindRelationshipRid(relsObj, ''); rId_ ++; - class(xlsxXml).AddRelationshipRid(relsObj, '/' + chartFile, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' $ rId_); - + class(TSXml).AddRelationshipRid(relsObj, targetFileName, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' $ rId_); //Content_Types contentType := docx.ZipObject().Get('[Content_Types].xml'); - class(xlsxXml).AddOverrideContentType(contentType, '/' + chartFile, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'); + class(TSXml).AddOverrideContentType(contentType, '/' + chartFile, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'); End; Function GetInnerXml(); @@ -33,12 +38,12 @@ Type TDocxChart = Class(TSChart) - + - ', integer(chartData_.Width * ETU), integer(chartData_.Height * ETU), chartId_, class(xlsxXml).CurCodePageToUtf8(chartData_.Name), rId_); + ', integer(chartData_.Width * ETU), integer(chartData_.Height * ETU), docx_.GetDocPrId(), class(TSXml).CurCodePageToUtf8(chartData_.Name), rId_); End; Function IsWord();override; @@ -46,6 +51,33 @@ Type TDocxChart = Class(TSChart) return true; End; + Function addExternalData(); + Begin + //内嵌excel数据文件 + if not ifObj(chartData_.Excel) then + return; + [err, data] := chartData_.Excel.Zip().Save2Mem(); + if err then + return; + xmlObj_.FirstChildElement('c:chartSpace').InsertEndChild(''); + rels := 'word/charts/_rels/chart' $ chartId_ $ '.xml.rels'; + xmlStr := ' + + +'; + fileCnt := 1 + vselect countof( ['FileName'] ) from docx_.ZipObject().Files() where AnsiStartsText('word/embeddings/Workbook', ['FileName']) end; + workBook := 'embeddings/Workbook' $ fileCnt $ '.xlsx'; + docx_.ZipObject().Add(rels, xmlStr); + if fileCnt > 1 then Begin + relsObj := docx_.ZipObject().Get(rels); + node := relsObj.FirstChildElement('Relationships').FirstChildElement('Relationship'); + node.SetAttribute('Target', '../' + workBook); + End; + docx_.ZipObject().Add('word/' + workBook, data); + End; + + docx_; chartId_; rId_; + xmlObj_; End; \ No newline at end of file diff --git a/funcext/TSOffice/document/TDocxStyles.tsf b/funcext/TSOffice/document/TDocxStyles.tsf index 34d476c..33ec222 100644 --- a/funcext/TSOffice/document/TDocxStyles.tsf +++ b/funcext/TSOffice/document/TDocxStyles.tsf @@ -21,13 +21,13 @@ Type TDocxStyles = Class _addStyle(o); node := node.NextElement('w:style'); End; - pNode := class(xlsxXml).GetNode(stylesNode, 'w:docDefaults/w:pPrDefault'); + pNode := class(TSXml).GetNode(stylesNode, 'w:docDefaults/w:pPrDefault'); if ifObj(pNode) then - defaultPpr_ := Class(xlsxXml).ReadPprFormat(pNode); + defaultPpr_ := Class(TSXml).ReadPprFormat(pNode); - rNode := class(xlsxXml).GetNode(stylesNode, 'w:docDefaults/w:rPrDefault'); + rNode := class(TSXml).GetNode(stylesNode, 'w:docDefaults/w:rPrDefault'); if ifObj(rNode) then - defaultRpr_ := Class(xlsxXml).ReadRprFormat(rNode); + defaultRpr_ := Class(TSXml).ReadRprFormat(rNode); End; End; End; diff --git a/funcext/TSOffice/document/TNumbering.tsf b/funcext/TSOffice/document/TNumbering.tsf index 95d97f1..a2ed407 100644 --- a/funcext/TSOffice/document/TNumbering.tsf +++ b/funcext/TSOffice/document/TNumbering.tsf @@ -14,11 +14,11 @@ Type TNumbering = Class docx.ZipObject().Add('word/numbering.xml', xmlData); rels := 'word/_rels/document.xml.rels'; relsObj := docx.ZipObject().Get(rels); - [rId, target] := class(xlsxXml).FindRelationshipRid(relsObj, ''); + [rId, target] := class(TSXml).FindRelationshipRid(relsObj, ''); rId ++; - class(xlsxXml).AddRelationshipRid(relsObj, 'numbering.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering', 'rId' $ rId); + class(TSXml).AddRelationshipRid(relsObj, 'numbering.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering', 'rId' $ rId); contentType := docx.ZipObject().Get('[Content_Types].xml'); - class(xlsxXml).AddOverrideContentType(contentType, '/word/numbering.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml'); + class(TSXml).AddOverrideContentType(contentType, '/word/numbering.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml'); numberingXml_ := docx.ZipObject().Get('word/numbering.xml'); End; End; @@ -216,7 +216,7 @@ Type TNumbering = Class o.nsid := id; o.tmpl := id; arr := o.Marshal(); - class(xlsxXml).UpdateNode(o.node_, arr['attributes'], arr['children']); + class(TSXml).UpdateNode(o.node_, arr['attributes'], arr['children']); End; private docx_; diff --git a/funcext/TSOffice/document/TTableContent.tsf b/funcext/TSOffice/document/TTableContent.tsf index 1afc2fb..dfabac7 100644 --- a/funcext/TSOffice/document/TTableContent.tsf +++ b/funcext/TSOffice/document/TTableContent.tsf @@ -13,7 +13,7 @@ Type TTableContent = class //_CheckNodes('endnotes.xml'); //_CheckNodes('footnotes.xml'); //contentType := docx.ZipObject().Get('[Content_Types].xml'); - //class(xlsxXml).AddOverrideContentType(contentType, 'wmf', 'image/x-wmf'); + //class(TSXml).AddOverrideContentType(contentType, 'wmf', 'image/x-wmf'); End; Function SetDefaultFormat(); @@ -43,7 +43,7 @@ Type TTableContent = class Function Apply(); override; Begin arr := impl_.Marshal(); - class(xlsxXml).UpdateNode(node_, arr['attributes'], arr['children']); + class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']); End; ///添加目录条目 @@ -287,18 +287,18 @@ Type TTableContent = class z.Add('word/' + name, xmlData); rels := 'word/_rels/document.xml.rels'; relsObj := z.Get(rels); - [rId, target] := class(xlsxXml).FindRelationshipRid(relsObj, ''); + [rId, target] := class(TSXml).FindRelationshipRid(relsObj, ''); rId ++; if name = 'endnotes.xml' then Begin - class(xlsxXml).AddRelationshipRid(relsObj, name, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes', 'rId' $ rId); + class(TSXml).AddRelationshipRid(relsObj, name, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes', 'rId' $ rId); contentType := z.Get('[Content_Types].xml'); - class(xlsxXml).AddOverrideContentType(contentType, '/word/' + name, 'application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml'); + class(TSXml).AddOverrideContentType(contentType, '/word/' + name, 'application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml'); End else if name = 'footnotes.xml' then Begin - class(xlsxXml).AddRelationshipRid(relsObj, name, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes', 'rId' $ rId); + class(TSXml).AddRelationshipRid(relsObj, name, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes', 'rId' $ rId); contentType := z.Get('[Content_Types].xml'); - class(xlsxXml).AddOverrideContentType(contentType, '/word/' + name, 'application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml'); + class(TSXml).AddOverrideContentType(contentType, '/word/' + name, 'application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml'); End; End; End; diff --git a/funcext/TSOffice/template/faq.txt b/funcext/TSOffice/template/faq.txt index 1a39c0a..f1ec09f 100644 --- a/funcext/TSOffice/template/faq.txt +++ b/funcext/TSOffice/template/faq.txt @@ -36,7 +36,7 @@ Apply()函数可以修改属性值,例如: *如何设置字符集(中文支持)? ★用户的脚本可能是UFT8格式,或可能是GBK码格式,系统提供API自动设置当前字符集环境: - class(xlsxXml).CodePage('中文'); //系统检测当前的环境字符集 + TOfficeApi().CodePage('中文'); //系统检测当前的环境字符集 ... p.Run.SetText('系统可以自动识别这里的中文字符集(utf8或gbk)!'); ★不设置,默认当前字符集为UTF8 diff --git a/funcext/TSOffice/worksheet/xlsxChart.tsf b/funcext/TSOffice/worksheet/xlsxChart.tsf index 88dd19e..3460e9b 100644 --- a/funcext/TSOffice/worksheet/xlsxChart.tsf +++ b/funcext/TSOffice/worksheet/xlsxChart.tsf @@ -8,12 +8,12 @@ Type xlsxChart = Class(TSChart) drawingRID_ := excel_.WorkBook().GetSheetDrawing(sheet); drawingXmlObj_ := excel_.WorkBook().GetXmlFileObj('xl/drawings/drawing' $ drawingRID_ $ '.xml'); drawingRelsObj := excel_.WorkBook().GetDrawingRelsFile(drawingRID_); - [chartRid_, find] := class(xlsxXml).FindRelationshipRid(drawingRelsObj, ''); + [chartRid_, find] := class(TSXml).FindRelationshipRid(drawingRelsObj, ''); chartRid_ ++; - class(xlsxXml).AddRelationshipRid(drawingRelsObj, '../charts/chart'+inttostr(chartId_)+'.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' + inttostr(chartRid_)); + class(TSXml).AddRelationshipRid(drawingRelsObj, '../charts/chart'+inttostr(chartId_)+'.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' + inttostr(chartRid_)); xlChartFileName_ := 'xl/charts/chart'+inttostr(chartId_)+'.xml'; - content_xml := excel_.WorkBook().GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types')); - class(xlsxXml).AddOverrideContentType(content_xml, '/' + xlChartFileName_, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'); + content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types')); + class(TSXml).AddOverrideContentType(content_xml, '/' + xlChartFileName_, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'); End; class Function NewObject(sheet, excel); @@ -49,7 +49,7 @@ Type xlsxChart = Class(TSChart) o.GraphicFrame.macro := ''; o.GraphicFrame.GraphicFramePr.Name := chartData.Name ? chartData.Name : 'Chart' + inttostr(chartId_); - o.GraphicFrame.GraphicFramePr.Id := class(xlsxXml).GetcNvPrID(drawingXmlObj_); + o.GraphicFrame.GraphicFramePr.Id := class(TSXml).GetcNvPrID(drawingXmlObj_); o.GraphicFrame.GraphicFramePr.cNvGraphicFramePr := true; o.GraphicFrame.XFrm.Off.X := 0; diff --git a/funcext/TSOffice/worksheet/xlsxComment.tsf b/funcext/TSOffice/worksheet/xlsxComment.tsf index a92c64e..c83548b 100644 --- a/funcext/TSOffice/worksheet/xlsxComment.tsf +++ b/funcext/TSOffice/worksheet/xlsxComment.tsf @@ -12,7 +12,7 @@ Type xlsxComment = Class commentId_ := excel_.WorkBook().GetFilesCount('xl/comments') + 1; commentFileName_ := '../comments' + inttostr(commentId_) + '.xml'; xlCommentFileName := 'xl/comments' + inttostr(commentId_) + '.xml'; - excel_.Zip().Add(xlCommentFileName, class(xlsxXml).XmlHeader() + ''); + excel_.Zip().Add(xlCommentFileName, class(TSXml).XmlHeader() + ''); excel_.WorkBook().AddRelationshipRid(relsfile, commentFileName_, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', rId_); rid ++; drawingVML_ := '../drawings/vmlDrawing' + inttostr(commentId_) + '.vml'; @@ -33,9 +33,9 @@ xmlns:v="urn:schemas-microsoft-com:vml"> '); excel_.WorkBook().AddRelationshipRid(relsfile, drawingVML_, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', 'rId' + inttostr(rid)); - content_xml := excel_.WorkBook().GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types')); - class(xlsxXml).AddOverrideContentType(content_xml, '/' + xlCommentFileName, 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml'); - class(xlsxXml).AddDefaultContentType(content_xml, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'); + content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types')); + class(TSXml).AddOverrideContentType(content_xml, '/' + xlCommentFileName, 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml'); + class(TSXml).AddDefaultContentType(content_xml, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'); sheetXml := excel_.WorkBook().GetSheetXmlfile(sheetName_).FirstChildElement('worksheet'); legacy := sheetXml.FirstChildElement('legacyDrawing'); diff --git a/funcext/TSOffice/worksheet/xlsxDocProps.tsf b/funcext/TSOffice/worksheet/xlsxDocProps.tsf index 4e2fbeb..5607600 100644 --- a/funcext/TSOffice/worksheet/xlsxDocProps.tsf +++ b/funcext/TSOffice/worksheet/xlsxDocProps.tsf @@ -10,7 +10,7 @@ Type xlsxDocProps = Class node := app_xml.FirstChildElement('Properties'); if not ifObj(node) then return "node::Properties can't be found"; marshal := appProps.Marshal(); - class(xlsxXml).UpdateNode(node, marshal['attributes'], marshal['children']); + class(TSXml).UpdateNode(node, marshal['attributes'], marshal['children']); End; Function GetAppProps(); @@ -27,7 +27,7 @@ Type xlsxDocProps = Class core_xml := excel_.WorkBook().GetXmlFileObj('docProps/core.xml'); node := core_xml.FirstChildElement('cp:coreProperties'); marshal := appProps.Marshal(); - class(xlsxXml).UpdateNode(node, marshal['attributes'], marshal['children']); + class(TSXml).UpdateNode(node, marshal['attributes'], marshal['children']); End Function GetCoreProps(); diff --git a/funcext/TSOffice/worksheet/xlsxHyperLink.tsf b/funcext/TSOffice/worksheet/xlsxHyperLink.tsf index a179845..6184efb 100644 --- a/funcext/TSOffice/worksheet/xlsxHyperLink.tsf +++ b/funcext/TSOffice/worksheet/xlsxHyperLink.tsf @@ -17,7 +17,7 @@ Type xlsxHyperLink = Class work_node := xmlFile_.FirstChildElement('worksheet'); hyperlinks := work_node.FirstChildElement('hyperlinks'); if not ifObj(hyperlinks) then begin - insert_node := class(xlsxXml).GetWorkSheetPrevNode(work_node, 'hyperlinks'); + insert_node := class(TSXml).GetWorkSheetPrevNode(work_node, 'hyperlinks'); hyperlinks := work_node.InsertAfterChild(insert_node, 'element', 'hyperlinks'); end; node := hyperlinks.FirstChildElement('hyperlink'); @@ -44,7 +44,7 @@ Type xlsxHyperLink = Class rid++; ridstr := 'rId' + inttostr(rid); xmlfile := file_.WorkBook().GetXmlFileObj(relsfile); - class(xlsxXml).AddRelationshipRid(xmlfile, hyperlink.LinkUrl, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", ridstr, "External"); + class(TSXml).AddRelationshipRid(xmlfile, hyperlink.LinkUrl, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", ridstr, "External"); End hyperlink.RId := 'rId' + inttostr(rid); end @@ -71,7 +71,7 @@ Type xlsxHyperLink = Class link.LinkType := 'external'; rid := node.GetAttribute('r:id'); rels_file := file_.WorkBook().GetSheetRelsFile(sheetName_); - target_node := class(xlsxXml).FindRelationship(rels_file, rid); + target_node := class(TSXml).FindRelationship(rels_file, rid); if ifObj(target_node) then link.LinkUrl := target_node.GetAttribute('Target'); end link.Tooltip := node.GetAttribute('tooltip'); diff --git a/funcext/TSOffice/worksheet/xlsxImage.tsf b/funcext/TSOffice/worksheet/xlsxImage.tsf index 5169205..51a21ac 100644 --- a/funcext/TSOffice/worksheet/xlsxImage.tsf +++ b/funcext/TSOffice/worksheet/xlsxImage.tsf @@ -23,21 +23,21 @@ Type xlsxImage = Class image_file := getImageFileName(picture); rels_xmlfile := excel_.WorkBook().GetSheetRelsFile(sheetName_); prefix := ReplaceStr(image_file, 'xl/', '../'); - [rid, target] := class(xlsxXml).FindRelationshipRid(rels_xmlfile, prefix); + [rid, target] := class(TSXml).FindRelationshipRid(rels_xmlfile, prefix); if target = '' then begin rid ++; - class(xlsxXml).AddRelationshipRid(rels_xmlfile, prefix, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid); + class(TSXml).AddRelationshipRid(rels_xmlfile, prefix, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid); end - content_xml := excel_.WorkBook().GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types')); - class(xlsxXml).AddDefaultContentType(content_xml, 'jpeg', 'image/jpeg'); + content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types')); + class(TSXml).AddDefaultContentType(content_xml, 'jpeg', 'image/jpeg'); sheet_xml := excel_.WorkBook().GetSheetXmlfile(sheetName_); node := sheet_xml.FirstChildElement('worksheet'); picture_node := node.FirstChildElement('picture'); if not ifObj(picture_node) then begin - prev_node := class(xlsxXml).GetWorkSheetPrevNode(node, 'picture'); + prev_node := class(TSXml).GetWorkSheetPrevNode(node, 'picture'); if ifObj(prev_node) then picture_node := node.InsertAfterChild(prev_node, 'element', 'picture'); else picture_node := node.InsertEndChild('element', 'picture'); end @@ -55,26 +55,26 @@ Type xlsxImage = Class image_target := ReplaceStr(getImageFileName(picture), 'xl/', '../'); drawing_id := excel_.WorkBook().GetSheetDrawing(sheetName_); drawing_rels := excel_.WorkBook().GetDrawingRelsFile(drawing_id); - [rid, target] := class(xlsxXml).FindRelationshipRid(drawing_rels, image_target); + [rid, target] := class(TSXml).FindRelationshipRid(drawing_rels, image_target); if target = '' then begin rid++; - class(xlsxXml).AddRelationshipRid(drawing_rels, image_target, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid); + class(TSXml).AddRelationshipRid(drawing_rels, image_target, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid); end - content_xml := excel_.WorkBook().GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types')); - class(xlsxXml).AddDefaultContentType(content_xml, 'jpeg', 'image/jpeg'); + content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types')); + class(TSXml).AddDefaultContentType(content_xml, 'jpeg', 'image/jpeg'); sheet_xml := excel_.WorkBook().GetSheetXmlfile(sheetName_); node := sheet_xml.FirstChildElement('worksheet'); drawing_node := node.FirstChildElement('drawing'); if not ifObj(drawing_node) then begin - prev_node := class(xlsxXml).GetWorkSheetPrevNode(node, 'drawing'); + 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'); end sheet_rels := excel_.WorkBook().GetSheetRelsFile(sheetName_); drawing_file_name := '../drawings/drawing' + inttostr(drawing_id) + '.xml'; - [id, target] := class(xlsxXml).FindRelationshipRid(sheet_rels, drawing_file_name); + [id, target] := class(TSXml).FindRelationshipRid(sheet_rels, drawing_file_name); drawing_node.SetAttribute('r:id', 'rId' + inttostr(id)); // drawingN.xml @@ -95,7 +95,7 @@ Type xlsxImage = Class o.Pic.NodeName := 'xdr:pic'; o.Pic.NvPicPr.NodeName := 'xdr:nvPicPr'; o.Pic.NvPicPr.CNvPr.Name := picture.Name ? picture.Name : ''; - o.Pic.NvPicPr.CNvPr.ID := class(xlsxXml).GetcNvPrID(drawing_xml); + o.Pic.NvPicPr.CNvPr.ID := class(TSXml).GetcNvPrID(drawing_xml); o.Pic.NvPicPr.CNvPr.Descr := picture.Descr ? : ''; o.Pic.NvPicPr.CNvPr.ExtLst.Ext.Uri := ''; o.Pic.NvPicPr.CNvPr.ExtLst.Ext.Xmlns16 := 'http://schemas.microsoft.com/office/drawing/2014/main'; diff --git a/funcext/TSOffice/worksheet/xlsxShape.tsf b/funcext/TSOffice/worksheet/xlsxShape.tsf index 8359c11..896a65d 100644 --- a/funcext/TSOffice/worksheet/xlsxShape.tsf +++ b/funcext/TSOffice/worksheet/xlsxShape.tsf @@ -20,8 +20,7 @@ Type xlsxShape = Class class Function NewObject(sheet, excel); Begin - excel_ := excel; - o := excel_.WorkBook().GetSheetObj(sheet);//sheet存在 + o := excel.WorkBook().GetSheetObj(sheet);//sheet存在 if not ifObj(o) then return 0; return new xlsxShape(sheet, excel); End; @@ -68,7 +67,7 @@ private Function setSpNvSpPr(obj, shapeType); Begin obj.NodeName := 'xdr:nvSpPr'; - obj.CNvPr.ID := class(xlsxXml).GetcNvPrID(drawingXmlObj_); + obj.CNvPr.ID := class(TSXml).GetcNvPrID(drawingXmlObj_); obj.CNvPr.Name := (getShapeInfo()[shapeType]['name'] ?: '') $ ' ' $ obj.CNvPr.ID; obj.CNvPr.ExtLst.Ext.Uri := ''; obj.CNvPr.ExtLst.Ext.Xmlns16 := 'http://schemas.microsoft.com/office/drawing/2014/main'; diff --git a/funcext/TSOffice/worksheet/xlsxSheetView.tsf b/funcext/TSOffice/worksheet/xlsxSheetView.tsf index 6cd17e8..58a20d5 100644 --- a/funcext/TSOffice/worksheet/xlsxSheetView.tsf +++ b/funcext/TSOffice/worksheet/xlsxSheetView.tsf @@ -16,7 +16,7 @@ Type xlsxSheetView = Class if trystrtoint(id, r) and r = viewIndex then Begin marshal := SheetView.Marshal(); - class(xlsxXml).UpdateNode(sheet_view_node, marshal['attributes'], array()); + class(TSXml).UpdateNode(sheet_view_node, marshal['attributes'], array()); return ''; End sheet_view_node := sheet_view_node.NextElement(); diff --git a/funcext/TSOffice/worksheet/xlsxTable.tsf b/funcext/TSOffice/worksheet/xlsxTable.tsf index 367e1f1..69f054e 100644 --- a/funcext/TSOffice/worksheet/xlsxTable.tsf +++ b/funcext/TSOffice/worksheet/xlsxTable.tsf @@ -45,7 +45,7 @@ Type xlsxTable = Class table_xml := excel_.WorkBook().GetXmlFileObj(table_name); table_node := table_xml.FirstChild('table'); marshal := table.Marshal(); - class(xlsxXml).UpdateNode(table_node, marshal['attributes'], marshal['children']); + class(TSXml).UpdateNode(table_node, marshal['attributes'], marshal['children']); table_node.InsertEndChild(table_str); table_node.InsertEndChild(format.Marshal()); @@ -59,7 +59,7 @@ Type xlsxTable = Class count := 1; end else begin - count := inttostr(table_part.GetAttribute('count')) + 1; + count := strtoint(table_part.GetAttribute('count')) + 1; end node := table_part.InsertEndChild('element', 'tablePart'); node.SetAttribute('r:id', 'rId' $ rid); @@ -73,15 +73,16 @@ private table_str := ''; id := 1; col_index := 1; - if not includeHeader then - begin - excel_.WorkBook().InsertRow(sheetName_, row); - end + 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 - name := excel_.WorkBook().GetCellValue(sheetName_, cell)[1]; + 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); @@ -96,15 +97,15 @@ private Function addTableXmlFileAndRelation(); Begin sheet_rels_file := excel_.WorkBook().GetSheetRelsFile(sheetName_); - [rid, target] := class(xlsxXml).FindRelationshipRid(sheet_rels_file, ''); + [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(xlsxXml).XmlHeader() + ""); - class(xlsxXml).AddRelationshipRid(sheet_rels_file, table_target, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/table', 'rId' $ rid); - content_xml := excel_.WorkBook().GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types')); - class(xlsxXml).AddOverrideContentType(content_xml, '/' + table_name, 'application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml'); + excel_.zip().Add(table_name, class(TSXml).XmlHeader() + "
"); + 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, 'application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml'); return array(rid, table_id, table_name); End diff --git a/funcext/TSOffice/worksheet/xlsxWorkBook.tsf b/funcext/TSOffice/worksheet/xlsxWorkBook.tsf index 7e72e15..4432734 100644 --- a/funcext/TSOffice/worksheet/xlsxWorkBook.tsf +++ b/funcext/TSOffice/worksheet/xlsxWorkBook.tsf @@ -26,7 +26,7 @@ Type xlsxWorkBook = Class //workbook.xml.rels中加载(rid -> sheet-filename) rids := array(); - workbook_rels := GetXmlFileObj(class(xlsxXml).GetFileName('workbook_rels')); + workbook_rels := GetXmlFileObj(class(TSXml).GetFileName('workbook_rels')); rels := workbook_rels.FirstChildElement('Relationships').FirstChildElement('Relationship'); while ifObj(rels) do Begin id := rels.GetAttribute('Id'); @@ -138,13 +138,13 @@ Type xlsxWorkBook = Class sheetId := vselect maxof(['sheetId']) from sheetNames_ end; sheetId := integer(sheetId) + 1; fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml'; - zipfile_.Add(fname, class(xlsxXml).XmlHeader() + class(xlsxXml).GetTemplate('sheet1')); + 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(xlsxXml).GetTemplate('RelationshipWorkSheet')); + rels.SetAttribute('Type', class(TSXml).GetTemplate('RelationshipWorkSheet')); rels.SetAttribute('Id', rid); //workbook_rels.Print; @@ -157,7 +157,7 @@ Type xlsxWorkBook = Class //workbook.Print(); //设置docProps/app.xml - app := GetXmlFileObj(class(xlsxXml).GetFileName('docProps_app')); + app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app')); //app.Print(); node := app.FirstChildElement('Properties').FirstChildElement('TitlesOfParts'); if not ifObj(node) then Begin @@ -178,8 +178,8 @@ Type xlsxWorkBook = Class //app.Print(); //设置[Content_Types].xml - content_xml := GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types')); - class(xlsxXml).AddOverrideContentType(content_xml, '/' + fname, class(xlsxXml).GetTemplate('SheetContentType')); + 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; @@ -224,7 +224,7 @@ Type xlsxWorkBook = Class f.FileName := files[i]['New-FileName']; End; End; - workbook_rels := GetXmlFileObj(class(xlsxXml).GetFileName('workbook_rels')); + workbook_rels := GetXmlFileObj(class(TSXml).GetFileName('workbook_rels')); parent := workbook_rels.FirstChildElement('Relationships'); rels := parent.FirstChildElement('Relationship'); while ifObj(rels) do Begin @@ -266,7 +266,7 @@ Type xlsxWorkBook = Class //workbook.Print(); //设置docProps/app.xml - app := GetXmlFileObj(class(xlsxXml).GetFileName('docProps_app')); + app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app')); node := app.FirstChildElement('Properties').FirstChildElement('TitlesOfParts'); if ifObj(node) then Begin vector := node.FirstChildElement('vt:vector'); @@ -330,7 +330,7 @@ Type xlsxWorkBook = Class End //设置docProps/app.xml - app := GetXmlFileObj(class(xlsxXml).GetFileName('docProps_app')); + 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 @@ -378,7 +378,7 @@ Type xlsxWorkBook = Class rels := 'xl/worksheets/_rels/sheet' + id + '.xml.rels'; if not FileIsExist(rels) then return array(0, array()); xmlfile := GetXmlFileObj(rels); - [rid2, target] := class(xlsxXml).FindRelationshipRid(xmlfile, '../drawings/drawing'); + [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'; @@ -804,7 +804,7 @@ Type xlsxWorkBook = Class Function DeleteContentType(del_partname); Begin - content := GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types')); + content := GetXmlFileObj(class(TSXml).GetFileName('Content_Types')); types := content.FirstChildElement('Types'); element := types.FirstChildElement('Override'); while ifObj(element) do Begin @@ -825,10 +825,10 @@ Type xlsxWorkBook = Class files := zipfile_.Files(); isexist := vselect thisrowindex from files where ['FileName']=file end; if ifnil(isexist) then Begin - zipfile_.Add(file, class(xlsxXml).XmlHeader() + class(xlsxXml).GetTemplate('sheet_rels')); + zipfile_.Add(file, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('sheet_rels')); end xmlfile := GetXmlFileObj(file); - r := class(xlsxXml).FindRelationshipRid(xmlfile, prefix); + r := class(TSXml).FindRelationshipRid(xmlfile, prefix); r[2] := sheetNames_[ind]['file']; r[3] := file; return r; @@ -837,7 +837,7 @@ Type xlsxWorkBook = Class Function AddRelationshipRid(relsfile, target, type, rid); Begin xmlfile := GetXmlFileObj(relsfile); - class(xlsxXml).AddRelationshipRid(xmlfile, target, type, rid); + class(TSXml).AddRelationshipRid(xmlfile, target, type, rid); End; Function GetFilesCount(prefix); @@ -857,7 +857,7 @@ Type xlsxWorkBook = Class ind := sheetIndexMap_[LowerCase(sheet)]; file := 'xl/worksheets/_rels/' + ExtractFileName(sheetNames_[ind]['file']) + '.rels'; if not FileIsExist(file) then - zipfile_.Add(file, class(xlsxXml).XmlHeader() + class(xlsxXml).GetTemplate('sheet_rels')); + zipfile_.Add(file, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('sheet_rels')); return GetXmlFileObj(file); End; @@ -865,7 +865,7 @@ Type xlsxWorkBook = Class Begin file := 'xl/drawings/_rels/drawing' + inttostr(drawingId) + '.xml.rels'; if not FileIsExist(drawing_rels) then - zipfile_.Add(file, class(xlsxXml).XmlHeader() + class(xlsxXml).GetTemplate('drawing_rels')); + zipfile_.Add(file, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('drawing_rels')); return GetXmlFileObj(file); End; @@ -899,13 +899,13 @@ Type xlsxWorkBook = Class 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(xlsxXml).XmlHeader() + ''); + zipfile_.Add(drawing_xl_file_name, class(TSXml).XmlHeader() + ''); AddRelationshipRid(relsfile, drawing_file_name, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', 'rId' $ inttostr(rid)); - content_xml := GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types')); - class(xlsxXml).AddOverrideContentType(content_xml, '/' + drawing_xl_file_name, 'application/vnd.openxmlformats-officedocument.drawing+xml'); + 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(xlsxXml).GetWorkSheetPrevNode(node, 'drawing'); + 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)); @@ -928,7 +928,7 @@ Type xlsxWorkBook = Class tbreak.Id := row; if not ifObj(page_node) then begin - node := class(xlsxXml).GetWorkSheetPrevNode(worksheet, 'rowBreaks'); + node := class(TSXml).GetWorkSheetPrevNode(worksheet, 'rowBreaks'); node := worksheet.InsertAfterChild(node, 'element', 'rowBreaks'); node.SetAttribute('count', 1); node.SetAttribute('manualBreakCount', 1); @@ -993,8 +993,8 @@ private Function getWorkbookRelsRid(); Begin - workbook_rels := GetXmlFileObj(class(xlsxXml).GetFileName('workbook_rels')); - [rId, find] := class(xlsxXml).FindRelationshipRid(workbook_rels, ''); + workbook_rels := GetXmlFileObj(class(TSXml).GetFileName('workbook_rels')); + [rId, find] := class(TSXml).FindRelationshipRid(workbook_rels, ''); rId ++; return 'rId' $ rId; End; @@ -1030,7 +1030,7 @@ private 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.ChartNode := xml.FirstChildElement(getC(chart) + 'chartSpace').FirstChildElement(getC(chart) + 'chart').FirstChildElement(getC(chart) + 'plotArea'); + chart.plotAreaNode := xml.FirstChildElement(getC(chart) + 'chartSpace').FirstChildElement(getC(chart) + 'chart').FirstChildElement(getC(chart) + 'plotArea'); End; sheetsCount_:integer; diff --git a/更新日志.md b/更新日志.md index 7584cc7..ffa6929 100644 --- a/更新日志.md +++ b/更新日志.md @@ -1,5 +1,11 @@ # 更新日志 +## 2023-1-10 + +### V1.0.6 + +中文自动转换API由`class(xlsxXml).CodePage('中文');`调整为`TOfficeApi().CodePage('中文');` + ## 2023-1-5 ### V1.0.5