PdfConverter/range/TSPdfTableRange.tsf

274 lines
8.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

type TSPdfTableRange = class(TSPdfAbstractRange)
public
function Create(docx_to_pdf: TSDocxToPdf; page: PdfPage; 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
docx_to_pdf_: TSDocxToPdf;
docx_components_: Components;
sect_ware_: TSSectWare;
table_: Tbl;
range_array_: tableArray;
page_: PdfPage;
point_: TSPoint;
end;
function TSPdfTableRange.Create(docx_to_pdf: TSDocxToPdf; page: PdfPage; components: Components; sect_ware: TSSectWare; table: Tbl);
begin
docx_to_pdf_ := docx_to_pdf;
page_ := page;
docx_components_ := Components;
sect_ware_ := sect_ware;
table_ := table;
range_array_ := array();
point_ := new TSPoint(); // 动态记录段落的坐标位置
end;
function TSPdfTableRange.Calc();
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();
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();
point_.Y := 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;
tcs := tr.Tcs();
tc_x := point_.X;
tc_y := point_.Y;
tc_h := height;
max_height := tc_h;
rows_range_array := array();
for i,tc in tcs do
begin
tc_w := grid_cols[i].W;
elements := tc.Elements();
rect_range := new TSPdfRectRange();
rect_range.X := tc_x;
rect_range.Y := tc_y;
rect_range.W := tc_w;
rect_range.H := tc_h;
rect_range.Page := page_;
rows_range_array[length(rows_range_array)] := rect_range;
cell_x := tc_x + tbl_pr.TblCellMar.Left.W;
cell_y := tc_y - tbl_pr.TblCellMar.Top.W;
cell_w := tc_w - tbl_pr.TblCellMar.Right.W - tbl_pr.TblCellMar.Left.W;
cell_total_h := 0;
for _,element in elements do
begin
range := nil;
if element.LocalName = "p" then
begin
range := new TSPdfParagraphRange(docx_to_pdf_, page_, 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_, page_, docx_components_, sect_ware_, element);
end
if ifObj(range) then
begin
range.X := cell_x;
range.Y := cell_y;
range.W := cell_w;
range.H := tc_h;
range.Calc();
rows_range_array[length(rows_range_array)] := range;
cell_total_h += range.H;
cell_y -= range.H;
end
end
tc_x += tc_w;
if cell_total_h > max_height then max_height := cell_total_h;
end
// 判定是否跨页
total_height := max_height + tbl_pr.TblCellMar.Top.W + tbl_pr.TblCellMar.Bottom.W;
surplus := total_height - (point_.Y - sect_ware_.SectPr.PgMar.Bottom);
if not self.H and surplus > 0 then
begin
for _,range in rows_range_array do
range.H := point_.Y - sect_ware_.SectPr.PgMar.Bottom;
span := sect_ware_.SectPr.PgSz.H - sect_ware_.SectPr.PgMar.Top - sect_ware_.SectPr.PgMar.Bottom;
quotient := surplus div span;
remainder := surplus % span;
page := page_;
tc_y := point_.Y;
i := 0;
while i < quotient do
begin
tc_x := point_.X;
tc_y := sect_ware_.SectPr.PgSz.H - sect_ware_.SectPr.PgMar.Top;
tc_h := tc_y - sect_ware_.SectPr.PgMar.Bottom;
page := docx_to_pdf_.GetNextPage(page);
for j:=0 to length(tcs)-1 do
begin
tc_w := grid_cols[i].W;
rect_range := new TSPdfRectRange();
rect_range.X := tc_x;
rect_range.Y := tc_y;
rect_range.W := tc_w;
rect_range.H := tc_h;
rect_range.Page := page;
tc_x += tc_w;
rows_range_array[length(rows_range_array)] := rect_range;
end
i++;
end
if remainder then
begin
tc_x := point_.X;
tc_y := sect_ware_.SectPr.PgSz.H - sect_ware_.SectPr.PgMar.Top;
tc_h := remainder;
page := docx_to_pdf_.GetNextPage(page);
for j:=0 to length(tcs)-1 do
begin
tc_w := grid_cols[i].W;
rect_range := new TSPdfRectRange();
rect_range.X := tc_x;
rect_range.Y := tc_y;
rect_range.W := tc_w;
rect_range.H := tc_h;
rect_range.Page := page;
tc_x += tc_w;
rows_range_array[length(rows_range_array)] := rect_range;
end
end
point_.Y := tc_y - remainder;
self.Y := point_.Y;
page_ := page;
end
else begin
tc_h := tc_h ? tc_h : max_height;
for _,range in rows_range_array do
range.H := tc_h;
point_.Y -= tc_h;
self.Y := point_.Y;
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();
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;