type TSPdfTableRange = class(TSPdfBasicRange) public function Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: Components; table: Tbl); function Calc(); function Do();override; private function GetCellMatrix(grid_cols: array of GridColUnitDecorator); function ResetCoordinates(tbl_pr: TblPr; grid_cols: array of GridCol); function SetTblPr(tbl_pr: TblPr); function SetTblPrByStyleId(var tbl_pr: TblPr; style_id: string); function SetTrPr(var tr_pr: TrPr); function SetTrPrByStyleId(var tr_pr: TrPr; style_id: string); function SetTcPr(var tc_pr: TcPr); function SetTcPrByStyleId(var tc_pr: TcPr; style_id: string); function SetTblStylePr(var tc_pr: TcPr; type: string); private [weakref]docx_to_pdf_: TSDocxToPdf; [weakref]docx_components_ware_: Components; [weakref]table_: Tbl; [weakref]page_: TSPage; range_array_: tableArray; end; function TSPdfTableRange.Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; table: Tbl); begin docx_to_pdf_ := docx_to_pdf; page_ := pg; docx_components_ware_ := Components; table_ := table; range_array_ := array(); {self.}TSPage := page_; end; function TSPdfTableRange.Calc(); begin {self.}SetTblPr(table_.TblPr); table_.TblPr := new TblPrUnitDecorator(table_.TblPr); grid_cols := table_.TblGrid.GridCols(); for i:=0 to length(grid_cols)-1 do grid_cols[i] := new GridColUnitDecorator(grid_cols[i]); {self.}ResetCoordinates(table_.TblPr, grid_cols); {self.}EndX := {self.}StartX; {self.}EndY := {self.}StartY; // 如果是根据内容自适应,应该计算并调整grid_cols的值 {self.}GetCellMatrix(grid_cols); end; function TSPdfTableRange.Do(); begin for _,row in range_array_ do for _,range in row do if ifObj(range) then range.Do(); end; function TSPdfTableRange.GetCellMatrix(grid_cols: array of GridColUnitDecorator); begin trs := table_.Trs(); for i,tr in trs do begin {self.}SetTrPr(tr.TrPr); tr_pr := new TrPrUnitDecorator(tr.TrPr); height := tr_pr.TrHeight.Val; tc_x := {self.}EndX; tc_y := {self.}EndY; tc_h := height; max_height := 0; tcs := tr.Tcs(); pos := 0; for j,tc in tcs do begin if i = 0 then {self.}SetTblStylePr(tc.TcPr, "firstRow"); cell_range := new TSPdfCellRange(docx_to_pdf_, page_, docx_components_ware_, tc, table_.TblPr); cell_range.StartX := tc_x; cell_range.StartY := tc_y; cell_range.FixedHeight := tc_h; cell_range.Width := grid_cols[pos].W; cell_range.LowerBound := {self.}LowerBound; range_array_[i][pos] := cell_range; grid_span := new GridSpanUnitDecorator(tc.TcPr.GridSpan); pos++; for k:=grid_span.Val-1 downto 1 do cell_range.Width += grid_cols[pos++].W; cell_range.Calc(); tc_x += cell_range.Width; if cell_range.DynamicHeight > max_height then max_height := cell_range.DynamicHeight; end if tc_h > max_height then max_height := tc_h; surplus := max_height - ({self.}EndY - {self.}LowerBound); arr := range_array_[i]; for _,range in arr do begin range.AlignHeight(max_height, surplus); {self.}EndY := range.EndY; // 理论上每个range.EndY都是一个值 page_ := range.GetLastPage(); end end for i:=length(range_array_)-1 downto 0 do begin for j:=0 to length(range_array_[i])-1 do begin range := range_array_[i][j]; if ifnil(range) then continue; if range.VMerge then begin if range.VMerge = "restart" then begin break; end else begin range_array_[i-1][j].SetVMergeEdge(range); range_array_[i][j] := nil; end end end end end; function TSPdfTableRange.SetTblStylePr(var tc_pr: TcPr; type: string); begin {self.}SetTcPr(tc_pr); tbl_style_pr := docx_components_ware_.GetTblStylePrByType(table_.TblPr.TblStyle.Val, type); if tbl_style_pr then tc_pr.Copy(tbl_style_pr.TcPr); end; function TSPdfTableRange.ResetCoordinates(tbl_pr: TblPr; grid_cols: array of GridCol); begin total_width := 0; for _,grid_col in grid_cols do total_width += grid_col.W; diff := total_width - {self.}Width; case tbl_pr.jc.Val of "center": begin offset := diff/2; {self.}StartX -= offset; end "right": begin {self.}StartX -= diff; end end; {self.}Width := total_width; end; function TSPdfTableRange.SetTblPr(var tbl_pr: TblPr); begin new_tbl_pr := new TblPr(); {self.}SetTblPrByStyleId(new_tbl_pr, tbl_pr.TblStyle.Val); new_tbl_pr.Copy(tbl_pr); tbl_pr.Copy(new_tbl_pr); end; function TSPdfTableRange.SetTblPrByStyleId(var tbl_pr: TblPr; style_id: string); begin styles := docx_components_ware_.GetStylesAdapter(); style := styles.GetStyleByStyleId(style_id); if ifObj(style) then begin based_on := style.BasedOn.Val; {self.}SetTblPrByStyleId(tbl_pr, based_on); tbl_pr.Copy(style.TblPr); end end; function TSPdfTableRange.SetTrPr(var tr_pr: TrPr); begin new_tr_pr := new TrPr(); {self.}SetTrPrByStyleId(new_tr_pr, table_.TblPr.TblStyle.Val); new_tr_pr.Copy(tr_pr); tr_pr.Copy(new_tr_pr); end; function TSPdfTableRange.SetTrPrByStyleId(var tr_pr: TrPr; style_id: string); begin styles := docx_components_ware_.GetStylesAdapter(); style := styles.GetStyleByStyleId(style_id); if ifObj(style) then begin based_on := style.BasedOn.Val; {self.}SetTrPrByStyleId(tr_pr, based_on); tr_pr.Copy(style.TrPr); end end; function TSPdfTableRange.SetTcPr(var tc_pr: TcPr); begin new_tc_pr := new TcPr(); {self.}SetTcPrByStyleId(new_tc_pr, table_.TblPr.TblStyle.Val); new_tc_pr.Copy(tc_pr); tc_pr.Copy(new_tc_pr); end; function TSPdfTableRange.SetTcPrByStyleId(var tc_pr: TcPr; style_id: string); begin styles := docx_components_ware_.GetStylesAdapter(); style := styles.GetStyleByStyleId(style_id); if ifObj(style) then begin based_on := style.BasedOn.Val; {self.}SetTcPrByStyleId(tc_pr, based_on); tc_pr.Copy(style.TcPr); end end;