OfficeVba/docx/TSDocxColumn.tsf

239 lines
6.3 KiB
Plaintext

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;