1. 支持表格列合并

2. 支持表头背景填充样式
This commit is contained in:
csh 2024-08-14 11:05:47 +08:00
parent 9dc7a66b62
commit 1cd72f6247
6 changed files with 124 additions and 47 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -30,5 +30,5 @@ end;
function TSSectWare.AddElement(element: tslobj);
begin
Elements[length(Elements)] := element;
{self.}Elements[length({self.}Elements)] := element;
end;