From 6a9ef161396e869b28d2b4d3ae865d619ef99071 Mon Sep 17 00:00:00 2001 From: KarlKallman Date: Tue, 25 Aug 2026 15:10:17 +0200 Subject: [PATCH 1/4] WIP --- src/EPPlus.Export.Pdf.Tests/PdfTests.cs | 12 ++++++ .../Settings/PdfPageSettings.cs | 4 +- src/EPPlus/Export/PdfExport/Data/PageData.cs | 2 + .../PdfExport/Layout/PdfGridlinesLayout.cs | 16 +++++--- .../Export/PdfExport/Layout/PdfLayout.cs | 37 +++++++++++++++++++ 5 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/EPPlus.Export.Pdf.Tests/PdfTests.cs b/src/EPPlus.Export.Pdf.Tests/PdfTests.cs index 8ab741f0c..4f05b1de4 100644 --- a/src/EPPlus.Export.Pdf.Tests/PdfTests.cs +++ b/src/EPPlus.Export.Pdf.Tests/PdfTests.cs @@ -14,6 +14,7 @@ Date Author Change using EPPlus.Export.Pdf.Tests; using OfficeOpenXml; using OfficeOpenXml.Export.PdfExport; +using OfficeOpenXml.Export.PdfExport.Layout; using OfficeOpenXml.Style; using System.Text; @@ -637,5 +638,16 @@ public void EPPlusToPdf() p.Workbook.SaveAsPdf(_pdfPath + "Snake.Pdf"); p.SaveAs(_pdfPath + "Snake.xlsx"); } + [TestMethod] + public void CenterOnPageTest() + { + using (var p = OpenTemplatePackage("CenterOnPagePdf.xlsx")) + { + var wb = p.Workbook; + var ws = wb.Worksheets[0]; + string path = _pdfPath + "CenterOnPagePdf.pdf"; + ws.SaveAsPdf(path); + } + } } } diff --git a/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs b/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs index 5416f1887..d3d6efbc4 100644 --- a/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs +++ b/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs @@ -200,8 +200,8 @@ public PdfScaling Scaling internal string defaultFontName = ""; //DEBUG - internal bool Debug = false; - internal bool PrintAsText = false; + internal bool Debug = true; + internal bool PrintAsText = true; public PdfPageSettings(OpenTypeFontEngine fontEngine) { diff --git a/src/EPPlus/Export/PdfExport/Data/PageData.cs b/src/EPPlus/Export/PdfExport/Data/PageData.cs index 6a7d8c510..ab3056461 100644 --- a/src/EPPlus/Export/PdfExport/Data/PageData.cs +++ b/src/EPPlus/Export/PdfExport/Data/PageData.cs @@ -39,6 +39,8 @@ internal struct Page public double[] RowHeights; public double HeadingWidth; public double HeadingHeight; + public double UsedWidth; + public double UsedHeight; } internal struct Pages diff --git a/src/EPPlus/Export/PdfExport/Layout/PdfGridlinesLayout.cs b/src/EPPlus/Export/PdfExport/Layout/PdfGridlinesLayout.cs index d2f9f50e7..8b432e073 100644 --- a/src/EPPlus/Export/PdfExport/Layout/PdfGridlinesLayout.cs +++ b/src/EPPlus/Export/PdfExport/Layout/PdfGridlinesLayout.cs @@ -50,7 +50,8 @@ public static void AddGridLines(PdfPageSettings pageSettings, Page page, PdfPage // colX[ci] = X of left edge of column ci (0-based within page). // colX[colCount] = X of right edge of last column. var colX = new double[colCount + 1]; - colX[0] = pageSettings.ContentBounds.Left + page.HeadingWidth + page.PrintTitleWidth; + //colX[0] = pageSettings.ContentBounds.Left + page.HeadingWidth + page.PrintTitleWidth; + colX[0] = PdfLayout.GetOriginX(pageSettings, page) + page.HeadingWidth + page.PrintTitleWidth; for (int ci = 0; ci < colCount; ci++) { var cell = page.Map[page.FromRow, page.FromColumn + ci]; @@ -61,9 +62,10 @@ public static void AddGridLines(PdfPageSettings pageSettings, Page page, PdfPage // rowY[rowCount] = Y of bottom edge of last row. // Y decreases downward (PDF coordinate system used throughout GetCatalog). var rowY = new double[rowCount + 1]; - rowY[0] = pageSettings.ContentBounds.Top - page.HeadingHeight - page.PrintTitleHeight; + //rowY[0] = pageSettings.ContentBounds.Top - page.HeadingHeight - page.PrintTitleHeight; + rowY[0] = PdfLayout.GetOriginY(pageSettings, page) - page.HeadingHeight - page.PrintTitleHeight; - for (int ri = 0; ri < rowCount; ri++) + for (int ri = 0; ri < rowCount; ri++) { rowY[ri + 1] = rowY[ri] - page.RowHeights[ri]; } @@ -72,9 +74,13 @@ public static void AddGridLines(PdfPageSettings pageSettings, Page page, PdfPage // Always computed so BorderLines is available for margin clipping regardless of // whether ShowGridLines is on. When borderOnly is true we stop here. - double frameLeft = pageSettings.ContentBounds.Left; //colX[0]; + //double frameLeft = pageSettings.ContentBounds.Left; //colX[0]; + //double frameRight = colX[colCount]; + //double frameTop = pageSettings.ContentBounds.Top; //rowY[0]; + //double frameBottom = rowY[rowCount]; + double frameLeft = PdfLayout.GetOriginX(pageSettings, page); double frameRight = colX[colCount]; - double frameTop = pageSettings.ContentBounds.Top; //rowY[0]; + double frameTop = PdfLayout.GetOriginY(pageSettings, page); double frameBottom = rowY[rowCount]; pageLayout.BorderLines.Add(new GridLine(frameLeft, frameTop, frameRight, frameTop)); diff --git a/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs b/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs index f4c4f1a9a..27f1f7ae5 100644 --- a/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs +++ b/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs @@ -1410,6 +1410,20 @@ internal static Pages MapPage(PdfRange range, Pages pdfPages) page.Map[row, col] = range.Map[row, col]; } } + double usedWidth = page.HeadingWidth + page.PrintTitleWidth; + for (int col = page.FromColumn; col <= page.ToColumn; col++) + { + usedWidth += page.Map[page.FromRow, col]?.ColumnWidth ?? 0d; + } + page.UsedWidth = usedWidth; + + double usedHeight = page.HeadingHeight + page.PrintTitleHeight; + for (int ri = 0; ri < page.RowHeights.Length; ri++) + { + usedHeight += page.RowHeights[ri]; + } + page.UsedHeight = usedHeight; + pdfPages.Page[i] = page; } pdfPages = pages; @@ -1613,5 +1627,28 @@ private static void EmitBandFrameV(List target, PdfRange range, double } if (rs != null) target.Add(new GridLine(x, rs.Value, x, re)); } + + /// + /// The X coordinate where the page's printed block begins. + /// Currently the left content bound; will include the centering offset. + /// + internal static double GetOriginX(PdfPageSettings pageSettings, Page page) + { + if (!pageSettings.CenterOnPageHorizontally) return pageSettings.ContentBounds.Left; + + var offset = (pageSettings.ContentBounds.Width - page.UsedWidth) / 2d; + return pageSettings.ContentBounds.Left + Math.Max(0d, offset); + } + + /// + /// The Y coordinate where the page's printed block begins (top edge). + /// + internal static double GetOriginY(PdfPageSettings pageSettings, Page page) + { + if (!pageSettings.CenterOnPageVertically) return pageSettings.ContentBounds.Top; + + var offset = (pageSettings.ContentBounds.Height - page.UsedHeight) / 2d; + return pageSettings.ContentBounds.Top - Math.Max(0d, offset); + } } } From 5031a1f97b2439ff46ff04b07fec401039b61556 Mon Sep 17 00:00:00 2001 From: KarlKallman Date: Wed, 26 Aug 2026 16:30:01 +0200 Subject: [PATCH 2/4] WIP --- src/EPPlus.Export.Pdf.Tests/PdfTests.cs | 39 ++++++++++++++++ .../Export/PdfExport/Layout/PdfLayout.cs | 45 ++++++++++--------- 2 files changed, 63 insertions(+), 21 deletions(-) diff --git a/src/EPPlus.Export.Pdf.Tests/PdfTests.cs b/src/EPPlus.Export.Pdf.Tests/PdfTests.cs index 4f05b1de4..18fa9a4f2 100644 --- a/src/EPPlus.Export.Pdf.Tests/PdfTests.cs +++ b/src/EPPlus.Export.Pdf.Tests/PdfTests.cs @@ -14,7 +14,9 @@ Date Author Change using EPPlus.Export.Pdf.Tests; using OfficeOpenXml; using OfficeOpenXml.Export.PdfExport; +using OfficeOpenXml.Export.PdfExport.Data; using OfficeOpenXml.Export.PdfExport.Layout; +using OfficeOpenXml.FormulaParsing.Excel.Functions.Information; using OfficeOpenXml.Style; using System.Text; @@ -638,6 +640,7 @@ public void EPPlusToPdf() p.Workbook.SaveAsPdf(_pdfPath + "Snake.Pdf"); p.SaveAs(_pdfPath + "Snake.xlsx"); } + [TestMethod] public void CenterOnPageTest() { @@ -645,9 +648,45 @@ public void CenterOnPageTest() { var wb = p.Workbook; var ws = wb.Worksheets[0]; + ws.HeaderFooter.OddFooter.LeftAlignedText = "Confidential Report"; + string path = _pdfPath + "CenterOnPagePdf.pdf"; ws.SaveAsPdf(path); } } + + [TestMethod] + public void GetOriginX_CenteringOff_ReturnsContentBoundsLeft() + { + var s = new PdfPageSettings(null); + var p = new Page() + { + FromRow = 1, ToRow = 10, FromColumn = 1, ToColumn = 5, + UsedWidth = 100, + UsedHeight = 100, + RowHeights = new double[10] + }; + + Assert.AreEqual(s.ContentBounds.Left, PdfLayout.GetOriginX(s, p), 0.0001); + } + + [TestMethod] + public void GetOrigin_FlagsAreIndependent() + { + var s = new PdfPageSettings(null); + s.CenterOnPageHorizontally = true; + var p = new Page() + { + FromRow = 1, + ToRow = 10, + FromColumn = 1, + ToColumn = 5, + UsedWidth = s.ContentBounds.Width - 100d, + UsedHeight = s.ContentBounds.Height - 200d, + RowHeights = new double[10] + }; + Assert.AreEqual(s.ContentBounds.Left + 50d, PdfLayout.GetOriginX(s, p), 0.0001); + Assert.AreEqual(s.ContentBounds.Top, PdfLayout.GetOriginY(s, p), 0.0001); + } } } diff --git a/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs b/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs index 27f1f7ae5..61048bbac 100644 --- a/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs +++ b/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs @@ -88,8 +88,9 @@ internal static Transform GetCatalog(PdfPageSettings pageSettings, PdfDictionari pageLayout.PrintTitleWidth = page.PrintTitleWidth; pageLayout.PrintTitleHeight = page.PrintTitleHeight; var drawnMergedCells = new HashSet(); - double contentStartX = pageSettings.ContentBounds.Left + page.HeadingWidth + page.PrintTitleWidth; - double contentStartY = pageSettings.ContentBounds.Top - page.HeadingHeight - page.PrintTitleHeight; + //double contentStartX = pageSettings.ContentBounds.Left + page.HeadingWidth + page.PrintTitleWidth; + double contentStartX = GetOriginX(pageSettings, page) + page.HeadingWidth + page.PrintTitleWidth; + double contentStartY = GetOriginY(pageSettings, page) - page.HeadingHeight - page.PrintTitleHeight; if (pageSettings.ShowHeadings && !pdfPages[i].IsCommentsPage) { AddHeadingCells(pageSettings, dictionaries, page, pageLayout, contentStartX, contentStartY, page.HeadingWidth, page.HeadingHeight, pdfPages[i].HeadingFontName, pdfPages[i].HeadingFontSize, pdfPages[i].HeadingFill); @@ -458,7 +459,7 @@ private static void AddHeadingCells(PdfPageSettings pageSettings, PdfDictionarie { var headingStyle = new PdfCellStyle(); headingStyle.xfFill = fill; - var cornerFill = new PdfCellLayout(pageSettings.ContentBounds.Left, pageSettings.ContentBounds.Top, headingWidth, headingHeight); + var cornerFill = new PdfCellLayout(GetOriginX(pageSettings, page), GetOriginY(pageSettings, page), headingWidth, headingHeight); SetFill(dictionaries, headingStyle, "", cornerFill); cornerFill.Name = "Heading_Corner"; cornerFill.UpdateShadingPositionMatrix(pageSettings); @@ -470,7 +471,7 @@ private static void AddHeadingCells(PdfPageSettings pageSettings, PdfDictionarie if (colWidth == 0d) { x += colWidth; continue; } string colLetter = ExcelCellBase.GetColumnLetter(col); AddHeadingCell(pageSettings, dictionaries, pageLayout, headingStyle, colLetter, - x, pageSettings.ContentBounds.Top, colWidth, headingHeight, fontName, fontSize, "Heading_Col_" + colLetter); + x, GetOriginY(pageSettings, page), colWidth, headingHeight, fontName, fontSize, "Heading_Col_" + colLetter); x += colWidth; } double y = contentStartY; @@ -480,7 +481,7 @@ private static void AddHeadingCells(PdfPageSettings pageSettings, PdfDictionarie if (rowHeight == 0d) { y -= rowHeight; continue; } string rowNum = row.ToString(); AddHeadingCell(pageSettings, dictionaries, pageLayout, headingStyle, rowNum, - pageSettings.ContentBounds.Left, y, headingWidth, rowHeight, fontName, fontSize, "Heading_Row_" + rowNum); + GetOriginX(pageSettings, page), y, headingWidth, rowHeight, fontName, fontSize, "Heading_Row_" + rowNum); y -= rowHeight; } } @@ -716,7 +717,8 @@ private static Page PrecomputePageMergedCells(PdfPageSettings pageSettings, PdfR } // --- Y --- // Replace the * 15d line with a sum of real row heights - double drawY = pageSettings.ContentBounds.Top - page.HeadingHeight - page.PrintTitleHeight; + //double drawY = pageSettings.ContentBounds.Top - page.HeadingHeight - page.PrintTitleHeight; + double drawY = GetOriginY(pageSettings, page) - page.HeadingHeight - page.PrintTitleHeight; for (int r = page.FromRow; r < row; r++) { drawY -= range.RowHeights[r - range.Range._fromRow].Height; @@ -765,7 +767,8 @@ private static double[] BuildColumnXPositions(PdfPageSettings pageSettings, Page { int colCount = page.ToColumn - page.FromColumn + 1; var colX = new double[colCount]; - double x = pageSettings.ContentBounds.Left + page.HeadingWidth + page.PrintTitleWidth; + //double x = pageSettings.ContentBounds.Left + page.HeadingWidth + page.PrintTitleWidth; + double x = GetOriginY(pageSettings, page) + page.HeadingWidth + page.PrintTitleWidth; for (int col = page.FromColumn; col <= page.ToColumn; col++) { colX[col - page.FromColumn] = x; @@ -817,7 +820,7 @@ private static Page PrecomputePagePrintTitleCells(PdfPageSettings pageSettings, // Content-column X: same origin/widths the content loop uses (step-2 origin). var contentColX = new Dictionary(); - double cx = pageSettings.ContentBounds.Left + page.HeadingWidth + page.PrintTitleWidth; + double cx = PdfLayout.GetOriginX(pageSettings, page) + page.HeadingWidth + page.PrintTitleWidth; for (int c = page.FromColumn; c <= page.ToColumn; c++) { contentColX[c] = cx; @@ -825,7 +828,7 @@ private static Page PrecomputePagePrintTitleCells(PdfPageSettings pageSettings, } // Content-row Y. var contentRowY = new Dictionary(); - double cy = pageSettings.ContentBounds.Top - page.HeadingHeight - page.PrintTitleHeight; + double cy = GetOriginY(pageSettings, page) - page.HeadingHeight - page.PrintTitleHeight; for (int r = page.FromRow; r <= page.ToRow; r++) { contentRowY[r] = cy; @@ -835,7 +838,7 @@ private static Page PrecomputePagePrintTitleCells(PdfPageSettings pageSettings, var titleColX = new Dictionary(); if (leftBand) { - double tx = pageSettings.ContentBounds.Left + page.HeadingWidth; + double tx = GetOriginX(pageSettings, page) + page.HeadingWidth; for (int c = pdfSheet.PrintTitleColFrom; c <= pdfSheet.PrintTitleColTo; c++) { titleColX[c] = tx; @@ -846,7 +849,7 @@ private static Page PrecomputePagePrintTitleCells(PdfPageSettings pageSettings, var titleRowY = new Dictionary(); if (topBand) { - double ty = pageSettings.ContentBounds.Top - page.HeadingHeight; + double ty = GetOriginY(pageSettings, page) - page.HeadingHeight; for (int r = pdfSheet.PrintTitleRowFrom; r <= pdfSheet.PrintTitleRowTo; r++) { titleRowY[r] = ty; @@ -889,7 +892,7 @@ private static Page PrecomputePagePrintTitleCells(PdfPageSettings pageSettings, { IsRow = true, Index = r, - X = pageSettings.ContentBounds.Left, + X = GetOriginX(pageSettings, page), Y = titleRowY[r], Width = page.HeadingWidth, Height = h @@ -906,7 +909,7 @@ private static Page PrecomputePagePrintTitleCells(PdfPageSettings pageSettings, IsRow = false, Index = c, X = titleColX[c], - Y = pageSettings.ContentBounds.Top, + Y = GetOriginY(pageSettings, page), Width = w, Height = page.HeadingHeight }); @@ -916,24 +919,24 @@ private static Page PrecomputePagePrintTitleCells(PdfPageSettings pageSettings, // repeated title-row text continues onto the next horizontal page's band if (topBand) AddIncomingSpill(page, range, pdfSheet.PrintTitleRowFrom, pdfSheet.PrintTitleRowTo, page.FromColumn, page.ToColumn, - pageSettings.ContentBounds.Left + page.HeadingWidth + page.PrintTitleWidth, - pageSettings.ContentBounds.Top - page.HeadingHeight, + GetOriginX(pageSettings, page) + page.HeadingWidth + page.PrintTitleWidth, + GetOriginY(pageSettings, page) - page.HeadingHeight, isPrintTitle: true); // left band: a neighbour whose text spills INTO a title column travels with the repeated column if (leftBand) AddIncomingSpill(page, range, page.FromRow, page.ToRow, pdfSheet.PrintTitleColFrom, pdfSheet.PrintTitleColTo, - pageSettings.ContentBounds.Left + page.HeadingWidth, // band origin X (left edge of the title columns) - pageSettings.ContentBounds.Top - page.HeadingHeight - page.PrintTitleHeight, // content-rows origin Y + GetOriginX(pageSettings, page) + page.HeadingWidth, // band origin X (left edge of the title columns) + GetOriginY(pageSettings, page) - page.HeadingHeight - page.PrintTitleHeight, // content-rows origin Y isPrintTitle: true); // corner: same, for the title-rows × title-columns intersection if (topBand && leftBand) AddIncomingSpill(page, range, pdfSheet.PrintTitleRowFrom, pdfSheet.PrintTitleRowTo, pdfSheet.PrintTitleColFrom, pdfSheet.PrintTitleColTo, - pageSettings.ContentBounds.Left + page.HeadingWidth, // band origin X - pageSettings.ContentBounds.Top - page.HeadingHeight, // title-rows origin Y + GetOriginX(pageSettings, page) + page.HeadingWidth, // band origin X + GetOriginY(pageSettings, page) - page.HeadingHeight, // title-rows origin Y isPrintTitle: true); return page; @@ -1570,8 +1573,8 @@ internal static Pages PrecomputeSpillCells(PdfPageSettings pageSettings, PdfRang { var page = pdfPages.Page[i]; page.SpillCells = new List(); - double originX = pageSettings.ContentBounds.Left + page.HeadingWidth + page.PrintTitleWidth; - double originY = pageSettings.ContentBounds.Top - page.HeadingHeight - page.PrintTitleHeight; + double originX = GetOriginX(pageSettings, page) + page.HeadingWidth + page.PrintTitleWidth; + double originY = GetOriginY(pageSettings, page) - page.HeadingHeight - page.PrintTitleHeight; AddIncomingSpill(page, range, page.FromRow, page.ToRow, page.FromColumn, page.ToColumn, originX, originY, isPrintTitle: false); pdfPages.Page[i] = page; } From 7061a74fb54df06d694529463c538f017c343a61 Mon Sep 17 00:00:00 2001 From: KarlKallman Date: Thu, 27 Aug 2026 08:02:21 +0200 Subject: [PATCH 3/4] WIP --- src/EPPlus/Export/PdfExport/Layout/PdfGridlinesLayout.cs | 5 ----- src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/EPPlus/Export/PdfExport/Layout/PdfGridlinesLayout.cs b/src/EPPlus/Export/PdfExport/Layout/PdfGridlinesLayout.cs index 8b432e073..ca4e94313 100644 --- a/src/EPPlus/Export/PdfExport/Layout/PdfGridlinesLayout.cs +++ b/src/EPPlus/Export/PdfExport/Layout/PdfGridlinesLayout.cs @@ -50,7 +50,6 @@ public static void AddGridLines(PdfPageSettings pageSettings, Page page, PdfPage // colX[ci] = X of left edge of column ci (0-based within page). // colX[colCount] = X of right edge of last column. var colX = new double[colCount + 1]; - //colX[0] = pageSettings.ContentBounds.Left + page.HeadingWidth + page.PrintTitleWidth; colX[0] = PdfLayout.GetOriginX(pageSettings, page) + page.HeadingWidth + page.PrintTitleWidth; for (int ci = 0; ci < colCount; ci++) { @@ -74,10 +73,6 @@ public static void AddGridLines(PdfPageSettings pageSettings, Page page, PdfPage // Always computed so BorderLines is available for margin clipping regardless of // whether ShowGridLines is on. When borderOnly is true we stop here. - //double frameLeft = pageSettings.ContentBounds.Left; //colX[0]; - //double frameRight = colX[colCount]; - //double frameTop = pageSettings.ContentBounds.Top; //rowY[0]; - //double frameBottom = rowY[rowCount]; double frameLeft = PdfLayout.GetOriginX(pageSettings, page); double frameRight = colX[colCount]; double frameTop = PdfLayout.GetOriginY(pageSettings, page); diff --git a/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs b/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs index 61048bbac..f97904e83 100644 --- a/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs +++ b/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs @@ -88,7 +88,6 @@ internal static Transform GetCatalog(PdfPageSettings pageSettings, PdfDictionari pageLayout.PrintTitleWidth = page.PrintTitleWidth; pageLayout.PrintTitleHeight = page.PrintTitleHeight; var drawnMergedCells = new HashSet(); - //double contentStartX = pageSettings.ContentBounds.Left + page.HeadingWidth + page.PrintTitleWidth; double contentStartX = GetOriginX(pageSettings, page) + page.HeadingWidth + page.PrintTitleWidth; double contentStartY = GetOriginY(pageSettings, page) - page.HeadingHeight - page.PrintTitleHeight; if (pageSettings.ShowHeadings && !pdfPages[i].IsCommentsPage) @@ -717,7 +716,6 @@ private static Page PrecomputePageMergedCells(PdfPageSettings pageSettings, PdfR } // --- Y --- // Replace the * 15d line with a sum of real row heights - //double drawY = pageSettings.ContentBounds.Top - page.HeadingHeight - page.PrintTitleHeight; double drawY = GetOriginY(pageSettings, page) - page.HeadingHeight - page.PrintTitleHeight; for (int r = page.FromRow; r < row; r++) { @@ -767,7 +765,6 @@ private static double[] BuildColumnXPositions(PdfPageSettings pageSettings, Page { int colCount = page.ToColumn - page.FromColumn + 1; var colX = new double[colCount]; - //double x = pageSettings.ContentBounds.Left + page.HeadingWidth + page.PrintTitleWidth; double x = GetOriginY(pageSettings, page) + page.HeadingWidth + page.PrintTitleWidth; for (int col = page.FromColumn; col <= page.ToColumn; col++) { From 7e9dd1269b440cdc6414c95540c551decea46002 Mon Sep 17 00:00:00 2001 From: KarlKallman Date: Thu, 27 Aug 2026 08:42:37 +0200 Subject: [PATCH 4/4] Added functionality for centered content horiziontally and vertically in PDF --- src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs b/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs index fe20194ed..76287e5a1 100644 --- a/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs +++ b/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs @@ -200,8 +200,8 @@ public PdfScaling Scaling internal string defaultFontName = ""; //DEBUG - internal bool Debug = true; - internal bool PrintAsText = true; + internal bool Debug = false; + internal bool PrintAsText = false; public PdfPageSettings(OpenTypeFontEngine fontEngine) {