type TSPdfTableRange = class(TSPdfBasicRange) public function Create(docx_to_pdf: TSDocxToPdf; pg: TSPage; components: Components; sect_ware: TSSectWare; paragraph: P); function Calc(); function Do();override; private function ProcessTrData(grid_cols: array of GridCol; tr: Tr; tbl_pr: TblPr): array of TSPdfAbstractRange; function ResetCoordinates(tbl_pr: TblPr; grid_cols: array of GridCol); function CheckAndAddPage(y: real; offset: real): boolean; 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); private [weakref]docx_to_pdf_: TSDocxToPdf; [weakref]docx_components_ware_: Components; [weakref]sect_ware_: TSSectWare; [weakref]table_: Tbl; [weakref]page_: TSPage; [weakref]range_array_: tableArray; point_: TSPoint; end; function TSPdfTableRange.Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; sect_ware: TSSectWare; table: Tbl); begin docx_to_pdf_ := docx_to_pdf; page_ := pg; docx_components_ware_ := Components; sect_ware_ := sect_ware; table_ := table; range_array_ := array(); {self.}TSPage := page_; end; function TSPdfTableRange.Calc(); begin // return; {self.}SetTblPr(table_.TblPr); tbl_pr := 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(tbl_pr, grid_cols); {self.}EndX := {self.}StartX; {self.}EndY := {self.}StartY; // 如果是根据内容自适应,应该计算并调整grid_cols的值 trs := table_.Trs(); for i,tr in trs do range_array_[i] := {self.}ProcessTrData(grid_cols, tr, tbl_pr); end; function TSPdfTableRange.Do(); begin for _,row in range_array_ do for _,range in row do range.Do(); end; function TSPdfTableRange.CheckAndAddPage(y: real; offset: real): boolean; begin if y - offset < sect_ware_.SectPr.PgMar.Bottom then begin page_ := docx_to_pdf_.GetNextPage(page_); if ifnil(page_) then page_ := docx_to_pdf_.AddPage(sect_ware_); point := docx_to_pdf_.GetCurrentPoint(); {self.}EndY := point.Y; return true; end return false; end; function TSPdfTableRange.ProcessTrData(grid_cols: array of GridCol; tr: Tr; tbl_pr: TblPr): array of TSPdfAbstractRange; 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; cell_range_array := array(); tcs := tr.Tcs(); for i,tc in tcs do begin cell_range := new TSPdfCellRange(docx_to_pdf_, page_, docx_components_ware_, sect_ware_, tc, tbl_pr); cell_range.StartX := tc_x; cell_range.StartY := tc_y; cell_range.Width := grid_cols[i].W; cell_range.FixedHeight := tc_h; cell_range.Calc(); tc_x += grid_cols[i].W; if cell_range.DynamicHeight > max_height then max_height := cell_range.DynamicHeight; cell_range_array[length(cell_range_array)] := cell_range; end if tc_h > max_height then max_height := tc_h; surplus := max_height - ({self.}EndY - sect_ware_.SectPr.PgMar.Bottom); for _,range in cell_range_array do begin range.AlignHeight(max_height, surplus); {self.}EndY := range.EndY; // 理论上每个range.EndY都是一个值 page_ := range.GetLastPage(); end return cell_range_array; 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.StyleId(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.StyleId(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.StyleId(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;