Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
83ec240
started work in scaling pdf with percentage
AdrianEPPlus Sep 22, 2026
76ec058
Merge branch 'develop9' into feature/pdf_scaling
AdrianEPPlus Sep 22, 2026
246d6c6
Progress
AdrianEPPlus Sep 22, 2026
b1593ac
Scaling header and footer
AdrianEPPlus Sep 23, 2026
4e1303d
Added fit to page test.
AdrianEPPlus Sep 24, 2026
b65aa60
scaling progress
AdrianEPPlus Oct 1, 2026
40117fe
Added more tests for scaling
AdrianEPPlus Oct 5, 2026
9036253
Merge branch 'develop9' into feature/pdf_scaling
AdrianEPPlus Oct 5, 2026
9fdbd4d
Fixed layout order and renamed PdfCatalog to EPPlusToPdfWriter
AdrianEPPlus Oct 7, 2026
e02c710
Merge branch 'develop9' into fix/_pdf_minior_issues
AdrianEPPlus Oct 7, 2026
a9e363d
removed debug comments
AdrianEPPlus Oct 7, 2026
912d439
removed more comments from pdf.
AdrianEPPlus Oct 7, 2026
5dd4d79
Added additional info to info object.
AdrianEPPlus Oct 8, 2026
a930c16
Merge branch 'develop9' into feature/pdf_info_object_update
swmal Oct 8, 2026
7a7a324
Merge branch 'develop9' into feature/pdf_info_object_update
swmal Oct 8, 2026
d7cac71
fixed null error when reading File from package.
AdrianEPPlus Oct 8, 2026
cc62230
header footer scaling.
AdrianEPPlus Oct 12, 2026
2ed20f9
align with page margins progress
AdrianEPPlus Oct 12, 2026
34386a3
Align with page margins done
AdrianEPPlus Oct 12, 2026
84e91a5
Merge branch 'develop9' into fix/pdf_hf_fixes
AdrianEPPlus Oct 13, 2026
fa91931
removed commented code.
AdrianEPPlus Oct 13, 2026
0244d3c
Added shrink to fit & better check clipping for spilling text.
AdrianEPPlus Oct 13, 2026
b00cdbb
Fixed fill selection for total row in tables.
AdrianEPPlus Oct 13, 2026
7b41847
Added draft feature to pdf.
AdrianEPPlus Oct 14, 2026
bdcbd2a
Merge branch 'develop9' into feature/pdf_draft
AdrianEPPlus Oct 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/EPPlus.Export.Pdf.Tests/PdfTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Date Author Change
using OfficeOpenXml.Style;
using OfficeOpenXml.Table;
using System.Data;
using System.Drawing.Printing;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
Expand Down Expand Up @@ -1325,5 +1326,15 @@ public void TableDxfStyleTest2()
string path = _pdfPath + "TableDxfStylePdf2.pdf";
ws.SaveAsPdf(path);
}

