type TSPdfTableRange = class(TSPdfAbstractRange) public function Create(docx_to_pdf: TSDocxToPdf; components: Components; sect_ware: TSSectWare; paragraph: P); function Calc(): tableArray; 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 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 docx_to_pdf_: TSDocxToPdf; docx_components_: Components; sect_ware_: TSSectWare; table_: Tbl; range_array_: array of TSPdfAbstractRange; page_: PdfPage; point_: TSPoint; end; function TSPdfTableRange.Create(docx_to_pdf: TSDocxToPdf; components: Components; sect_ware: TSSectWare; table: Tbl); begin docx_to_pdf_ := docx_to_pdf; docx_components_ := Components; sect_ware_ := sect_ware; table_ := table; page_ := docx_to_pdf_.GetCurrentPage(); range_array_ := array(); point_ := new TSPoint(); // 动态记录段落的坐标位置 end; function TSPdfTableRange.Calc(): tableArray; begin 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); point_.X := self.X; point_.Y := self.Y; // 如果是根据内容自适应,应该计算并调整grid_cols的值 trs := table_.Trs(); matrix := array(); for i,tr in trs do matrix[i] := self.ProcessTrData(grid_cols, tr, tbl_pr); return matrix; 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); tcs := tr.Tcs(); rows_range_array := array(); for _,tc in tcs do begin elements := tc.Elements(); rect_range := new TSPdfRectRange(); rect_range.X := point_.X; rect_range.Y := point_.Y; rect_range.W := grid_col.W; rect_range.H := 100; rows_range_array[length(rows_range_array)] := rect_range; for _,element in elements do begin range := nil; if element.LocalName = "p" then begin range := new TSPdfParagraphRange(docx_to_pdf_, docx_components_, sect_ware_, element); range.SetExtraStyleId(tbl_pr.TblStyle.Val); end else if element.LocalName = "tbl" then begin range := new TSPdfTableRange(docx_to_pdf_, docx_components_, sect_ware_, element); end if ifObj(range) then begin range.X := point_.X - tbl_pr.TblCellMar.Left.W; range.Y := point_.Y - tbl_pr.TblCellMar.Top.W; range.W := grid_col.W - tbl_pr.TblCellMar.Right.W; range.H := nil; ret := range.Calc(); point_.Y := range.Y; point_.X += grid_col.W; rows_range_array[length(rows_range_array)] := range; end end end return rows_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.W; case tbl_pr.jc.Val of "center": begin offset := diff/2; self.X -= offset; end "right": begin self.X -= diff; end end; self.W := total_width; end; function TSPdfTableRange.SetTblPr(var tbl_pr: TblPr); begin new_tbl_pr := new TblPr(); tbl_pr.TblStyle.XmlNode.print; 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 := class(TSPdfSingletonKit).GetComponent(docx_components_, "styles_adapter"); 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 := class(TSPdfSingletonKit).GetComponent(docx_components_, "styles_adapter"); 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 := class(TSPdfSingletonKit).GetComponent(docx_components_, "styles_adapter"); 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;