From 988066fb5d82b1797f4e6c5071f2ef6ec56392a3 Mon Sep 17 00:00:00 2001 From: KarlKallman Date: Fri, 14 Aug 2026 08:29:32 +0200 Subject: [PATCH 1/6] WIP --- src/EPPlus.Export.Pdf.Tests/PdfTests.cs | 14 +++++++++++++ .../Settings/PdfPageSettings.cs | 14 ++++++++++++- .../PdfExport/Settings/PdfDocumentSettings.cs | 21 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/EPPlus/Export/PdfExport/Settings/PdfDocumentSettings.cs diff --git a/src/EPPlus.Export.Pdf.Tests/PdfTests.cs b/src/EPPlus.Export.Pdf.Tests/PdfTests.cs index cf33d67d3..d38c5e114 100644 --- a/src/EPPlus.Export.Pdf.Tests/PdfTests.cs +++ b/src/EPPlus.Export.Pdf.Tests/PdfTests.cs @@ -638,5 +638,19 @@ public void EPPlusToPdf() p.Workbook.SaveAsPdf(pdfPath + "Snake.Pdf"); p.SaveAs(pdfPath + "Snake.xlsx"); } + + [TestMethod] + public void PrinterSettingsDebug() + { + using (var package = OpenTemplatePackage("PDFTestKarl.xlsx")) + { + var firstWs = package.Workbook.Worksheets[0]; + var secondWs = package.Workbook.Worksheets[1]; + string path = pdfPath + "WorksheetTest1.pdf"; + + package.Workbook.SaveAsPdf(path); + AssertLooksLikePdf(File.ReadAllBytes(path)); + } + } } } diff --git a/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs b/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs index 5416f1887..76287e5a1 100644 --- a/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs +++ b/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs @@ -147,7 +147,7 @@ public PdfPageSize PageSize private Orientations _orientation = Orientations.Portrait; /// /// Set the orientation of the pages. - /// + /// public Orientations Orientation { get @@ -216,6 +216,18 @@ private static PdfPageSize ApplyOrientation(PdfPageSize size, Orientations orien ? size : new PdfPageSize(size.Height, size.Width); // swap (ctor is width, height) } + + internal PdfPageSettings CloneForSheet() + { + var c = new PdfPageSettings(_fontEngine); + c.FontDirectories = FontDirectories; + c.SearchSystemDirectories = SearchSystemDirectories; + c.EmbeddFonts = EmbeddFonts; + c.defaultFontName = defaultFontName; + c.Debug = Debug; + c.PrintAsText = PrintAsText; + return c; + } } /// diff --git a/src/EPPlus/Export/PdfExport/Settings/PdfDocumentSettings.cs b/src/EPPlus/Export/PdfExport/Settings/PdfDocumentSettings.cs new file mode 100644 index 000000000..fd7940aee --- /dev/null +++ b/src/EPPlus/Export/PdfExport/Settings/PdfDocumentSettings.cs @@ -0,0 +1,21 @@ +using EPPlus.Fonts.OpenType; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EPPlus.Export.Pdf.Settings +{ + internal class PdfDocumentSettings + { + internal OpenTypeFontEngine FontEngine; + internal List FontDirectories; + internal bool SearchSystemDirectories; + internal bool EmbeddFonts; + internal string defaultFontName; + internal int FirstPageNumber; + internal bool Debug; + internal bool PrintAsText; + } +} From f8cdae4fc43a2287583c2991dcbb7d9a843ab893 Mon Sep 17 00:00:00 2001 From: KarlKallman Date: Tue, 18 Aug 2026 16:28:04 +0200 Subject: [PATCH 2/6] WIP --- src/EPPlus.Export.Pdf.Tests/PdfTests.cs | 93 +++++++++++++++++-- src/EPPlus.Export.Pdf/ExcelPdf.cs | 22 +++-- src/EPPlus.Export.Pdf/Layout/PdfPageLayout.cs | 7 +- .../Settings/PdfPageSettings.cs | 4 +- src/EPPlus/Export/PdfExport/Data/PageData.cs | 10 +- .../Export/PdfExport/Layout/PdfLayout.cs | 31 +++++-- src/EPPlus/Export/PdfExport/PdfCatalog.cs | 88 ++++++++++++++---- .../PdfExport/Settings/GetPdfSettings.cs | 17 +++- 8 files changed, 224 insertions(+), 48 deletions(-) diff --git a/src/EPPlus.Export.Pdf.Tests/PdfTests.cs b/src/EPPlus.Export.Pdf.Tests/PdfTests.cs index d38c5e114..52ce61958 100644 --- a/src/EPPlus.Export.Pdf.Tests/PdfTests.cs +++ b/src/EPPlus.Export.Pdf.Tests/PdfTests.cs @@ -13,8 +13,12 @@ Date Author Change using EPPlus.Export.Pdf.Settings; using OfficeOpenXml; using OfficeOpenXml.Export.PdfExport; -using System.Text; +using OfficeOpenXml.Export.PdfExport.Settings; using OfficeOpenXml.Style; +using System.Diagnostics; +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; namespace EPPlusTest.PDF { @@ -640,16 +644,91 @@ public void EPPlusToPdf() } [TestMethod] - public void PrinterSettingsDebug() + public void Testing() + { + using var p = OpenTemplatePackage("PDFTestKarl.xlsx"); + var wb = p.Workbook; + string path = pdfPath + "WorksheetTest1.pdf"; + wb.SaveAsPdf(path); + AssertLooksLikePdf(File.ReadAllBytes(path)); + } + + [TestMethod] + public void EachWorksheetUsesItsOwnOrientation() + { + using (var package = OpenTemplatePackage("PDFTestKarl.xlsx")) + { + package.Workbook.Worksheets[0].PrinterSettings.Orientation = eOrientation.Portrait; + package.Workbook.Worksheets[1].PrinterSettings.Orientation = eOrientation.Landscape; + + var settings = GetPdfSettings.GetPdfSettingsFromPrinterSettings( + package.Workbook, + package.Workbook.Worksheets[0].PrinterSettings); + + byte[] pdf; + using (var ms = new MemoryStream()) + { + new PdfCatalog(ms, settings, package.Workbook); + pdf = ms.ToArray(); + } + + var matches = Regex.Matches( + Encoding.ASCII.GetString(pdf), + @"/MediaBox\s*\[\s*0\s+0\s+(?[\d.]+)\s+(?[\d.]+)\s*\]"); + + Assert.AreEqual(2, matches.Count, "Expected one page per worksheet."); + + var ci = CultureInfo.InvariantCulture; + double w1 = double.Parse(matches[0].Groups["w"].Value, ci); + double h1 = double.Parse(matches[0].Groups["h"].Value, ci); + double w2 = double.Parse(matches[1].Groups["w"].Value, ci); + double h2 = double.Parse(matches[1].Groups["h"].Value, ci); + + Assert.IsTrue(h1 > w1, "Page 1 should be portrait."); + Assert.IsTrue(w2 > h2, "Page 2 should be landscape."); + // Landscape is the same paper transposed, not a different paper size. + Assert.AreEqual(w1, h2, 0.01d); + Assert.AreEqual(h1, w2, 0.01d); + } + } + + [TestMethod] + public void EachWorksheetUsesItsOwnShowGridLines() { using (var package = OpenTemplatePackage("PDFTestKarl.xlsx")) { - var firstWs = package.Workbook.Worksheets[0]; - var secondWs = package.Workbook.Worksheets[1]; - string path = pdfPath + "WorksheetTest1.pdf"; + package.Workbook.Worksheets[0].PrinterSettings.ShowGridLines = false; + package.Workbook.Worksheets[1].PrinterSettings.ShowGridLines = true; + + var settings = GetPdfSettings.GetPdfSettingsFromPrinterSettings( + package.Workbook, + package.Workbook.Worksheets[0].PrinterSettings); + + byte[] pdf; + using (var ms = new MemoryStream()) + { + new PdfCatalog(ms, settings, package.Workbook); + pdf = ms.ToArray(); + } + + var text = Encoding.ASCII.GetString(pdf); + + // One page per worksheet - guards against the count assertion below + // being thrown off by pagination or a comments page. + Assert.AreEqual(2, Regex.Matches(text, @"/MediaBox\s*\[").Count, + "Expected one page per worksheet."); + + // PdfContentStream.AddInnerGridLines writes this marker whenever the flag + // is set, so the number of occurrences equals the number of pages that + // asked for gridlines. Exactly one means the flag was read per sheet: + // reading sheet 1's flag globally would give 0, applying it to every page + // would give 2. + Assert.AreEqual(1, Regex.Matches(text, @"% Gridlines Start").Count, + "Only sheet 2 asked for gridlines."); - package.Workbook.SaveAsPdf(path); - AssertLooksLikePdf(File.ReadAllBytes(path)); + //var text = Encoding.ASCII.GetString(pdf); + //Debug.WriteLine($"pages={Regex.Matches(text, @"/MediaBox\s*\[").Count} " + + // $"gridlines={Regex.Matches(text, @"% Gridlines Start").Count}"); } } } diff --git a/src/EPPlus.Export.Pdf/ExcelPdf.cs b/src/EPPlus.Export.Pdf/ExcelPdf.cs index 2c03a03de..eaa716cd6 100644 --- a/src/EPPlus.Export.Pdf/ExcelPdf.cs +++ b/src/EPPlus.Export.Pdf/ExcelPdf.cs @@ -134,8 +134,10 @@ private PdfCatalog AddCatalog(int pagesObjectNumber) } //Create Content - private void AddContent(Transform pageLayout, PdfPage page) + private void AddContent(PdfPageLayout pageLayout, PdfPage page) { + var pageSettings = pageLayout.Settings; + var cells = pageLayout.ChildObjects.Where(t => (t is PdfCellLayout || t is PdfCellContentLayout || t is PdfCellBorderLayout) && !(t is PdfCellLayout cc && (cc.IsHeading || cc.IsPrintTitle)) && @@ -151,7 +153,7 @@ private void AddContent(Transform pageLayout, PdfPage page) //Add clipping rectangle around page content. contentStream.AddCommand("q"); contentStream.AddMarginClipping((PdfPageLayout)pageLayout); - if (_pageSettings.ShowGridLines) + if (pageSettings.ShowGridLines) { contentStream.AddInnerGridLines(pageLayout); } @@ -166,7 +168,7 @@ private void AddContent(Transform pageLayout, PdfPage page) contentStream.AddCellLayout(layout, GetPatternLabel(layout)); break; case PdfCellContentLayout contentLayout: - contentStream.AddCellContentLayout(contentLayout, _dictionaries, _pageSettings); + contentStream.AddCellContentLayout(contentLayout, _dictionaries, pageSettings); break; case PdfCellBorderLayout borderLayout: contentStream.AddBorderLayout(borderLayout); @@ -186,12 +188,12 @@ private void AddContent(Transform pageLayout, PdfPage page) case PdfCellLayout layout: contentStream.AddCellLayout(layout, GetPatternLabel(layout)); break; case PdfCellContentLayout contentLayout: - contentStream.AddCellContentLayout(contentLayout, _dictionaries, _pageSettings); break; + contentStream.AddCellContentLayout(contentLayout, _dictionaries, pageSettings); break; case PdfCellBorderLayout borderLayout: contentStream.AddBorderLayout(borderLayout); break; } } - if (_pageSettings.ShowGridLines || _pageSettings.ShowHeadings) + if (pageSettings.ShowGridLines || pageSettings.ShowHeadings) { contentStream.AddOuterGridBorder(pageLayout); contentStream.AddPrintTitleGridLines(pageLayout); @@ -199,7 +201,7 @@ private void AddContent(Transform pageLayout, PdfPage page) //Add header and footer. foreach (var hf in headerFooterLayouts) { - contentStream.AddCellContentLayout(hf, _dictionaries, _pageSettings); + contentStream.AddCellContentLayout(hf, _dictionaries, pageSettings); } foreach (var titleCell in printTitleLayouts) { @@ -209,7 +211,7 @@ private void AddContent(Transform pageLayout, PdfPage page) case PdfCellLayout layout: contentStream.AddCellLayout(layout, GetPatternLabel(layout)); break; case PdfCellContentLayout contentLayout: - contentStream.AddCellContentLayout(contentLayout, _dictionaries, _pageSettings); break; + contentStream.AddCellContentLayout(contentLayout, _dictionaries, pageSettings); break; case PdfCellBorderLayout borderLayout: contentStream.AddBorderLayout(borderLayout); break; } @@ -271,8 +273,10 @@ internal void CreatePdf(PdfPageSettings pageSettings, PdfDictionaries dictionari //Create Page and Content for (int i = 0; i < layout.ChildObjects.Count; i++) { - var pageLayout = layout.ChildObjects[i]; - var page = AddPage(2, new List(), _pageSettings); + //var pageLayout = layout.ChildObjects[i]; + var pageLayout = (PdfPageLayout)layout.ChildObjects[i]; // ← ny rad + //var page = AddPage(2, new List(), _pageSettings); + var page = AddPage(2, new List(), pageLayout.Settings); AddContent(pageLayout, page); pages.pageObjectNumbers.Add(page.objectNumber); } diff --git a/src/EPPlus.Export.Pdf/Layout/PdfPageLayout.cs b/src/EPPlus.Export.Pdf/Layout/PdfPageLayout.cs index 2a1d0d9a8..b30789030 100644 --- a/src/EPPlus.Export.Pdf/Layout/PdfPageLayout.cs +++ b/src/EPPlus.Export.Pdf/Layout/PdfPageLayout.cs @@ -10,6 +10,7 @@ Date Author Change ************************************************************************************************* 27/11/2025 EPPlus Software AB EPPlus 9 *************************************************************************************************/ +using EPPlus.Export.Pdf.Settings; using EPPlus.Graphics; using System.Collections.Generic; using System.Diagnostics; @@ -27,7 +28,11 @@ internal class PdfPageLayout : Transform public double PrintTitleWidth; public double PrintTitleHeight; public bool isCommentsPage = false; - + /// + /// The settings of the worksheet this page belongs to. + /// Set in PdfLayout.GetCatalog, read in ExcelPdf when writing the page. + /// + internal PdfPageSettings Settings; public PdfPageLayout(double x, double y, double width, double height) : base(x, y, width, height) { } diff --git a/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs b/src/EPPlus.Export.Pdf/Settings/PdfPageSettings.cs index 76287e5a1..fe20194ed 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..458d1bb62 100644 --- a/src/EPPlus/Export/PdfExport/Data/PageData.cs +++ b/src/EPPlus/Export/PdfExport/Data/PageData.cs @@ -10,11 +10,12 @@ Date Author Change ************************************************************************************************* 27/11/2025 EPPlus Software AB EPPlus 9 *************************************************************************************************/ +using EPPlus.Export.Pdf.Layout; +using EPPlus.Export.Pdf.Settings; +using OfficeOpenXml.Export.PdfExport.Layout; using OfficeOpenXml.Export.PdfExport.TextMapping; using OfficeOpenXml.Style; using System.Collections.Generic; -using EPPlus.Export.Pdf.Layout; -using OfficeOpenXml.Export.PdfExport.Layout; namespace OfficeOpenXml.Export.PdfExport.Data @@ -50,6 +51,11 @@ internal struct Pages public string HeadingFontName; public float HeadingFontSize; public ExcelFill HeadingFill; + /// + /// The settings of the worksheet these pages belong to. + /// Set in PdfLayout.GetPages, read in PdfLayout.GetCatalog. + /// + public PdfPageSettings Settings; public int Count { get { return Width * Height; } diff --git a/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs b/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs index d28ab76c4..bc8c1720a 100644 --- a/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs +++ b/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs @@ -63,25 +63,38 @@ internal class PdfLayout { private const double rowHeadingWith1CharWidth = 18d; - public static Transform GetLayout(PdfPageSettings pageSettings, PdfDictionaries dictionaries, PdfWorksheet[] pdfSheets) + //public static Transform GetLayout(PdfPageSettings pageSettings, PdfDictionaries dictionaries, PdfWorksheet[] pdfSheets) + //{ + // var PagesCollection = GetPages(pageSettings, pdfSheets); + // var Catalog = GetCatalog(pageSettings, dictionaries, PagesCollection); + // return Catalog; + //} + + public static Transform GetLayout(PdfPageSettings[] sheetSettings, PdfDictionaries dictionaries, PdfWorksheet[] pdfSheets) { - var PagesCollection = GetPages(pageSettings, pdfSheets); - var Catalog = GetCatalog(pageSettings, dictionaries, PagesCollection); + var PagesCollection = GetPages(sheetSettings, pdfSheets); + // Page numbering is document-global; sheet 1 supplies it, as before. + var Catalog = GetCatalog(sheetSettings[0].FirstPageNumber, dictionaries, PagesCollection); return Catalog; } - internal static Transform GetCatalog(PdfPageSettings pageSettings, PdfDictionaries dictionaries, List pdfPages) + //internal static Transform GetCatalog(PdfPageSettings pageSettings, PdfDictionaries dictionaries, List pdfPages) + internal static Transform GetCatalog(int firstPageNumber, PdfDictionaries dictionaries, List pdfPages) { Transform Catalog = new Transform(0d, 0d, 0d, 0d); int totalPages = GetTotalPages(pdfPages); for (int i = 0; i < pdfPages.Count; i++) { + var pageSettings = pdfPages[i].Settings; + + var pages = pdfPages[i].Page; int pageNumber = pageSettings.FirstPageNumber; for (int j = 0; j < pages.Length; j++) { var page = pages[j]; PdfPageLayout pageLayout = new PdfPageLayout(0d, 0d, 0d, 0d); + pageLayout.Settings = pageSettings; // ← saknas pageLayout.isCommentsPage = pdfPages[i].IsCommentsPage; pageLayout.HeadingWidth = page.HeadingWidth; pageLayout.HeadingHeight = page.HeadingHeight; @@ -645,11 +658,15 @@ private static int GetTotalPages(List pdfPages) return totalPages; } - internal static List GetPages(PdfPageSettings pageSettings, PdfWorksheet[] pdfSheets) + internal static List GetPages(PdfPageSettings[] sheetSettings, PdfWorksheet[] pdfSheets) { List PagesCollection = new List(); - foreach (var pdfSheet in pdfSheets) + for (int si = 0; si < pdfSheets.Length; si++) { + var pdfSheet= pdfSheets[si]; + var pageSettings = sheetSettings[si]; + //foreach (var pdfSheet in pdfSheets) + //{ for (int ri = 0; ri < pdfSheet.Ranges.Count; ri++) { var range = pdfSheet.Ranges[ri]; @@ -663,6 +680,7 @@ internal static List GetPages(PdfPageSettings pageSettings, PdfWorksheet[ pages.HeadingFontName = pdfSheet.NormalStyle.Style.Font.Name; pages.HeadingFontSize = pdfSheet.NormalStyle.Style.Font.Size; pages.HeadingFill = pdfSheet.NormalStyle.Style.Fill; + pages.Settings = pageSettings; // new PagesCollection.Add(pages); } if (pdfSheet.CommentsAndNotes.Range != null) @@ -674,6 +692,7 @@ internal static List GetPages(PdfPageSettings pageSettings, PdfWorksheet[ pages = MapPage(pdfSheet.CommentsAndNotes, pages); pageSettings.ShowHeadings = savedShowHeadings; pages.IsCommentsPage = true; + pages.Settings = pageSettings; // NY PagesCollection.Add(pages); } } diff --git a/src/EPPlus/Export/PdfExport/PdfCatalog.cs b/src/EPPlus/Export/PdfExport/PdfCatalog.cs index 2bfb60d0a..9cc0cfa06 100644 --- a/src/EPPlus/Export/PdfExport/PdfCatalog.cs +++ b/src/EPPlus/Export/PdfExport/PdfCatalog.cs @@ -11,24 +11,25 @@ Date Author Change 27/11/2025 EPPlus Software AB EPPlus 9 *************************************************************************************************/ using EPPlus.Export.Pdf; +using EPPlus.Export.Pdf; +using EPPlus.Export.Pdf.Resources; using EPPlus.Export.Pdf.Resources; using EPPlus.Export.Pdf.Settings; +using EPPlus.Export.Pdf.Settings; using EPPlus.Graphics; using EPPlus.Graphics; -using EPPlus.Export.Pdf; -using EPPlus.Export.Pdf.Settings; -using EPPlus.Export.Pdf.Resources; using OfficeOpenXml.Export.PdfExport.Data; using OfficeOpenXml.Export.PdfExport.Layout; using OfficeOpenXml.Export.PdfExport.RowResize; +using OfficeOpenXml.Export.PdfExport.Settings; using OfficeOpenXml.Export.PdfExport.TextMapping; using OfficeOpenXml.Export.PdfExport.TextShaping; using System; using System.Collections.Generic; -using System.Diagnostics; -using System.IO; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics; +using System.IO; using System.Linq; namespace OfficeOpenXml.Export.PdfExport @@ -80,21 +81,35 @@ private void HandleWorksheetCollection(PdfPageSettings pageSettings, ExcelWorksh // Match the single-worksheet path: resolve the default font before building. pageSettings.defaultFontName = worksheets[0].Workbook.ThemeManager.GetOrCreateTheme().FontScheme.MinorFont[0].Typeface; + // NEW: one settings object per worksheet, each from its own printer settings. + var sheetSettings = new PdfPageSettings[worksheets.Length]; + for (int i = 0; i < worksheets.Length; i++) + { + sheetSettings[i] = GetPdfSettings.GetPdfSettingsForSheet(pageSettings, worksheets[i].PrinterSettings); + } + PdfWorksheet[] pdfSheets = null; try { - // Collect text for every worksheet. - pdfSheets = GetPdfWorksheets(pageSettings, worksheets); - - // Shape text and auto-fit rows per sheet. - foreach (var pdfSheet in pdfSheets) + //// Collect text for every worksheet. + //pdfSheets = GetPdfWorksheets(pageSettings, worksheets); + + //// Shape text and auto-fit rows per sheet. + //foreach (var pdfSheet in pdfSheets) + //{ + // ShapeTextInPdfWorksheet(pageSettings, pdfSheet); + // PdfCalculateRowHeight.ResizeRowHeights(pdfSheet); + //} + pdfSheets = GetPdfWorksheets(sheetSettings, worksheets); + + for (int i = 0; i < pdfSheets.Length; i++) { - ShapeTextInPdfWorksheet(pageSettings, pdfSheet); - PdfCalculateRowHeight.ResizeRowHeights(pdfSheet); + ShapeTextInPdfWorksheet(sheetSettings[i], pdfSheets[i]); + PdfCalculateRowHeight.ResizeRowHeights(pdfSheets[i]); } // One layout spanning all sheets and their ranges. - var layout = GetLayout(pageSettings, pdfSheets); + var layout = GetLayout(sheetSettings, pdfSheets); // Write the PDF document. writePdf(layout); @@ -259,8 +274,13 @@ private void HandleRangeCollection(PdfPageSettings pageSettings, ExcelRangeBase[ ShapeTextInPdfWorksheet(pageSettings, pdfSheet); PdfCalculateRowHeight.ResizeRowHeights(pdfSheet); } - - var layout = GetLayout(pageSettings, pdfSheets); + var sheetSettings = new PdfPageSettings[pdfSheets.Length]; + for (int i = 0; i < sheetSettings.Length; i++) + { + // Ranges within one export share the same printer settings today. + sheetSettings[i] = pageSettings; + } + var layout = GetLayout(sheetSettings, pdfSheets); writePdf(layout); } @@ -302,16 +322,29 @@ private Action WriteToStream(PdfPageSettings pageSettings, Stream str //Create Layout Methods - private Transform GetLayout(PdfPageSettings pageSettings, PdfWorksheet[] pdfSheets) + //private Transform GetLayout(PdfPageSettings pageSettings, PdfWorksheet[] pdfSheets) + //{ + // var Layout = PdfLayout.GetLayout(pageSettings, _dictionaries, pdfSheets); + // return Layout; + //} + + //private Transform GetLayout(PdfPageSettings pageSettings, PdfWorksheet pdfSheet) + //{ + // PdfWorksheet[] pdfSheets = new PdfWorksheet[1] { pdfSheet }; + // var Layout = PdfLayout.GetLayout(pageSettings, _dictionaries, pdfSheets); + // return Layout; + //} + + private Transform GetLayout(PdfPageSettings[] sheetSettings, PdfWorksheet[] pdfSheets) { - var Layout = PdfLayout.GetLayout(pageSettings, _dictionaries, pdfSheets); + var Layout = PdfLayout.GetLayout(sheetSettings, _dictionaries, pdfSheets); return Layout; } private Transform GetLayout(PdfPageSettings pageSettings, PdfWorksheet pdfSheet) { - PdfWorksheet[] pdfSheets = new PdfWorksheet[1] { pdfSheet }; - var Layout = PdfLayout.GetLayout(pageSettings, _dictionaries, pdfSheets); + // Single sheet: one settings object, one sheet. + var Layout = PdfLayout.GetLayout(new[] { pageSettings }, _dictionaries, new[] { pdfSheet }); return Layout; } @@ -434,9 +467,14 @@ private PdfWorksheet GetPdfWorksheet(PdfPageSettings pageSettings, ExcelWorkshee pdfSheet.Ranges.Add(new PdfRange(range, false)); } + //if (pageSettings.ShowHeadings && _addTextForHeadings) + // _dictionaries.AddFont(pageSettings, pdfSheet.NormalStyle.Style.Font.Name, pdfSheet.GetSubFamilyFromNormalStyle, "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"); + //_addTextForHeadings = false; if (pageSettings.ShowHeadings && _addTextForHeadings) + { _dictionaries.AddFont(pageSettings, pdfSheet.NormalStyle.Style.Font.Name, pdfSheet.GetSubFamilyFromNormalStyle, "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"); - _addTextForHeadings = false; + _addTextForHeadings = false; + } GetMaps(pageSettings, pdfSheet, pdfSheet.Ranges); GetPrintTitles(pageSettings, pdfSheet); @@ -445,6 +483,16 @@ private PdfWorksheet GetPdfWorksheet(PdfPageSettings pageSettings, ExcelWorkshee return pdfSheet; } + private PdfWorksheet[] GetPdfWorksheets(PdfPageSettings[] sheetSettings, ExcelWorksheet[] worksheets) + { + PdfWorksheet[] pdfSheets = new PdfWorksheet[worksheets.Length]; + for (int i = 0; i < pdfSheets.Length; i++) + { + pdfSheets[i] = GetPdfWorksheet(sheetSettings[i], worksheets[i]); + } + return pdfSheets; + } + private List GetRanges(ExcelWorksheet worksheet) { List ranges = new List(); diff --git a/src/EPPlus/Export/PdfExport/Settings/GetPdfSettings.cs b/src/EPPlus/Export/PdfExport/Settings/GetPdfSettings.cs index 571ee41e0..7eb51052b 100644 --- a/src/EPPlus/Export/PdfExport/Settings/GetPdfSettings.cs +++ b/src/EPPlus/Export/PdfExport/Settings/GetPdfSettings.cs @@ -22,6 +22,22 @@ internal static class GetPdfSettings internal static PdfPageSettings GetPdfSettingsFromPrinterSettings(ExcelWorkbook workbook, ExcelPrinterSettings eps) { var settings = new PdfPageSettings(workbook.RenderContext.FontEngine); + ApplyPrinterSettings(settings, eps); + return settings; + } + + internal static PdfPageSettings GetPdfSettingsForSheet( + PdfPageSettings baseSettings, ExcelPrinterSettings eps) + { + var s = baseSettings.CloneForSheet(); + ApplyPrinterSettings(s, eps); + return s; + } + + private static void ApplyPrinterSettings(PdfPageSettings settings, ExcelPrinterSettings eps) + { + // ← hela den befintliga kroppen flyttas hit, oförändrad + var leftMargin = UnitConversion.ToMillimeters(eps.LeftMargin); var rightMargin = UnitConversion.ToMillimeters(eps.RightMargin); var topMargin = UnitConversion.ToMillimeters(eps.TopMargin); @@ -50,7 +66,6 @@ internal static PdfPageSettings GetPdfSettingsFromPrinterSettings(ExcelWorkbook settings.CommentsAndNotes = (CommentsAndNotes)eps.CellComments; settings.CellErrors = (CellErrors)eps.Errors; settings.FirstPageNumber = eps.FirstPageNumber; - return settings; } private static PdfPageSize GetPageSize(ePaperSize PaperSize) From 353c11aa4d4967967ed37580909ba13bcbd76116 Mon Sep 17 00:00:00 2001 From: KarlKallman Date: Wed, 19 Aug 2026 14:21:08 +0200 Subject: [PATCH 3/6] Implemented support for setting diffrent printer settings per worksheet when exporting a workbook to PDF --- src/EPPlus.Export.Pdf.Tests/PdfTests.cs | 46 +++++++++++++++++++ src/EPPlus.Export.Pdf/ExcelPdf.cs | 20 ++++---- .../Settings/PdfDocumentSettings.cs | 37 +++++++++++++++ src/EPPlus/Export/PdfExport/PdfCatalog.cs | 32 ++++--------- .../PdfExport/Settings/PdfDocumentSettings.cs | 21 --------- 5 files changed, 101 insertions(+), 55 deletions(-) create mode 100644 src/EPPlus.Export.Pdf/Settings/PdfDocumentSettings.cs delete mode 100644 src/EPPlus/Export/PdfExport/Settings/PdfDocumentSettings.cs diff --git a/src/EPPlus.Export.Pdf.Tests/PdfTests.cs b/src/EPPlus.Export.Pdf.Tests/PdfTests.cs index 52ce61958..905d9920c 100644 --- a/src/EPPlus.Export.Pdf.Tests/PdfTests.cs +++ b/src/EPPlus.Export.Pdf.Tests/PdfTests.cs @@ -11,6 +11,7 @@ Date Author Change 10/07/2025 EPPlus Software AB EPPlus.Fonts.OpenType 1.0 *************************************************************************************************/ using EPPlus.Export.Pdf.Settings; +using EPPlus.Export.Pdf.Settings.PdfPageSizes; using OfficeOpenXml; using OfficeOpenXml.Export.PdfExport; using OfficeOpenXml.Export.PdfExport.Settings; @@ -731,5 +732,50 @@ public void EachWorksheetUsesItsOwnShowGridLines() // $"gridlines={Regex.Matches(text, @"% Gridlines Start").Count}"); } } + + [TestMethod] + public void EachWorksheetUsesItsOwnPaperSize() + { + using (var package = OpenTemplatePackage("PDFTestKarl.xlsx")) + { + // Orientation is set explicitly so a transposed page size cannot be + // mistaken for a different paper size. + package.Workbook.Worksheets[0].PrinterSettings.Orientation = eOrientation.Portrait; + package.Workbook.Worksheets[1].PrinterSettings.Orientation = eOrientation.Portrait; + package.Workbook.Worksheets[0].PrinterSettings.PaperSize = ePaperSize.A4; + package.Workbook.Worksheets[1].PrinterSettings.PaperSize = ePaperSize.A3; + + var settings = GetPdfSettings.GetPdfSettingsFromPrinterSettings( + package.Workbook, + package.Workbook.Worksheets[0].PrinterSettings); + + byte[] pdf; + using (var ms = new MemoryStream()) + { + new PdfCatalog(ms, settings, package.Workbook); + pdf = ms.ToArray(); + } + + var matches = Regex.Matches( + Encoding.ASCII.GetString(pdf), + @"/MediaBox\s*\[\s*0\s+0\s+(?[\d.]+)\s+(?[\d.]+)\s*\]"); + + Assert.AreEqual(2, matches.Count, "Expected one page per worksheet."); + + var ci = CultureInfo.InvariantCulture; + double w1 = double.Parse(matches[0].Groups["w"].Value, ci); + double h1 = double.Parse(matches[0].Groups["h"].Value, ci); + double w2 = double.Parse(matches[1].Groups["w"].Value, ci); + double h2 = double.Parse(matches[1].Groups["h"].Value, ci); + + // Compare against the source of truth rather than literal point values. + // PdfPageSize rounds mm to whole points, so 210x297 mm becomes 595x842. + Assert.AreEqual(PdfPageSize.A4.WidthPu, w1, "Page 1 should be A4."); + Assert.AreEqual(PdfPageSize.A4.HeightPu, h1, "Page 1 should be A4."); + Assert.AreEqual(PdfPageSize.A3.WidthPu, w2, "Page 2 should be A3, not sheet 1's A4."); + Assert.AreEqual(PdfPageSize.A3.HeightPu, h2, "Page 2 should be A3, not sheet 1's A4."); + } + } + } } diff --git a/src/EPPlus.Export.Pdf/ExcelPdf.cs b/src/EPPlus.Export.Pdf/ExcelPdf.cs index eaa716cd6..6f8a06525 100644 --- a/src/EPPlus.Export.Pdf/ExcelPdf.cs +++ b/src/EPPlus.Export.Pdf/ExcelPdf.cs @@ -30,6 +30,7 @@ namespace EPPlus.Export.Pdf internal class ExcelPdf { private PdfPageSettings _pageSettings; + private PdfDocumentSettings _documentSettings; private PdfDictionaries _dictionaries; private List _document = new List(); private string _debugString; @@ -59,8 +60,8 @@ private string GetPatternLabel(PdfCellLayout layout) //Add Fonts //Need to update this method a bit. We should check for all default fonts and not only courier new? Also need to check if we are allowed to embedd the font. private void AddFontData() - { - if (_pageSettings.EmbeddFonts) + { + if (_documentSettings.EmbeddFonts) { foreach (var font in _dictionaries.Fonts) { @@ -229,16 +230,16 @@ private PdfInfoObject AddInfoObject(string workBookName = "") return info; } - internal void CreatePdf(PdfPageSettings pageSettings, PdfDictionaries dictionaries, Transform layout, string fileName) + internal void CreatePdf(PdfDocumentSettings documentSettings, PdfDictionaries dictionaries, Transform layout, string fileName) { //Write the PDF to the file. The Stream overload does the actual work and //populates _debugString. using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) { - CreatePdf(pageSettings, dictionaries, layout, fs); + CreatePdf(documentSettings, dictionaries, layout, fs); } //Write pdf as txt for debug. - if (_pageSettings.Debug && _pageSettings.PrintAsText) + if (_documentSettings.Debug && _documentSettings.PrintAsText) { using (var fs = new FileStream(fileName + ".txt", FileMode.Create, FileAccess.Write)) { @@ -250,7 +251,7 @@ internal void CreatePdf(PdfPageSettings pageSettings, PdfDictionaries dictionari } } - internal void CreatePdf(PdfPageSettings pageSettings, PdfDictionaries dictionaries, Transform layout, Stream stream) + internal void CreatePdf(PdfDocumentSettings documentSettings, PdfDictionaries dictionaries, Transform layout, Stream stream) { if (stream == null) throw new ArgumentNullException(nameof(stream)); if (!stream.CanWrite) throw new ArgumentException("The stream must be writable.", nameof(stream)); @@ -258,7 +259,8 @@ internal void CreatePdf(PdfPageSettings pageSettings, PdfDictionaries dictionari //seek to each object, so the target stream has to support querying its position. if (!stream.CanSeek) throw new ArgumentException("The stream must be seekable, because the PDF cross-reference table requires byte offsets.", nameof(stream)); - _pageSettings = pageSettings; + //_pageSettings = pageSettings; + _documentSettings = documentSettings; _dictionaries = dictionaries; var catalog = AddCatalog(2); //Create Pages @@ -273,9 +275,7 @@ internal void CreatePdf(PdfPageSettings pageSettings, PdfDictionaries dictionari //Create Page and Content for (int i = 0; i < layout.ChildObjects.Count; i++) { - //var pageLayout = layout.ChildObjects[i]; - var pageLayout = (PdfPageLayout)layout.ChildObjects[i]; // ← ny rad - //var page = AddPage(2, new List(), _pageSettings); + var pageLayout = (PdfPageLayout)layout.ChildObjects[i]; var page = AddPage(2, new List(), pageLayout.Settings); AddContent(pageLayout, page); pages.pageObjectNumbers.Add(page.objectNumber); diff --git a/src/EPPlus.Export.Pdf/Settings/PdfDocumentSettings.cs b/src/EPPlus.Export.Pdf/Settings/PdfDocumentSettings.cs new file mode 100644 index 000000000..5744156ba --- /dev/null +++ b/src/EPPlus.Export.Pdf/Settings/PdfDocumentSettings.cs @@ -0,0 +1,37 @@ +using EPPlus.Fonts.OpenType; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EPPlus.Export.Pdf.Settings +{ + internal class PdfDocumentSettings + { + internal OpenTypeFontEngine FontEngine; + internal List FontDirectories; + internal bool SearchSystemDirectories; + internal bool EmbeddFonts; + internal string defaultFontName; + internal int FirstPageNumber; + internal bool Debug; + internal bool PrintAsText; + + internal static PdfDocumentSettings From(PdfPageSettings s) + { + return new PdfDocumentSettings + { + FontEngine = s.FontEngine, + FontDirectories = s.FontDirectories, // shared by reference + SearchSystemDirectories = s.SearchSystemDirectories, + EmbeddFonts = s.EmbeddFonts, + defaultFontName = s.defaultFontName, + FirstPageNumber = s.FirstPageNumber, + Debug = s.Debug, + PrintAsText = s.PrintAsText, + }; + } + + } +} diff --git a/src/EPPlus/Export/PdfExport/PdfCatalog.cs b/src/EPPlus/Export/PdfExport/PdfCatalog.cs index 9cc0cfa06..e1e66cd16 100644 --- a/src/EPPlus/Export/PdfExport/PdfCatalog.cs +++ b/src/EPPlus/Export/PdfExport/PdfCatalog.cs @@ -81,7 +81,7 @@ private void HandleWorksheetCollection(PdfPageSettings pageSettings, ExcelWorksh // Match the single-worksheet path: resolve the default font before building. pageSettings.defaultFontName = worksheets[0].Workbook.ThemeManager.GetOrCreateTheme().FontScheme.MinorFont[0].Typeface; - // NEW: one settings object per worksheet, each from its own printer settings. + // One settings object per worksheet, each from its own printer settings. var sheetSettings = new PdfPageSettings[worksheets.Length]; for (int i = 0; i < worksheets.Length; i++) { @@ -92,16 +92,9 @@ private void HandleWorksheetCollection(PdfPageSettings pageSettings, ExcelWorksh try { //// Collect text for every worksheet. - //pdfSheets = GetPdfWorksheets(pageSettings, worksheets); - - //// Shape text and auto-fit rows per sheet. - //foreach (var pdfSheet in pdfSheets) - //{ - // ShapeTextInPdfWorksheet(pageSettings, pdfSheet); - // PdfCalculateRowHeight.ResizeRowHeights(pdfSheet); - //} pdfSheets = GetPdfWorksheets(sheetSettings, worksheets); + //// Shape text and auto-fit rows per sheet. for (int i = 0; i < pdfSheets.Length; i++) { ShapeTextInPdfWorksheet(sheetSettings[i], pdfSheets[i]); @@ -312,29 +305,20 @@ internal PdfCellCollection GetCellCollectionFromRange(PdfPageSettings pageSettin private Action WriteToFile(PdfPageSettings pageSettings, string fileName) { - return layout => new ExcelPdf().CreatePdf(pageSettings, _dictionaries, layout, fileName); + //return layout => new ExcelPdf().CreatePdf(pageSettings, _dictionaries, layout, fileName); + return layout => new ExcelPdf().CreatePdf( + PdfDocumentSettings.From(pageSettings), _dictionaries, layout, fileName); } private Action WriteToStream(PdfPageSettings pageSettings, Stream stream) { - return layout => new ExcelPdf().CreatePdf(pageSettings, _dictionaries, layout, stream); + //return layout => new ExcelPdf().CreatePdf(pageSettings, _dictionaries, layout, stream); + return layout => new ExcelPdf().CreatePdf( + PdfDocumentSettings.From(pageSettings), _dictionaries, layout, stream); } //Create Layout Methods - //private Transform GetLayout(PdfPageSettings pageSettings, PdfWorksheet[] pdfSheets) - //{ - // var Layout = PdfLayout.GetLayout(pageSettings, _dictionaries, pdfSheets); - // return Layout; - //} - - //private Transform GetLayout(PdfPageSettings pageSettings, PdfWorksheet pdfSheet) - //{ - // PdfWorksheet[] pdfSheets = new PdfWorksheet[1] { pdfSheet }; - // var Layout = PdfLayout.GetLayout(pageSettings, _dictionaries, pdfSheets); - // return Layout; - //} - private Transform GetLayout(PdfPageSettings[] sheetSettings, PdfWorksheet[] pdfSheets) { var Layout = PdfLayout.GetLayout(sheetSettings, _dictionaries, pdfSheets); diff --git a/src/EPPlus/Export/PdfExport/Settings/PdfDocumentSettings.cs b/src/EPPlus/Export/PdfExport/Settings/PdfDocumentSettings.cs deleted file mode 100644 index fd7940aee..000000000 --- a/src/EPPlus/Export/PdfExport/Settings/PdfDocumentSettings.cs +++ /dev/null @@ -1,21 +0,0 @@ -using EPPlus.Fonts.OpenType; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace EPPlus.Export.Pdf.Settings -{ - internal class PdfDocumentSettings - { - internal OpenTypeFontEngine FontEngine; - internal List FontDirectories; - internal bool SearchSystemDirectories; - internal bool EmbeddFonts; - internal string defaultFontName; - internal int FirstPageNumber; - internal bool Debug; - internal bool PrintAsText; - } -} From 3af959d275948002abf8611a3e7662581dc2606c Mon Sep 17 00:00:00 2001 From: KarlKallman Date: Wed, 19 Aug 2026 14:39:08 +0200 Subject: [PATCH 4/6] Clean-up --- src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs | 15 +++------------ src/EPPlus/Export/PdfExport/PdfCatalog.cs | 13 ++++--------- .../Export/PdfExport/Settings/GetPdfSettings.cs | 1 - 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs b/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs index bc8c1720a..983f6f94c 100644 --- a/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs +++ b/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs @@ -63,13 +63,6 @@ internal class PdfLayout { private const double rowHeadingWith1CharWidth = 18d; - //public static Transform GetLayout(PdfPageSettings pageSettings, PdfDictionaries dictionaries, PdfWorksheet[] pdfSheets) - //{ - // var PagesCollection = GetPages(pageSettings, pdfSheets); - // var Catalog = GetCatalog(pageSettings, dictionaries, PagesCollection); - // return Catalog; - //} - public static Transform GetLayout(PdfPageSettings[] sheetSettings, PdfDictionaries dictionaries, PdfWorksheet[] pdfSheets) { var PagesCollection = GetPages(sheetSettings, pdfSheets); @@ -78,7 +71,6 @@ public static Transform GetLayout(PdfPageSettings[] sheetSettings, PdfDictionari return Catalog; } - //internal static Transform GetCatalog(PdfPageSettings pageSettings, PdfDictionaries dictionaries, List pdfPages) internal static Transform GetCatalog(int firstPageNumber, PdfDictionaries dictionaries, List pdfPages) { Transform Catalog = new Transform(0d, 0d, 0d, 0d); @@ -665,8 +657,7 @@ internal static List GetPages(PdfPageSettings[] sheetSettings, PdfWorkshe { var pdfSheet= pdfSheets[si]; var pageSettings = sheetSettings[si]; - //foreach (var pdfSheet in pdfSheets) - //{ + for (int ri = 0; ri < pdfSheet.Ranges.Count; ri++) { var range = pdfSheet.Ranges[ri]; @@ -680,7 +671,7 @@ internal static List GetPages(PdfPageSettings[] sheetSettings, PdfWorkshe pages.HeadingFontName = pdfSheet.NormalStyle.Style.Font.Name; pages.HeadingFontSize = pdfSheet.NormalStyle.Style.Font.Size; pages.HeadingFill = pdfSheet.NormalStyle.Style.Fill; - pages.Settings = pageSettings; // new + pages.Settings = pageSettings; PagesCollection.Add(pages); } if (pdfSheet.CommentsAndNotes.Range != null) @@ -692,7 +683,7 @@ internal static List GetPages(PdfPageSettings[] sheetSettings, PdfWorkshe pages = MapPage(pdfSheet.CommentsAndNotes, pages); pageSettings.ShowHeadings = savedShowHeadings; pages.IsCommentsPage = true; - pages.Settings = pageSettings; // NY + pages.Settings = pageSettings; PagesCollection.Add(pages); } } diff --git a/src/EPPlus/Export/PdfExport/PdfCatalog.cs b/src/EPPlus/Export/PdfExport/PdfCatalog.cs index e1e66cd16..87691222b 100644 --- a/src/EPPlus/Export/PdfExport/PdfCatalog.cs +++ b/src/EPPlus/Export/PdfExport/PdfCatalog.cs @@ -304,17 +304,15 @@ internal PdfCellCollection GetCellCollectionFromRange(PdfPageSettings pageSettin //Private Methods private Action WriteToFile(PdfPageSettings pageSettings, string fileName) - { - //return layout => new ExcelPdf().CreatePdf(pageSettings, _dictionaries, layout, fileName); + { return layout => new ExcelPdf().CreatePdf( - PdfDocumentSettings.From(pageSettings), _dictionaries, layout, fileName); + PdfDocumentSettings.From(pageSettings), _dictionaries, layout, fileName); } private Action WriteToStream(PdfPageSettings pageSettings, Stream stream) - { - //return layout => new ExcelPdf().CreatePdf(pageSettings, _dictionaries, layout, stream); + { return layout => new ExcelPdf().CreatePdf( - PdfDocumentSettings.From(pageSettings), _dictionaries, layout, stream); + PdfDocumentSettings.From(pageSettings), _dictionaries, layout, stream); } //Create Layout Methods @@ -451,9 +449,6 @@ private PdfWorksheet GetPdfWorksheet(PdfPageSettings pageSettings, ExcelWorkshee pdfSheet.Ranges.Add(new PdfRange(range, false)); } - //if (pageSettings.ShowHeadings && _addTextForHeadings) - // _dictionaries.AddFont(pageSettings, pdfSheet.NormalStyle.Style.Font.Name, pdfSheet.GetSubFamilyFromNormalStyle, "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"); - //_addTextForHeadings = false; if (pageSettings.ShowHeadings && _addTextForHeadings) { _dictionaries.AddFont(pageSettings, pdfSheet.NormalStyle.Style.Font.Name, pdfSheet.GetSubFamilyFromNormalStyle, "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"); diff --git a/src/EPPlus/Export/PdfExport/Settings/GetPdfSettings.cs b/src/EPPlus/Export/PdfExport/Settings/GetPdfSettings.cs index 7eb51052b..fb78ad66b 100644 --- a/src/EPPlus/Export/PdfExport/Settings/GetPdfSettings.cs +++ b/src/EPPlus/Export/PdfExport/Settings/GetPdfSettings.cs @@ -36,7 +36,6 @@ internal static PdfPageSettings GetPdfSettingsForSheet( private static void ApplyPrinterSettings(PdfPageSettings settings, ExcelPrinterSettings eps) { - // ← hela den befintliga kroppen flyttas hit, oförändrad var leftMargin = UnitConversion.ToMillimeters(eps.LeftMargin); var rightMargin = UnitConversion.ToMillimeters(eps.RightMargin); From aef22f2d18d6159aaa5babc64207d96d60bea673 Mon Sep 17 00:00:00 2001 From: KarlKallman Date: Thu, 20 Aug 2026 09:13:33 +0200 Subject: [PATCH 5/6] Merge and cleanup --- 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) { From 321c58c3d186c925b9b9106b3a88be88f2a4d479 Mon Sep 17 00:00:00 2001 From: KarlKallman Date: Thu, 20 Aug 2026 09:28:32 +0200 Subject: [PATCH 6/6] Another cleanup --- src/EPPlus.Export.Pdf/Settings/PdfDocumentSettings.cs | 2 +- src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EPPlus.Export.Pdf/Settings/PdfDocumentSettings.cs b/src/EPPlus.Export.Pdf/Settings/PdfDocumentSettings.cs index 5744156ba..9217ddef6 100644 --- a/src/EPPlus.Export.Pdf/Settings/PdfDocumentSettings.cs +++ b/src/EPPlus.Export.Pdf/Settings/PdfDocumentSettings.cs @@ -23,7 +23,7 @@ internal static PdfDocumentSettings From(PdfPageSettings s) return new PdfDocumentSettings { FontEngine = s.FontEngine, - FontDirectories = s.FontDirectories, // shared by reference + FontDirectories = s.FontDirectories, SearchSystemDirectories = s.SearchSystemDirectories, EmbeddFonts = s.EmbeddFonts, defaultFontName = s.defaultFontName, diff --git a/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs b/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs index 983f6f94c..b4d0bde56 100644 --- a/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs +++ b/src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs @@ -86,7 +86,7 @@ internal static Transform GetCatalog(int firstPageNumber, PdfDictionaries dictio { var page = pages[j]; PdfPageLayout pageLayout = new PdfPageLayout(0d, 0d, 0d, 0d); - pageLayout.Settings = pageSettings; // ← saknas + pageLayout.Settings = pageSettings; pageLayout.isCommentsPage = pdfPages[i].IsCommentsPage; pageLayout.HeadingWidth = page.HeadingWidth; pageLayout.HeadingHeight = page.HeadingHeight;