580 lines
14 KiB
Plaintext
580 lines
14 KiB
Plaintext
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=100,xml是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 * bottom;
|
||
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;
|
||
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;
|