diff --git a/TSVbaDocxHelp.docx b/TSVbaDocxHelp.docx index 0cee57f..d50a77c 100644 Binary files a/TSVbaDocxHelp.docx and b/TSVbaDocxHelp.docx differ diff --git a/docx/TSDocxApplication.tsf b/docx/TSDocxApplication.tsf index 5c20eeb..9ee0f1e 100644 --- a/docx/TSDocxApplication.tsf +++ b/docx/TSDocxApplication.tsf @@ -4,6 +4,9 @@ public Function Create(); Function Init(); +private + documents_; + public // Methods Function Activate(); @@ -340,9 +343,6 @@ public Function ReadActiveEncryptionSession(); Function ReadActiveDocument(); -private - documents_; - End; // ============== 实现 ================= // @@ -358,7 +358,6 @@ Begin documents_.Init(); End; - // Properties Function TSDocxApplication.ReadDocuments(Index) Begin diff --git a/docx/TSDocxDocuments.tsf b/docx/TSDocxDocuments.tsf index 0aacc7e..d100811 100644 --- a/docx/TSDocxDocuments.tsf +++ b/docx/TSDocxDocuments.tsf @@ -21,7 +21,7 @@ public Function Item(Index); Function Open(FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, - Encoding, Visible, OpenConflictDocument, OpenAndRepair, DocumentDirection, NoEncodingDialog); // Completed + Encoding, Visible, OpenConflictDocument, OpenAndRepair, DocumentDirection, NoEncodingDialog); overload; Function OpenNoRepairDialog(FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, Encoding, Visible, OpenAndRepair, diff --git a/docx/TSDocxRange.tsf b/docx/TSDocxRange.tsf index 155621c..3cd2e73 100644 --- a/docx/TSDocxRange.tsf +++ b/docx/TSDocxRange.tsf @@ -17,6 +17,7 @@ private docx_; range_obj_; // TSWdRange range_font_; // TSDocxFontRange + range_shading_; // TSDocxShadingRange paragraph_format_range_; // TSDocxParagraphFormatRange list_format_range_; // TSDocxListFormatRange borders_range_; // TSDocxBordersRange @@ -79,7 +80,7 @@ public Function MoveStartWhile(Cset, Count); Function MoveUnti(Cset, Count); Function MoveWhile(Cset, Count); - Function Nex(_Unit, Count); + Function Next(_Unit, Count); Function NextSubdocument(); Function Paste(); Function PasteAndFormat(Type); @@ -332,6 +333,8 @@ Begin range_obj_ := rangeObj; range_font_ := new TSDocxFontRange(self.Application, self.Creator, self); range_font_.Init(range_obj_); + range_shading_ := new TSDocxShadingRange(self.Application, self.Creator, self); + range_shading_.Init(range_obj_); paragraph_format_range_ := new TSDocxParagraphFormatRange(self.Application, self.Creator, self); paragraph_format_range_.Init(docx_, range_obj_); list_format_range_ := new TSDocxListFormatRange(self.Application, self.Creator, self); @@ -732,6 +735,7 @@ End; Function TSDocxRange.WriteText(value); Begin + range_obj_.SplitRun(); self.Clear(); run := range_obj_[0].TRun; if ifObj(run.Root()) then run.SetText(value); @@ -743,12 +747,21 @@ Begin End; Function TSDocxRange.ReadText(); Begin + range_obj_.SplitRun(); txt := ""; prev := range_obj_[0].TParagraph; for i:=0 to range_obj_.Size()-1 do begin run := range_obj_[i].TRun; - txt += prev = range_obj_[i].TParagraph ? run.Text() : "\n" + run.Text(); + if not ifObj(run.Root()) then continue; + if prev = range_obj_[i].TParagraph then + begin + txt += run.Text(); + end + else begin + txt += "\n" + run.Text(); + prev := range_obj_[i].TParagraph; + end end return txt; End; @@ -757,3 +770,18 @@ Function TSDocxRange.ReadListFormat(); Begin return list_format_range_; End; + +Function TSDocxRange.ReadShading(); +Begin + return range_shading_; +End; + +Function TSDocxRange.ReadEnd(); +Begin + return range_obj_.GetEnd(); +End; + +Function TSDocxRange.ReadStart(); +Begin + return range_obj_.GetStart(); +End; diff --git a/docx/TSDocxTable.tsf b/docx/TSDocxTable.tsf index 9da9ae5..0b30716 100644 --- a/docx/TSDocxTable.tsf +++ b/docx/TSDocxTable.tsf @@ -193,20 +193,6 @@ Begin return ifnil(index) ? rows_obj : rows_obj[index]; End; -Function TSDocxTable.WritePreferredWidthType(value); -Begin -End; -Function TSDocxTable.ReadPreferredWidthType(); -Begin -End; - -Function TSDocxTable.WritePreferredWidth(value); -Begin -End; -Function TSDocxTable.ReadPreferredWidth(); -Begin -End; - Function TSDocxTable.ReadRange(); Begin if ifnil(range_) then diff --git a/docx/font/TSDocxFontRange.tsf b/docx/font/TSDocxFontRange.tsf index 7e1580e..2ba4a56 100644 --- a/docx/font/TSDocxFontRange.tsf +++ b/docx/font/TSDocxFontRange.tsf @@ -3,7 +3,7 @@ Uses TSDocxEnumerations; public Function Init(rangeObj); - Function Apply();overload; + Function Apply();override; Function ReWrite(pr);override; private @@ -115,7 +115,7 @@ Begin class(TSDocxFont).Init(nil); End; -Function TSDocxFontRange.Apply();overload; +Function TSDocxFontRange.Apply();override; Begin CallFunction(ThisFunction(class(TSDocxFont).Apply)); End; diff --git a/docx/paragraphformat/TSDocxParagraphFormat.tsf b/docx/paragraphformat/TSDocxParagraphFormat.tsf index d975152..b8c2c57 100644 --- a/docx/paragraphformat/TSDocxParagraphFormat.tsf +++ b/docx/paragraphformat/TSDocxParagraphFormat.tsf @@ -9,6 +9,7 @@ public protected docx_; pr_; // TOfficeObj("TwpPr") + shading_; // TSDocxShading public // Methods @@ -151,6 +152,7 @@ Function TSDocxParagraphFormat.Init(docx, pPr); Begin docx_ := docx; pr_ := pPr; + shading_ := nil; End; Function TSDocxParagraphFormat.Apply();virtual; @@ -316,9 +318,12 @@ End; Function TSDocxParagraphFormat.ReadShading();virtual; Begin - shading_obj := new TSDocxShading(self.Application, self.Creator, self.Parent); - shading_obj.Init(pr_.Shading); - return shading_obj; + if ifnil(shading_) then + begin + shading_ := new TSDocxShading(self.Application, self.Creator, self.Parent); + shading_.Init(pr_.Shading); + end + return shading_; End; Function TSDocxParagraphFormat.WriteRightIndent(value);virtual; diff --git a/docx/shading/TSDocxShading.tsf b/docx/shading/TSDocxShading.tsf index 6b5c36a..8057e81 100644 --- a/docx/shading/TSDocxShading.tsf +++ b/docx/shading/TSDocxShading.tsf @@ -45,7 +45,7 @@ Begin End; // property -Function TSDocxShading.WriteTexture(value); +Function TSDocxShading.WriteTexture(value);virtual; Begin case value of TSDocxEnumerations.wdTexture10Percent(): @@ -156,7 +156,7 @@ Begin shading_.Val := "thinVertStripe"; end; End; -Function TSDocxShading.ReadTexture(); +Function TSDocxShading.ReadTexture();virtual; Begin value := shading_.Value("Val"); case value of @@ -269,29 +269,29 @@ Begin end; End; -Function TSDocxShading.WriteForegroundPatternColorIndex(value); +Function TSDocxShading.WriteForegroundPatternColorIndex(value);virtual; Begin shading_.Color := color_index_[value]; End; -Function TSDocxShading.ReadForegroundPatternColorIndex(); +Function TSDocxShading.ReadForegroundPatternColorIndex();virtual; Begin return color_index_[shading_.Value("Color")]; End; -Function TSDocxShading.WriteForegroundPatternColor(value); +Function TSDocxShading.WriteForegroundPatternColor(value);virtual; Begin shading_.Color := color_[value]; End; -Function TSDocxShading.ReadForegroundPatternColor(); +Function TSDocxShading.ReadForegroundPatternColor();virtual; Begin return color_[shading_.Value("Color")]; End; -Function TSDocxShading.WriteBackgroundPatternColorIndex(value); +Function TSDocxShading.WriteBackgroundPatternColorIndex(value);virtual; Begin shading_.Fill := color_index_[value]; End; -Function TSDocxShading.ReadBackgroundPatternColorIndex(); +Function TSDocxShading.ReadBackgroundPatternColorIndex();virtual; Begin return color_index_[shading_.Value("Fill")]; End; diff --git a/docx/shading/TSDocxShadingRange.tsf b/docx/shading/TSDocxShadingRange.tsf index 8f3a024..66f6e4b 100644 --- a/docx/shading/TSDocxShadingRange.tsf +++ b/docx/shading/TSDocxShadingRange.tsf @@ -7,13 +7,13 @@ public private Function GetShadingObjectByNode(node); - Function GetShading(arr, hash); + Function GetShading(arr); Function CallFunction(fname, value);overload; Function CallFunction(fname);overload; - Function SplitRun(); private range_obj_; + shading_hash_; public Function WriteTexture(value);override; @@ -34,27 +34,22 @@ End; Function TSDocxShadingRange.Init(rangeObj); Begin range_obj_ := rangeObj; + shading_hash_ := array(); class(TSDocxShading).Init(nil); End; Function TSDocxShadingRange.Apply();override; Begin - CallFunction(ThisFunction(class(TSDocxShading).Apply), nil); + CallFunction("Apply"); End; -Function TSDocxShadingRange.SplitRun(); -Begin - range_obj_.SplitRangeRun(); - self.Parent.SetRangeObj(range_obj_); -End; - -Function TSDocxShadingRange.GetShading(arr, hash); +Function TSDocxShadingRange.GetShading(arr); Begin if arr.Entirety then begin - if not ifnil(hash[arr.Entirety]) then nil; - hash[arr.Entirety] := true; + if not ifnil(shading_hash_[arr.Entirety]) then return nil; shading := GetShadingObjectByNode(arr.Entirety); + shading_hash_[arr.Entirety] := shading; end else begin trun := arr.TRun; @@ -74,7 +69,7 @@ Begin obj.Init(node); paragraph_obj := new TSDocxParagraph(self.Application, self.Creator, self.Parent); paragraph_obj.Init(nil, obj, nil); - return paragraph_obj.Shading(); + return paragraph_obj.Shading; end else if name = "w:tbl" then begin @@ -82,24 +77,23 @@ Begin obj.Init(node); table_obj := new TSDocxTable(self.Application, self.Creator, self.Parent); table_obj.Init(nil, obj); - return table_obj.Shading(); + return table_obj.Shading; end else if name = "w:tc" then begin cell_obj := new TSDocxCell(self.Application, self.Creator, self.Parent); cell_obj.Init(node); - return cell_obj.Shading(); + return cell_obj.Shading; end End; Function TSDocxShadingRange.CallFunction(fname, value);overload; Begin // 这样设计是为了段落走走段落的shading,table走table的,cell走cell的 - SplitRun(); - hash := array(); + range_obj_.SplitRun(); for i:=0 to range_obj_.Size()-1 do begin - shading := GetShading(range_obj_[i], hash); + shading := GetShading(range_obj_[i]); if ifnil(shading) then continue; pf := FindFunction(fname, shading); pf.Do(value); @@ -108,11 +102,13 @@ End; Function TSDocxShadingRange.CallFunction(fname);overload; Begin - hash := array(); + range_obj_.SplitRun(); ret := nil; for i:=0 to range_obj_.Size()-1 do begin - shading := GetShading(range_obj_[i], hash); + arr := range_obj_[i]; + if arr.Entirety and shading_hash_[arr.Entirety] then shading := shading_hash_[arr.Entirety]; + else shading := GetShading(range_obj_[i]); if ifnil(shading) then continue; pf := FindFunction(fname, shading); r := pf.Do(); diff --git a/docx/utils/TSWdRange.tsf b/docx/utils/TSWdRange.tsf index 8b9995f..0c87c6e 100644 --- a/docx/utils/TSWdRange.tsf +++ b/docx/utils/TSWdRange.tsf @@ -13,7 +13,6 @@ public Function SplitRun(index);overload; Function Clear(deleteAll); Function Size(); - Function Root(); Function Print(); Begin @@ -27,6 +26,7 @@ private Function AddRunInfo(runNode, tParagraph); Function AddRunInfo2(runNode, tParagraph); Function ParagraphRange(node); + Function CalcPosition(startNode); public data_; // 管理range结构的数组,字段如下 @@ -106,7 +106,7 @@ Function TSWdRange.Create(rootNode, startP, endP);overload; Begin root_node_ := rootNode; start_position_ := startP; - end_position_ := endP; + end_position_ := endP = -1 ? INF : endP; target_node_ := nil; self.Init(); End; @@ -153,21 +153,15 @@ Begin return length(data_); End; -Function TSWdRange.Root(); -Begin - node := root_node_; - return node; -End; - Function TSWdRange.GetStart(); Begin - if ifnil(start_position_) then return 0; + if ifnil(start_position_) then self.CalcPosition(root_node_); return start_position_; End; Function TSWdRange.GetEnd(); Begin - if ifnil(end_position_) then return 0; + if ifnil(end_position_) then self.CalcPosition(root_node_); return end_position_; End; @@ -372,6 +366,86 @@ Begin end; End; +Function TSWdRange.CalcPosition(startNode); +Begin + node := startNode.FirstChildElement(); + while ifObj(node) do + begin + if node.Eq(target_node_) then + begin + eq_flag := true; + start_position_ := cur_position_; + end + case node.GetName() of + "w:p": + begin + paragraph_obj := TOfficeObj("TParagraph"); + paragraph_obj.Init(node); + if paragraph_obj.Empty() then // 空段落 + begin + cur_position_ += 1; + end + else begin + sub_node := node.FirstChildElement(); + while ifObj(sub_node) do + begin + case sub_node.GetName() of + "w:r": + begin + run_obj := TOfficeObj("TRun"); + run_obj.Init(sub_node); + text := run_obj.Text(); + if class(TSXml).IsUtf8() then text := Utf8ToAnsi(text); + cur_position_ += lengthw(text); + end + + "w:ins", "w:del": + begin + run_node := sub_node.FirstChildElement("w:r"); + while ifObj(run_node) do + begin + run_obj := TOfficeObj("TRun"); + run_obj.Init(run_node); + text := run_obj.Text(); + if class(TSXml).IsUtf8() then text := Utf8ToAnsi(text); + cur_position_ += lengthw(text); + run_node := run_node.NextElement("w:r"); + end + end + end; + sub_node := sub_node.NextElement(); + end + // 完整段落 + cur_position_ += 1; + end + end + + "w:tbl": + begin + tr := node.FirstChildElement("w:tr"); + while ifObj(tr) do + begin + tc := tr.FirstChildElement("w:tc"); + while ifObj(tc) do + begin + flag := self.CalcPosition(tc); + if flag then return 1; + tc := tc.NextElement("w:tc"); + end + cur_position_ += 1; + tr := tr.NextElement("w:tr"); + end + end + end; + if eq_flag then + begin + end_position_ := cur_position_; + return 1; + end + node := node.NextElement(); + end +End; + Function TSWdRange.ParagraphRange(node); Begin paragraph_obj := TOfficeObj("TParagraph");