Skip to content

Commit eb892ab

Browse files
committed
968706: Move and reorder bookmark in the PDF document.
1 parent 07c15fd commit eb892ab

File tree

5 files changed

+147
-0
lines changed

5 files changed

+147
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.14.36221.1 d17.14
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Move-and-reorder-bookmark-in-the-PDF", "Move-and-reorder-bookmark-in-the-PDF\Move-and-reorder-bookmark-in-the-PDF.csproj", "{2D864F6D-C55F-4995-9871-B322FAFA3B30}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{2D864F6D-C55F-4995-9871-B322FAFA3B30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{2D864F6D-C55F-4995-9871-B322FAFA3B30}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{2D864F6D-C55F-4995-9871-B322FAFA3B30}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{2D864F6D-C55F-4995-9871-B322FAFA3B30}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {77EDC987-03C1-47D2-AD47-61625B9D80FC}
24+
EndGlobalSection
25+
EndGlobal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<RootNamespace>Move_and_reorder_bookmark_in_the_PDF</RootNamespace>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<Nullable>enable</Nullable>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Syncfusion.Pdf.Net.Core" Version="*" />
13+
</ItemGroup>
14+
15+
</Project>

Bookmarks/Move-and-reorder-bookmark-in-the-PDF/.NET/Move-and-reorder-bookmark-in-the-PDF/Output/gitkeep.txt

Whitespace-only changes.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
using Syncfusion.Drawing;
2+
using Syncfusion.Pdf;
3+
using Syncfusion.Pdf.Interactive;
4+
using Syncfusion.Pdf.Parsing;
5+
class Program
6+
{
7+
static void Main(string[] args)
8+
{
9+
// Load the PDF document from disk.
10+
using (FileStream docStream = new FileStream(Path.GetFullPath(@"Data/Input.pdf"), FileMode.Open, FileAccess.Read))
11+
{
12+
// Load the PDF document into memory.
13+
PdfLoadedDocument loadedDocument = new PdfLoadedDocument(docStream);
14+
15+
// Access the root bookmark collection of the document.
16+
PdfBookmarkBase bookmarks = loadedDocument.Bookmarks;
17+
18+
// Move a bookmark from index 2 to index 0 (reorder).
19+
MoveBookmark(bookmarks, 2, 0, loadedDocument);
20+
21+
// Remove a bookmark by its title (removes the first match found in hierarchy).
22+
RemoveBookmarkByTitle(bookmarks, "Bookmark To Remove");
23+
24+
//Create file stream.
25+
using (FileStream outputFileStream = new FileStream(Path.GetFullPath(@"Output/Output.pdf"), FileMode.Create, FileAccess.ReadWrite))
26+
{
27+
loadedDocument.Save(outputFileStream);
28+
}
29+
30+
loadedDocument.Close(true);
31+
}
32+
}
33+
34+
// Moves a bookmark from one index to another within its parent collection.
35+
static void MoveBookmark(PdfBookmarkBase parentCollection, int fromIndex, int toIndex, PdfLoadedDocument document)
36+
{
37+
if (fromIndex == toIndex) return; // No move required if indices are the same.
38+
39+
// Safely cast the bookmark to be moved.
40+
PdfLoadedBookmark bookmarkToMove = parentCollection[fromIndex] as PdfLoadedBookmark;
41+
if (bookmarkToMove == null) return;
42+
43+
// Remove the bookmark from its original location.
44+
parentCollection.RemoveAt(fromIndex);
45+
46+
// Remove any existing bookmark with the same title at the new location to avoid duplicates.
47+
RemoveBookmarkByTitle(parentCollection, bookmarkToMove.Title);
48+
49+
// Insert the bookmark at the new index.
50+
PdfBookmark newBookmark = parentCollection.Insert(toIndex, bookmarkToMove.Title);
51+
newBookmark.TextStyle = bookmarkToMove.TextStyle;
52+
newBookmark.Color = bookmarkToMove.Color;
53+
54+
// Set the destination (page location/zoom) for the moved bookmark.
55+
newBookmark.Destination = bookmarkToMove.Destination ?? new PdfDestination(document.Pages[0])
56+
{
57+
Location = bookmarkToMove.Destination?.Location ?? new PointF(0, 0),
58+
Zoom = bookmarkToMove.Destination?.Zoom ?? 1F
59+
};
60+
61+
// Move all child bookmarks recursively.
62+
foreach (PdfBookmark child in bookmarkToMove)
63+
{
64+
AddBookmark(newBookmark, child, document);
65+
}
66+
}
67+
68+
// Clones an existing bookmark (including all descendants) and adds it to a parent.
69+
static void AddBookmark(PdfBookmark parent, PdfBookmark bookmark, PdfLoadedDocument document)
70+
{
71+
// Remove any even-closer duplicate title children before insertion.
72+
RemoveBookmarkByTitle(parent, bookmark.Title);
73+
74+
PdfBookmark newChild = parent.Insert(parent.Count, bookmark.Title);
75+
newChild.Destination = bookmark.Destination ?? new PdfDestination(document.Pages[0])
76+
{
77+
Location = new PointF(0, 0),
78+
Zoom = 1F
79+
};
80+
newChild.TextStyle = bookmark.TextStyle;
81+
newChild.Color = bookmark.Color;
82+
83+
// Recursively clone and add children.
84+
foreach (PdfBookmark child in bookmark)
85+
{
86+
AddBookmark(newChild, child, document);
87+
}
88+
}
89+
90+
// Removes the first occurrence of a bookmark with the specified title from a parent (searches recursively).
91+
static void RemoveBookmarkByTitle(PdfBookmarkBase parent, string title)
92+
{
93+
for (int i = 0; i < parent.Count;)
94+
{
95+
if (parent[i].Title == title)
96+
{
97+
parent.RemoveAt(i);
98+
continue;
99+
}
100+
if (parent[i] is PdfBookmark child)
101+
{
102+
RemoveBookmarkByTitle(child, title); // Recurse for children
103+
}
104+
i++;
105+
}
106+
}
107+
}

0 commit comments

Comments
 (0)