OfficeVba/docx/TSDocxCell.tsf

580 lines
14 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Type TSDocxCell = Class(TSVbaBase)
Uses TSDocxEnumerations;
public
Function Init(docx, table, r, c);overload;
Function Init(node);overload;
private
Function GetCell();
Function SetCellTcPrWidth(r, c, widthValue, widthType);overload;
Function SetCellTcPrWidth(tcpr, widthValue, widthType);overload;
Function GetTcprObject(r, c);
Function GetTrPrObject();
Function AdjustSameWidth();
Function AdjustFirstColumn(widthValue);
Function ProcessWidthValue(widthValue, widthType);
private
docx_;
table_; // TOfficeObj("TTable")
tcpr_; // TOfficeObj("TwTcPr")
trpr_; // TOfficeObj("TwTrPr")
cell_; // TOfficeObj("TCell")
min_dxa_width_; // 最小宽度 321
range_;
row_;
column_;
shading_;
public
// Methods
Function AutoSum();
Function Delete(ShiftCells);
Function Formula(Formula, NumFormat);
Function Merge(MergeTo);
Function Select();
Function SetHeight(RowHeight, HeightRule);
Function SetWidth(ColumnWidth, RulerStyle);
Function Split(NumRows, NumColumns);
// Properties
property Borders read ReadBorders;
property BottomPadding read ReadBottomPadding write WriteBottomPadding;
property Column read ReadColumn;
property ColumnIndex read ReadColumnIndex;
property FitText read ReadFitText write WriteFitText;
property Height read ReadHeight write WriteHeight;
property HeightRule read ReadHeightRule write WriteHeightRule;
property ID read ReadID write WriteID;
property LeftPadding read ReadLeftPadding write WriteLeftPadding;
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 Range read ReadRange;
property RightPadding read ReadRightPadding write WriteRightPadding;
property Row read ReadRow;
property RowIndex read ReadRowIndex;
property Shading read ReadShading;
property Tables read ReadTables;
property TopPadding read ReadTopPadding write WriteTopPadding;
property VerticalAlignment read ReadVerticalAlignment write WriteVerticalAlignment;
property Width read ReadWidth write WriteWidth;
property WordWrap read ReadWordWrap write WriteWordWrap;
Function WriteWordWrap(value);
Function ReadWordWrap();
Function WriteWidth(value);
Function ReadWidth();
Function WriteVerticalAlignment(value);
Function ReadVerticalAlignment();
Function WriteTopPadding(value);
Function ReadTopPadding();
Function ReadTables(index);
Function ReadShading();
Function ReadRowIndex();
Function ReadRow();
Function WriteRightPadding(value);
Function ReadRightPadding();
Function ReadRange();
Function ReadPrevious();
Function WritePreferredWidthType(value);
Function ReadPreferredWidthType();
Function WritePreferredWidth(value);
Function ReadPreferredWidth();
Function ReadNext();
Function ReadNestingLevel();
Function WriteLeftPadding(value);
Function ReadLeftPadding();
Function WriteID();
Function ReadID();
Function WriteHeightRule(value);
Function ReadHeightRule();
Function WriteHeight(value);
Function ReadHeight();
Function WriteFitText();
Function ReadFitText();
Function ReadColumnIndex();
Function ReadColumn();
Function WriteBottomPadding(value);
Function ReadBottomPadding();
Function ReadBorders(index);
End;
// ============== 实现 ================= //
Function TSDocxCell.Init(docx, table, r, c);overload;
Begin
docx_ := docx;
table_ := table;
row_ := r;
column_ := c;
min_dxa_width_ := 321;
tcpr_ := GetTcprObject(row_, column_);
trpr_ := nil; // 延迟访问
cell_ := nil;
range_ := nil;
End;
Function TSDocxCell.Init(node);overload;
Begin
cell_ := TOfficeObj("tcell");
cell_.Create(node);
tcpr_node := class(TSXml).GetNode(node, "w:tcPr", "first");
tcpr_ := TOfficeObj("TwTcPr");
tcpr_.InitRootNode(tcpr_node);
End;
Function TSDocxCell.GetCell();
Begin
if ifObj(cell_) then return cell_;
cell_ := table_.Cell(row_, column_);
return cell_;
End;
Function TSDocxCell.ProcessWidthValue(widthValue, widthType);
Begin
case widthType of
"dxa":
begin
widthValue := widthValue * 20;
if widthValue < min_dxa_width_ then widthValue := min_dxa_width_;
end
"pct":
begin
widthValue := widthValue * 50;
end
end;
End;
Function TSDocxCell.GetTrPrObject();
Begin
if ifObj(trpr_) then return trpr_;
tr_node := class(TSXml).GetNodeN(table_.Root(), "w:tr", column_);
trpr_node := tr_node.FirstChild("w:trPr");
if not ifObj(trpr_node) then trpr_node := tr_node.InsertFirstChild("element", "w:trPr");
trpr_:= TOfficeObj("TwTrPr");
trpr_.InitRootNode(trpr_node);
return trpr_;
End;
Function TSDocxCell.SetCellTcPrWidth(r, c, widthValue, widthType);overload;
Begin
tcpr_obj := GetTcprObject(r, c);
if ifnil(tcpr_obj) then return;
SetCellTcPrWidth(tcpr_obj, widthValue, widthType);
End;
Function TSDocxCell.SetCellTcPrWidth(tcpr, widthValue, widthType);overload;
Begin
ProcessWidthValue(widthValue, widthType);
tcpr.Width := widthValue;
tcpr.Type := widthType;
tcpr.Update();
End;
Function TSDocxCell.GetTcprObject(r, c);
Begin
cell := table_.GetCell(r, c);
if ifnil(cell) then return nil;
tcpr_node := class(TSXml).GetNode(cell[0], "w:tcPr", "first");
tcpr := TOfficeObj("TwTcPr");
tcpr.InitRootNode(tcpr_node);
return tcpr;
End;
// function
Function TSDocxCell.Delete(ShiftCells);
Begin
if ifnil(ShiftCells) then ShiftCells := TSDocxEnumerations.wdDeleteCellsShiftLeft();
case ShiftCells of
TSDocxEnumerations.wdDeleteCellsEntireColumn():
table_.DeleteCell(nil, column_);
TSDocxEnumerations.wdDeleteCellsEntireRow():
table_.DeleteCell(row_, nil);
TSDocxEnumerations.wdDeleteCellsShiftLeft():
table_.DeleteCell(row_, column_);
TSDocxEnumerations.wdDeleteCellsShiftUp():
table_.DeleteCell(row_, column_, 0);
end;
End;
Function TSDocxCell.SetHeight(RowHeight, HeightRule);
Begin
trpr_obj := GetTrPrObject();
case HeightRule of
TSDocxEnumerations.wdRowHeightAtLeast:
begin
h_rule := "least";
end
TSDocxEnumerations.wdRowHeightAuto:
begin
h_rule := "auto";
end
TSDocxEnumerations.wdRowHeightExactly:
begin
h_rule := "exact";
end
end;
trpr_obj.Rule := h_rule;
trpr_obj.Height := RowHeight * 20;
trpr_obj.Update();
End;
Function TSDocxCell.SetWidth(ColumnWidth, RulerStyle);
Begin
if ifnil(RulerStyle) then RulerStyle := TSDocxEnumerations.wdAdjustNone();
width_value := ColumnWidth;
case RulerStyle of
TSDocxEnumerations.wdAdjustFirstColumn():
AdjustFirstColumn(width_value);
TSDocxEnumerations.wdAdjustNone():
begin
end
TSDocxEnumerations.wdAdjustProportional():
begin
end
TSDocxEnumerations.wdAdjustSameWidth():
AdjustSameWidth();
end;
SetCellTcPrWidth(tcpr_, width_value, "dxa");
End;
Function TSDocxCell.AdjustFirstColumn(widthValue);
Begin
tcpr_next := GetTcprObject(row_, column_ + 1);
if not tcpr_next then return;
ww := tcpr_next.Value("width");
new_width := ww + tcpr_.Value("width") - widthValue;
SetCellTcPrWidth(tcpr_next, new_width, "dxa");
End;
Function TSDocxCell.AdjustSameWidth();
Begin
if column_ <> table_.Cols() then
begin
after_total_width := 0;
tcpr_arr := array();
for i:=column_+1 to table_.Cols() do
begin
tcpr := GetTcprObject(row_, i);
after_total_width += tcpr.Value("Width");
tcpr_arr[length(tcpr_arr)] := tcpr;
end
after_width := integer(after_total_width / length(tcpr_arr));
for i:=0 to length(tcpr_arr)-1 do
SetCellTcPrWidth(tcpr_arr[i], after_width, "dxa");
end
End;
Function TSDocxCell.Merge(MergeTo);
Begin
table_.Merge(self.RowIndex, self.ColumnIndex, MergeTo.RowIndex, MergeTo.ColumnIndex, false);
End;
// property
Function TSDocxCell.ReadColumnIndex();
Begin
return column_;
End;
Function TSDocxCell.ReadColumn();
Begin
column_obj := new TSDocxColumn(self.Application, self.Creator, self);
column_obj.Init(table_, column_);
return column_obj;
End;
Function TSDocxCell.ReadRowIndex();
Begin
return row_;
End;
// VBA width=100xml是2000
Function TSDocxCell.WriteWidth(value);
Begin
width_type := tcpr_.Value("Type");
width_value := value;
case width_type of
"auto":
begin
width_value := width_value * 20;
width_type := "dxa";
end
"dxa": width_value := width_value * 20;
"pct": width_value := width_value * 12.05;
end;
tcpr_.Width := integer(width_value);
tcpr_.Type := width_type;
tcpr_.Update();
End;
Function TSDocxCell.ReadWidth();
Begin
width_type := tcpr_.Value("Type");
width_value := tcpr_.Value("width");
case width_type of
"dxa", "auto": return width_value / 20;
"pct": return width_value / 12.05;
end;
End;
Function TSDocxCell.WriteWordWrap(value);
Begin
tcpr_.noWrap := value ? 0 : 1;
tcpr_.Update();
End;
Function TSDocxCell.ReadWordWrap();
Begin
return tcpr_.Value("noWrap") ? false : true;
End;
Function TSDocxCell.WriteVerticalAlignment(value);
Begin
case value of
TSDocxEnumerations.wdCellAlignVerticalBottom():
begin
tcpr_.vAlign := "bottom";
tcpr_.Update();
end
TSDocxEnumerations.wdCellAlignVerticalCenter():
begin
tcpr_.vAlign := "center";
tcpr_.Update();
end
TSDocxEnumerations.wdCellAlignVerticalTop():
begin
tcpr_.vAlign := "top";
tcpr_.Update();
end;
end;
End;
Function TSDocxCell.ReadVerticalAlignment();
Begin
alignment := tcpr_.Value("vAlign");
case alignment of
"bottom": return TSDocxEnumerations.wdCellAlignVerticalBottom();
"center": return TSDocxEnumerations.wdCellAlignVerticalCenter();
else return TSDocxEnumerations.wdCellAlignVerticalTop();
end;
End;
Function TSDocxCell.WriteTopPadding(value);
Begin
tcpr_.CellMar.Top := 20 * value;
tcpr_.CellMar.TopType := "dxa";
tcpr_.Update();
End;
Function TSDocxCell.ReadTopPadding();
Begin
return tcpr_.CellMar.Value("Top") / 20;
End;
Function TSDocxCell.WriteLeftPadding(value);
Begin
tcpr_.CellMar.Left := 20 * value;
tcpr_.CellMar.LeftType := "dxa";
tcpr_.Update();
End;
Function TSDocxCell.ReadLeftPadding();
Begin
return tcpr_.CellMar.Value("Left") / 20;
End;
Function TSDocxCell.WriteBottomPadding(value);
Begin
tcpr_.CellMar.Bottom := 20 * value;
tcpr_.CellMar.BottomType := "dxa";
tcpr_.Update();
End;
Function TSDocxCell.ReadBottomPadding();
Begin
return tcpr_.CellMar.Value("Bottom") / 20;
End;
Function TSDocxCell.WriteRightPadding(value);
Begin
tcpr_.CellMar.Right := 20 * value;
tcpr_.CellMar.RightType := "dxa";
tcpr_.Update();
End;
Function TSDocxCell.ReadRightPadding();
Begin
return tcpr_.CellMar.Value("Right") / 20;
End;
Function TSDocxCell.ReadTables(index);
Begin
tables_obj := new TSDocxTables(self.Application, self.Creator, self);
tables_obj.Init(GetCell());
return ifnil(index) ? tables_obj : tables_obj[index];
End;
Function TSDocxCell.ReadShading();
Begin
if ifnil(shading_) then
begin
shading_ := new TSDocxShading(self.Application, self.Creator, self);
shading_.Init(tcpr_.Shading);
end
return shading_;
End;
Function TSDocxCell.ReadBorders(index);
Begin
borders_obj := new TSDocxBordersCell(self.Application, self.Creator, self);
borders_obj.Init(GetCell());
return ifnil(index) ? borders_obj : borders_obj.Item(index);
End;
Function TSDocxCell.WritePreferredWidthType(value);
Begin
width_value := nil;
width_type := nil;
case value of
TSDocxEnumerations.wdPreferredWidthAuto():
begin
table_.TblPr.Width := 0;
table_.TblPr.WidthType := "auto";
table_.TblPr.Update();
width_value := 0;
width_type := "auto";
end
TSDocxEnumerations.wdPreferredWidthPercent():
begin
table_.TblPr.Width := 5000;
table_.TblPr.WidthType := "pct";
table_.TblPr.Update();
width_value := integer(5000 / table_.Cols());
width_type := "pct";
end
TSDocxEnumerations.wdPreferredWidthPoints():
begin
width_value := nil;
width_type := "dxa";
end
end;
SetCellTcPrWidth(row_, column_, width_value, width_type);
End;
Function TSDocxCell.ReadPreferredWidthType();
Begin
width_type := tcpr_.Value("Type");
case width_type of
"auto": return TSDocxEnumerations.wdPreferredWidthAuto();
"dxa": return TSDocxEnumerations.wdPreferredWidthPoints();
"pct": return TSDocxEnumerations.wdPreferredWidthPercent();
end;
End;
Function TSDocxCell.WritePreferredWidth(value);
Begin
width_type := self.PreferredWidthType;
width_value := value;
case width_type of
TSDocxEnumerations.wdPreferredWidthAuto(),
TSDocxEnumerations.wdPreferredWidthPoints():
begin
width_type := "dxa";
SetCellTcPrWidth(row_, column_, width_value, width_type);
end
TSDocxEnumerations.wdPreferredWidthPercent():
begin
width_type := "pct";
SetCellTcPrWidth(row_, column_, width_value, width_type);
end
end;
End;
Function TSDocxCell.ReadPreferredWidth();
Begin
width_type := tcpr_.Value("Type");
width_value := tcpr_.Value("Width");
case width_type of
"auto", "dxa": return width_value / 20;
"pct": return width_value / 50;
end;
End;
Function TSDocxCell.WriteHeight(value);
Begin
SetHeight(value, self.HeightRule);
End;
Function TSDocxCell.ReadHeight();
Begin
trpr_obj := GetTrPrObject();
value := trpr_obj.Value("Height");
return ifnil(value) ? 0 : value / 20;
End;
Function TSDocxCell.WriteHeightRule(value);
Begin
trpr_obj := GetTrPrObject();
case value of
TSDocxEnumerations.wdRowHeightAuto():
trpr_obj.Rule := "auto";
TSDocxEnumerations.wdRowHeightAtLeast():
trpr_obj.Rule := "least";
TSDocxEnumerations.wdRowHeightExactly():
trpr_obj.Rule := "exact";
end;
trpr_obj.Update();
End;
Function TSDocxCell.ReadHeightRule();
Begin
trpr_obj := GetTrPrObject();
rule := trpr_obj.Value("Rule");
case rule of
"auto": return TSDocxEnumerations.wdRowHeightAuto();
"least": return TSDocxEnumerations.wdRowHeightAtLeast();
"exact": return TSDocxEnumerations.wdRowHeightExactly();
end;
return TSDocxEnumerations.wdRowHeightAtLeast();
End;
Function TSDocxCell.ReadNext();
Begin
if column_ = table_.Cols() then
begin
if row_ = table_.Rows() then return nil;
return self.Parent.Cell(row_ + 1, 1);
end
return self.Parent.Cell(row_, column_ + 1);
End;
Function TSDocxCell.ReadPrevious();
Begin
if column_ = 1 then
begin
if row_ = 1 then return nil;
return self.Parent.Cell(row_ - 1, table_.Cols());
end
return self.Parent.Cell(row_, column_ - 1);
End;
Function TSDocxCell.ReadRange();
Begin
if ifnil(range_) then
begin
obj := new TSWdRange(docx_.Body().Root(), GetCell().Root());
range_ := new TSDocxRange(self.Application, self.Creator, self);
range_.Init(docx_, obj);
end
return range_;
End;