diff --git a/TSDocxToPdf.tsf b/TSDocxToPdf.tsf index 1cbfc5f..378bfe6 100644 --- a/TSDocxToPdf.tsf +++ b/TSDocxToPdf.tsf @@ -44,10 +44,10 @@ private current_page_: TSPage; point_: TSPoint; // 定位坐标点 page_array_: array of TSPage; - toc_array_: tableArray; - toc_unmacthed_array_: tableArray; sect_ware_: TSSectWare; sect_pr_adapter_: SectPrAdapter; + toc_array_: tableArray; + toc_unmacthed_array_: tableArray; range_page_number_array_: tableArray; end; @@ -100,12 +100,15 @@ begin elements := sect_ware.Elements; for _,element in elements do begin + // if _ = 64 then + // if _ = 19 then + // println("_ = {}", _); if element.LocalName = "p" then {self.}TransformP(sect_ware, element); else if element.LocalName = "tbl" then {self.}TransformTbl(sect_ware, element); else if element.LocalName = "sdt" then {self.}TransformSdt(sect_ware, element); end end - ProcessNumpages(); + {self.}ProcessNumpages(); end; function TSDocxToPdf.GetCurrentPoint(): Point; @@ -197,7 +200,8 @@ begin page.SetHeight(sect_ware_.SectPr.PgSz.H); len := length(page_array_); - start := ifString(sect_ware.SectPr.PgNumType.Start) and trystrtoint(sect_ware.SectPr.PgNumType.Start, r) ? r : 0; + start := sect_ware.SectPr.PgNumType.Start; + println("start = {}, type = {}", start, ifInt(start)); current_page_ := new TSPage(); current_page_.Index := len; current_page_.PdfPage := page; @@ -278,7 +282,7 @@ begin {self.}ResetCoordinates(sect_ware); len := length(page_array_); - start := ifString(sect_ware.SectPr.PgNumType.Start) and trystrtoint(sect_ware.SectPr.PgNumType.Start, r) ? r : 0; + start := sect_ware.SectPr.PgNumType.Start; current_page_ := new TSPage(); current_page_.Index := len; current_page_.PdfPage := page; diff --git a/range/Advanced/TSPdfCellRange.tsf b/range/Advanced/TSPdfCellRange.tsf index 0d07ba0..d68aec8 100644 --- a/range/Advanced/TSPdfCellRange.tsf +++ b/range/Advanced/TSPdfCellRange.tsf @@ -5,6 +5,11 @@ public function AlignHeight(height: real; surplus: real); function GetLastPage(); function Do();override; + function SetVMergeEdge(range: TSPdfCellRange); + function GetRegionArr(): array of Region; + +public + VMerge; private [weakref]docx_to_pdf_: TSDocxToPdf; @@ -37,6 +42,7 @@ begin tbl_pr_ := tbl_pr; region_array_ := array(); {self.}TSPage := page_; + {self.}VMerge := tc_.TcPr.XmlChildVMerge.Val ? tc_.TcPr.XmlChildVMerge.Val : tc_.TcPr.VMerge; end; function TSPdfCellRange.Calc(); @@ -47,6 +53,7 @@ begin region.RectangleRange.Width := {self.}Width; region.RectangleRange.FixedHeight := {self.}FixedHeight; region.RectangleRange.TSPage := page_; + region.RectangleRange.TcPr := tc_.TcPr; region_array_[length(region_array_)] := region; {self.}EndX := {self.}StartX; @@ -118,6 +125,7 @@ begin region.RectangleRange.Width := {self.}Width; region.RectangleRange.DynamicHeight := span; region.RectangleRange.TSPage := page_; + region.RectangleRange.TcPr := tc_.TcPr; region_array_[length(region_array_)] := region; surplus -= span; hash[region.RectangleRange.TSPage.Index] := region; @@ -131,6 +139,7 @@ begin region.RectangleRange.Width := {self.}Width; region.RectangleRange.DynamicHeight := surplus; region.RectangleRange.TSPage := page_; + region.RectangleRange.TcPr := tc_.TcPr; region_array_[length(region_array_)] := region; hash[region.RectangleRange.TSPage.Index] := region; {self.}EndY := region.RectangleRange.EndY - surplus; @@ -146,3 +155,16 @@ function TSPdfCellRange.GetLastPage(); begin return page_; end; + +function TSPdfCellRange.GetRegionArr(): array of Region; +begin + return region_array_; +end; + +function TSPdfCellRange.SetVMergeEdge(range: TSPdfCellRange); +begin + rect := region_array_[length(region_array_)-1].RectangleRange; + range_rect := range.GetRegionArr(); + range_rect := range_rect[0].RectangleRange; + rect.DynamicHeight += range_rect.DynamicHeight; +end; diff --git a/range/Advanced/TSPdfTableRange.tsf b/range/Advanced/TSPdfTableRange.tsf index f0d2638..6c825fa 100644 --- a/range/Advanced/TSPdfTableRange.tsf +++ b/range/Advanced/TSPdfTableRange.tsf @@ -5,7 +5,7 @@ public function Do();override; private - function ProcessTrData(grid_cols: array of GridCol; tr: Tr; tbl_pr: TblPr): array of TSPdfAbstractRange; + 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); @@ -13,6 +13,7 @@ private 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; @@ -20,7 +21,7 @@ private [weakref]sect_ware_: TSSectWare; [weakref]table_: Tbl; [weakref]page_: TSPage; - [weakref]range_array_: tableArray; + range_array_: tableArray; end; function TSPdfTableRange.Create(docx_to_pdf: TSDocxToPdf; pg: PdfPage; components: Components; sect_ware: TSSectWare; table: Tbl); @@ -36,65 +37,92 @@ end; function TSPdfTableRange.Calc(); begin - // return; {self.}SetTblPr(table_.TblPr); - tbl_pr := new TblPrUnitDecorator(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(tbl_pr, grid_cols); + {self.}ResetCoordinates(table_.TblPr, 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); + {self.}GetCellMatrix(grid_cols); end; function TSPdfTableRange.Do(); begin for _,row in range_array_ do for _,range in row do - range.Do(); + if ifObj(range) then range.Do(); end; -function TSPdfTableRange.ProcessTrData(grid_cols: array of GridCol; tr: Tr; tbl_pr: TblPr): array of TSPdfAbstractRange; +function TSPdfTableRange.GetCellMatrix(grid_cols: array of GridColUnitDecorator); 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 + trs := table_.Trs(); + for i,tr in trs 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; - if i = length(tcs)-1 and i <> length(grid_cols)-1 then + {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 - for j:=i+1 to length(grid_cols)-1 do - cell_range.Width += grid_cols[j].W; + if i = 0 then {self.}SetTblStylePr(tc.TcPr, "firstRow"); + cell_range := new TSPdfCellRange(docx_to_pdf_, page_, docx_components_ware_, sect_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; + 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 - sect_ware_.SectPr.PgMar.Bottom); + 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 - 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 + for i:=length(range_array_)-1 downto 0 do begin - range.AlignHeight(max_height, surplus); - {self.}EndY := range.EndY; // 理论上每个range.EndY都是一个值 - page_ := range.GetLastPage(); + 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 - return cell_range_array; +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); diff --git a/range/basic/TSPdfRectangleRange.tsf b/range/basic/TSPdfRectangleRange.tsf index abc07fb..54151a5 100644 --- a/range/basic/TSPdfRectangleRange.tsf +++ b/range/basic/TSPdfRectangleRange.tsf @@ -1,8 +1,10 @@ type TSPdfRectangleRange = class(TSPdfBasicRange) +uses TSColorToolKit; public function Create(); function Do();override; - +public + TcPr: TcPr; end; function TSPdfRectangleRange.Create(); @@ -14,8 +16,16 @@ function TSPdfRectangleRange.Do();override; begin // {self.}Page.SetRGBStroke(1.0, 0.0, 0.0); // println("page = {}, endx = {}, endy = {}, DynamicHeight = {}, Width = {}", {self.}Page, {self.}EndX, {self.}EndY, {self.}DynamicHeight, {self.}Width); + if {self.}TcPr.Shd.Fill then + begin + [r, g, b] := TSColorToolKit.HexToRGB({self.}TcPr.Shd.Fill); + {self.}TSPage.PdfPage.SetRGBFill(r/255, g/255, b/255); + {self.}TSPage.PdfPage.Rectangle({self.}EndX, {self.}EndY - {self.}DynamicHeight, {self.}Width, {self.}DynamicHeight); + {self.}TSPage.PdfPage.Fill(); + {self.}TSPage.PdfPage.SetRGBFill(0, 0, 0); + end {self.}TSPage.PdfPage.SetGrayStroke(0.5); - {self.}TSPage.PdfPage.SetLineWidth(0.5); + {self.}TSPage.PdfPage.SetLineWidth(0.25); {self.}TSPage.PdfPage.Rectangle({self.}EndX, {self.}EndY - {self.}DynamicHeight, {self.}Width, {self.}DynamicHeight); {self.}TSPage.PdfPage.Stroke(); {self.}TSPage.PdfPage.SetGrayStroke(0); diff --git a/ware/TSDocxComponentsWare.tsf b/ware/TSDocxComponentsWare.tsf index c78125c..8899aa6 100644 --- a/ware/TSDocxComponentsWare.tsf +++ b/ware/TSDocxComponentsWare.tsf @@ -5,17 +5,20 @@ public function GetStylesAdapter(): StylesAdapter; function GetDocumentRelsAdapter(): RelationShipsAdapter; function GetNumberingWare(): TSNumberingWare; + function GetTblStylePrByType(style_id: string; type: string): TblStylePr; private styles_deserialize_flag_; styles_adapter_; document_rels_adapter_; numbering_ware_; + tbl_style_pr_hash_; end; function TSDocxComponentsWare.Create(); begin class(Components).Create(); + tbl_style_pr_hash_ := array(); end; function TSDocxComponentsWare.GetStyles(): Styles; @@ -50,3 +53,13 @@ begin return numbering_ware_; end; +function TSDocxComponentsWare.GetTblStylePrByType(style_id: string; type: string): TblStylePr; +begin + if tbl_style_pr_hash_[style_id][type] then return tbl_style_pr_hash_[style_id][type]; + styles_adapter := {self.}GetStylesAdapter(); + style := styles_adapter.GetStyleByStyleId(style_id); + style := new StyleAdapter(style); + tbl_style_pr := style.GetTblStylePrByType(type); + tbl_style_pr_hash_[style_id][type] := tbl_style_pr; + return tbl_style_pr; +end; diff --git a/ware/TSSectWare.tsf b/ware/TSSectWare.tsf index b283c89..11044b9 100644 --- a/ware/TSSectWare.tsf +++ b/ware/TSSectWare.tsf @@ -30,5 +30,5 @@ end; function TSSectWare.AddElement(element: tslobj); begin - Elements[length(Elements)] := element; + {self.}Elements[length({self.}Elements)] := element; end;