274 lines
8.8 KiB
Plaintext
274 lines
8.8 KiB
Plaintext
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;
|