[TestMethod]
public void PdfIsDraftTest1()
{
using var p = OpenTemplatePackage("PDFTest.xlsx");
var ws = p.Workbook.Worksheets[0];
ws.PrinterSettings.Draft = true;
string path = _pdfPath + "DraftTest1.pdf";
ws.SaveAsPdf(path);
}
}
}
151 changes: 86 additions & 65 deletions src/EPPlus/Export/PdfExport/Layout/PdfLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ internal static Transform GetCatalog(int firstPageNumber, PdfDictionaries dictio
for (int i = 0; i < pdfPages.Count; i++)
{
var pageSettings = pdfPages[i].Settings;
bool isDraft = pageSettings.Draft;
if (pdfPages[i].SheetIndex != currentSheetIndex)
{
currentSheetIndex = pdfPages[i].SheetIndex;
Expand Down Expand Up @@ -140,17 +141,20 @@ internal static Transform GetCatalog(int firstPageNumber, PdfDictionaries dictio
pages[j].MergedCells.TryGetValue(key, out info))
{
//Fill
var cellStyle = map.Main?.CellStyle ?? map.CellStyle;
var fill = new PdfCellLayout(info.X, info.Y, info.Width, info.Height);
SetFill(dictionaries, cellStyle, map.Text, fill);
fill.Name = map.Name;
fill.UpdateShadingPositionMatrix(pageSettings);
pageLayout.AddChild(fill);
//In-cell picture
var picMap = (map.CellPictureBytes != null) ? map : (map.Main != null && map.Main.CellPictureBytes != null) ? map.Main : null;
if (picMap != null)
if (!isDraft)
{
AddCellPicture(pageLayout, picMap, info.X, info.Y, info.Width, info.Height);
var cellStyle = map.Main?.CellStyle ?? map.CellStyle;
var fill = new PdfCellLayout(info.X, info.Y, info.Width, info.Height);
SetFill(dictionaries, cellStyle, map.Text, fill);
fill.Name = map.Name;
fill.UpdateShadingPositionMatrix(pageSettings);
pageLayout.AddChild(fill);
//In-cell picture
var picMap = (map.CellPictureBytes != null) ? map : (map.Main != null && map.Main.CellPictureBytes != null) ? map.Main : null;
if (picMap != null)
{
AddCellPicture(pageLayout, picMap, info.X, info.Y, info.Width, info.Height);
}
}
//Text
var sourceMap = (map.TextLines != null && map.TextLines.Count > 0) ? map : (map.Main != null && map.Main.TextLines != null && map.Main.TextLines.Count > 0) ? map.Main : null;
Expand All @@ -162,26 +166,29 @@ internal static Transform GetCatalog(int firstPageNumber, PdfDictionaries dictio
text.SetupClipping(info.X, info.Y, info.Width, info.Height);
pageLayout.AddChild(text);
}
if (map.Main != null)
if (!isDraft)
{
var mergeMainStyle = map.Main.CellStyle;
if (HasDiagonalBorder(mergeMainStyle))
if (map.Main != null)
{
var diagBorder = new PdfCellBorderLayout(
isMerged: false,
corners: MergedCellCorners.All,
info: info,
x: info.X,
y: info.Y,
width: info.Width,
height: info.Height);
SetBorderStyle(mergeMainStyle, diagBorder);
diagBorder.Name = map.Name;
diagBorder.BorderData.Top.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
diagBorder.BorderData.Bottom.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
diagBorder.BorderData.Left.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
diagBorder.BorderData.Right.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
pageLayout.AddChild(diagBorder);
var mergeMainStyle = map.Main.CellStyle;
if (HasDiagonalBorder(mergeMainStyle))
{
var diagBorder = new PdfCellBorderLayout(
isMerged: false,
corners: MergedCellCorners.All,
info: info,
x: info.X,
y: info.Y,
width: info.Width,
height: info.Height);
SetBorderStyle(mergeMainStyle, diagBorder);
diagBorder.Name = map.Name;
diagBorder.BorderData.Top.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
diagBorder.BorderData.Bottom.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
diagBorder.BorderData.Left.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
diagBorder.BorderData.Right.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
pageLayout.AddChild(diagBorder);
}
}
}
drawnMergedCells.Add(key);
Expand All @@ -192,13 +199,16 @@ internal static Transform GetCatalog(int firstPageNumber, PdfDictionaries dictio
var contentRight = pageSettings.ContentBounds.Left + pageSettings.ContentBounds.Width;
var effectiveWidth = GetClampedCellWidth(pageSettings, x, map.ColumnWidth);
//Fill
var fill = new PdfCellLayout(x, y, effectiveWidth, rowHeight);
SetFill(dictionaries, map.CellStyle, map.Text, fill);
fill.UpdateShadingPositionMatrix(pageSettings);
fill.Name = map.Name;
pageLayout.AddChild(fill);
//In-cell picture
AddCellPicture(pageLayout, map, x, y, effectiveWidth, rowHeight);
if (!isDraft)
{
var fill = new PdfCellLayout(x, y, effectiveWidth, rowHeight);
SetFill(dictionaries, map.CellStyle, map.Text, fill);
fill.UpdateShadingPositionMatrix(pageSettings);
fill.Name = map.Name;
pageLayout.AddChild(fill);
//In-cell picture
AddCellPicture(pageLayout, map, x, y, effectiveWidth, rowHeight);
}
//Text
if (map.TextLines != null && map.TextLines.Count > 0)
{
Expand All @@ -210,38 +220,44 @@ internal static Transform GetCatalog(int firstPageNumber, PdfDictionaries dictio
pageLayout.AddChild(text);
}
}
//Border
var borderStyle = (map.Merged && map.Main != null) ? map.Main.CellStyle : map.CellStyle;
if (HasBorder(map.CellStyle))
if (!isDraft)
{
var border = new PdfCellBorderLayout(map.Merged, GetCorners(map.MergedAddress, row, col), info, x, y, map.ColumnWidth, rowHeight);
SetBorderStyle(map.CellStyle, border);
border.Name = map.Name;
if (map.Merged && map.MergedAddress != null)
//Border
var borderStyle = (map.Merged && map.Main != null) ? map.Main.CellStyle : map.CellStyle;
if (HasBorder(map.CellStyle))
{
var addr = map.MergedAddress;
if (row != addr.Start.Row) border.BorderData.Top.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
if (row != addr.End.Row) border.BorderData.Bottom.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
if (col != addr.Start.Column) border.BorderData.Left.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
if (col != addr.End.Column) border.BorderData.Right.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
var border = new PdfCellBorderLayout(map.Merged, GetCorners(map.MergedAddress, row, col), info, x, y, map.ColumnWidth, rowHeight);
SetBorderStyle(map.CellStyle, border);
border.Name = map.Name;
if (map.Merged && map.MergedAddress != null)
{
var addr = map.MergedAddress;
if (row != addr.Start.Row) border.BorderData.Top.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
if (row != addr.End.Row) border.BorderData.Bottom.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
if (col != addr.Start.Column) border.BorderData.Left.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
if (col != addr.End.Column) border.BorderData.Right.BorderStyle = (EPPlus.Export.Pdf.Enums.ExcelBorderStyle)ExcelBorderStyle.None;
}
SetDoubleBorderMiterFlags(pages[j], row, col, border);
pageLayout.AddChild(border);
}
SetDoubleBorderMiterFlags(pages[j], row, col, border);
pageLayout.AddChild(border);
}
x += map.ColumnWidth;
}
y -= rowHeight;
x = contentStartX;
}
if (page.Images != null)
if (!isDraft)
{
foreach (var img in page.Images)
if (page.Images != null)
{
pageLayout.AddChild(new PdfImageLayout(img.X, img.Y, img.Width, img.Height)
foreach (var img in page.Images)
{
ImageBytes = img.ImageBytes,
Name = img.Name,
});
pageLayout.AddChild(new PdfImageLayout(img.X, img.Y, img.Width, img.Height)
{
ImageBytes = img.ImageBytes,
Name = img.Name,
});
}
}
}
if (page.HeaderFooters != null)
Expand Down Expand Up @@ -424,7 +440,8 @@ internal static Transform GetCatalog(int firstPageNumber, PdfDictionaries dictio
cellcont.GidsAndCharMap(dictionaries);
pageLayout.AddChild(cellcont);
}
PdfGridlinesLayout.AddGridLines(pageSettings, pages[j], pageLayout, borderOnly: !pageSettings.ShowGridLines || pdfPages[i].IsCommentsPage);
if(!isDraft)
PdfGridlinesLayout.AddGridLines(pageSettings, pages[j], pageLayout, borderOnly: !pageSettings.ShowGridLines || pdfPages[i].IsCommentsPage);
pageLayout.ChildObjects.Sort((a, b) =>
{
int cmp = a.Z.CompareTo(b.Z);
Expand Down Expand Up @@ -710,7 +727,8 @@ private static void AddHeadingCell(PdfPageSettings pageSettings, PdfDictionaries
text.GidsAndCharMap(dictionaries);
pageLayout.AddChild(text);
}
AddHeadingCellBorder(pageLayout, x, y, width, height);
if(!pageSettings.Draft)
AddHeadingCellBorder(pageLayout, x, y, width, height);
}

private static void AddHeadingCells(PdfPageSettings pageSettings, PdfDictionaries dictionaries, Page page, PdfPageLayout pageLayout, double contentStartX, double contentStartY, double headingWidth, double headingHeight, string fontName, float fontSize, ExcelFill fill)
Expand All @@ -732,15 +750,18 @@ private static void AddHeadingCells(PdfPageSettings pageSettings, PdfDictionarie
x, GetOriginY(pageSettings, page), colWidth, headingHeight, fontName, fontSize, "Heading_Col_" + colLetter);
x += colWidth;
}
double y = contentStartY;
for (int row = page.FromRow; row <= page.ToRow; row++)
if (!pageSettings.Draft)
{
double rowHeight = page.RowHeights[row - page.FromRow];
if (rowHeight == 0d) { y -= rowHeight; continue; }
string rowNum = row.ToString();
AddHeadingCell(pageSettings, dictionaries, pageLayout, headingStyle, rowNum,
GetOriginX(pageSettings, page), y, headingWidth, rowHeight, fontName, fontSize, "Heading_Row_" + rowNum);
y -= rowHeight;
double y = contentStartY;
for (int row = page.FromRow; row <= page.ToRow; row++)
{
double rowHeight = page.RowHeights[row - page.FromRow];
if (rowHeight == 0d) { y -= rowHeight; continue; }
string rowNum = row.ToString();
AddHeadingCell(pageSettings, dictionaries, pageLayout, headingStyle, rowNum,
GetOriginX(pageSettings, page), y, headingWidth, rowHeight, fontName, fontSize, "Heading_Row_" + rowNum);
y -= rowHeight;
}
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/EPPlus/Export/PdfExport/TextMapping/PdfTextMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,14 +207,14 @@ private static IEnumerable<ExcelTableStyleElement> GetApplicableTableElements(Ex
yield return (tableRow & 1) != 0 ? ts.FirstRowStripe // 4
: ts.SecondRowStripe; // 5

if (lastCol) yield return ts.LastColumn; // 6
if (lastCol) yield return ts.LastColumn; // 6
if (firstCol) yield return ts.FirstColumn; // 7
if (total) yield return ts.TotalRow; // 8
if (header) yield return ts.HeaderRow; // 9
if (total) yield return ts.TotalRow; // 8
if (header) yield return ts.HeaderRow; // 9
if (header && firstCol) yield return ts.FirstHeaderCell; // 10
if (header && lastCol) yield return ts.LastHeaderCell; // 11
if (total && firstCol) yield return ts.FirstTotalCell; // 12
if (total && lastCol) yield return ts.LastTotalCell; // 13
if (header && lastCol) yield return ts.LastHeaderCell; // 11
if (total && firstCol) yield return ts.FirstTotalCell; // 12
if (total && lastCol) yield return ts.LastTotalCell; // 13
}

// Overlay only the font properties `src` actually specifies onto `dst`. All members are on the base type.
Expand Down
Loading