Type TSDocxColumn = Class(TSVbaBase) Uses TSDocxEnumerations; public Function Init(table, column); private Function SetColumnWidth(column, wvalue, type); Function SerializeTblGrid(); private table_; column_; min_dxa_width_; // 最小宽度 321 public Function AutoFit(); Function Delete(); Function Select(); Function SetWidth(ColumnWidth, RulerStyle); Function Sort(ExcludeHeader, SortFieldType, SortOrder, CaseSensitive, BidiSort, IgnoreThe, IgnoreKashida, IgnoreDiacritics, IgnoreHe, LanguageID); property Borders read ReadBorders; property Cells read ReadCells; property Index read ReadIndex; property IsFirst read ReadIsFirst; property IsLast read ReadIsLast; property NestingLevel read ReadNestingLevel; property Next read ReadNext; property PreferredWidth read ReadPreferredWidth write WritePreferredWidth; property PreferredWidthType read ReadPreferredWidthType write WritePreferredWidthType; property Previous read ReadPrevious; property Shading read ReadShading; property Width read ReadWidth write WriteWidth; Function WriteWidth(value); Function ReadWidth(); Function ReadShading(); Function ReadPrevious(); Function WritePreferredWidthType(value); Function ReadPreferredWidthType(); Function WritePreferredWidth(value); Function ReadPreferredWidth(); Function ReadNext(); Function ReadNestingLevel(); Function ReadIsLast(); Function ReadIsFirst(); Function ReadIndex(); Function ReadCells(); Function ReadBorders(); End; // ============== 实现 ================= // Function TSDocxColumn.Init(table, column); Begin table_ := table; column_ := column; min_dxa_width_ := 321; End; Function TSDocxColumn.SetColumnWidth(column, wvalue, type); Begin if ifnil(wvalue) and ifnil(type) then return; tcells := table_.GetCells(); for r:=0 to table_.Rows()-1 do begin cell := tcells[r, column-1]; if ifnil(cell) then continue; tcpr := class(TSXml).GetNode(cell[0], "w:tcPr", "first"); obj := TOfficeObj("TwTcPr"); obj.InitRootNode(tcpr); obj.Width := wvalue; obj.Type := type; obj.Update(); end End; Function TSDocxColumn.SerializeTblGrid(); Begin grid_col_arr := array(); total_width := 0; grid_col := class(TSXml).GetNode(table_.Root(), "w:tblGrid/w:gridCol"); while ifObj(grid_col) do begin ww := strtoint(grid_col.GetAttribute("w:w")); total_width += ww; grid_col_arr[length(grid_col_arr)] := array(grid_col, ww); grid_col := grid_col.NextElement(); end return array(total_width, grid_col_arr); End; // function Function TSDocxColumn.SetWidth(ColumnWidth, RulerStyle); Begin if ifnil(RulerStyle) then RulerStyle := TSDocxEnumerations.wdAdjustNone(); width_value := ColumnWidth * 20; [total_width, grid_col_arr] := SerializeTblGrid(); // 设置w:tblPr的总宽度 table_.TblPr.Width := total_width; table_.TblPr.WidthType := "dxa"; table_.TblPr.Update(); case RulerStyle of TSDocxEnumerations.wdAdjustFirstColumn(): begin if column_ < length(grid_col_arr)-1 then begin new_width := grid_col_arr[column_][1] + grid_col_arr[column_-1][1] - width_value; if new_width < min_dxa_width_ then new_width := min_dxa_width_; grid_col_arr[column_][0].SetAttribute("w:w", new_width); SetColumnWidth(column_ + 1, new_w, "dxa"); end end TSDocxEnumerations.wdAdjustNone(): begin end TSDocxEnumerations.wdAdjustProportional(): begin // TODO : 需要搞懂算法 end TSDocxEnumerations.wdAdjustSameWidth(): begin after_width := grid_col_arr[column_-1][1] - width_value; for i:=column_ to length(grid_col_arr)-1 do after_width += grid_col_arr[i][1]; if length(grid_col_arr) > column_ then // 不是最后一列 begin num := length(grid_col_arr) - column_; new_width := integer(after_width / num); for c:=column_+1 to length(grid_col_arr) do begin grid_col_arr[c-1][0].SetAttribute("w:w", new_width); SetColumnWidth(c, new_width, "dxa"); end end end end; grid_col_arr[column_-1][0].SetAttribute("w:w", width_value); SetColumnWidth(column_, width_value, "dxa"); End; //property Function TSDocxColumn.WriteWidth(value); Begin End; Function TSDocxColumn.ReadWidth(); Begin End; Function TSDocxColumn.WritePreferredWidthType(value); Begin case value of TSDocxEnumerations.wdPreferredWidthAuto(): begin table_.TblPr.Width := 0; table_.TblPr.WidthType := "auto"; table_.TblPr.Update(); for c:=1 to table_.Cols() do SetColumnWidth(c, 0, "auto"); end TSDocxEnumerations.wdPreferredWidthPercent(): begin table_.TblPr.Width := 5000; table_.TblPr.WidthType := "pct"; table_.TblPr.Update(); width_value := integer(5000 / table_.Cols()); for c:=1 to table_.Cols() do SetColumnWidth(c, width_value, "pct"); end TSDocxEnumerations.wdPreferredWidthPoints(): begin for c:=1 to table_.Cols() do SetColumnWidth(c, nil, "dxa"); end end; End; Function TSDocxColumn.ReadPreferredWidthType(); Begin tcells := table_.GetCells(); cell := tcells[1, column_ - 1]; if ifnil(cell) then return nil; tcpr := class(TSXml).GetNode(cell[0], "w:tcPr", "first"); obj := TOfficeObj("TwTcPr"); obj.InitRootNode(tcpr); width_type := obj.Value("Type"); tcpr.print; case width_type of "auto": return TSDocxEnumerations.wdPreferredWidthAuto(); "dxa": return TSDocxEnumerations.wdPreferredWidthPoints(); "pct": return TSDocxEnumerations.wdPreferredWidthPercent(); end; End; Function TSDocxColumn.WritePreferredWidth(value); Begin width_type := self.PreferredWidthType; width_value := 0; case width_type of TSDocxEnumerations.wdPreferredWidthAuto(), TSDocxEnumerations.wdPreferredWidthPoints(): begin width_type := "dxa"; width_value := 20 * value; if width_type > min_dxa_width_ then width_type := min_dxa_width_; SetColumnWidth(column_, width_value, width_type); end TSDocxEnumerations.wdPreferredWidthPercent(): begin width_type := "pct"; if value < 0 or value > 100 then return; width_value := 50 * value; SetColumnWidth(column_, width_value, width_type); end end; End; Function TSDocxColumn.ReadPreferredWidth(); Begin tcells := table_.GetCells(); cell := tcells[1, column_ - 1]; if ifnil(cell) then return nil; tcpr := class(TSXml).GetNode(cell[0], "w:tcPr", "first"); obj := TOfficeObj("TwTcPr"); obj.InitRootNode(tcpr); width_type := obj.Value("Type"); width_value := obj.Value("Width"); case width_type of "auto", "dxa": return width_value / 20; "pct": return width_value / 50; end; End;