這里分享的兩個類庫,各有特色。
Spire.Pdf 容易理解,使用方便,但效率比較低,操作PDF數量多,會占用特別多內存,甚至內存溢出。
iTextSharp 不容易理解,尤其是添加書簽部分,但效率奇高,5000份單張PDF文件同時合並、添加書簽用時2-3秒,內存在用少。
類庫 Spire.Pdf
1、書簽相關操作
書簽相關操作在這里有詳細介紹,此處我留下連接並拿來主義,防止某天網頁無法訪問
概述:Spire.PDF 是一個專業的 PDF 組件,能夠獨立地創建、編寫、編輯、操作和閱讀 PDF 文件,支持 .NET、Java、WPF 和 Silverlight。書簽不僅可以幫助我們跳轉到文檔中相應的位置,還可以讓我們快速地了解文檔所講述的內容。本文將介紹如何添加刪除 PDF 書簽,獲取多級書簽。
書簽不僅可以幫助我們跳轉到文檔中相應的位置,還可以讓我們快速地了解文檔所講述的內容。本文將介紹如何添加刪除 PDF 書簽,獲取多級書簽。
C# 獲取 PDF 多級書簽
Spire.PDF 不僅支持對簡單書簽的操作,還支持多級書簽。接下來將介紹如何使用 Spire.PDF 來獲取 PDF 文檔中的多級書簽。
static void Main(string[] args)
{
//加載含有多級書簽的PDF文件
PdfDocument doc = new PdfDocument();
doc.LoadFromFile("示例.pdf");
//獲取文檔的書簽
PdfBookmarkCollection bookmarks = doc.Bookmarks;
//聲明一個可變字符串
StringBuilder stringbuilder = new StringBuilder();
//獲取父書簽和子書簽
GetBookmarkTitle(bookmarks, stringbuilder);
//聲明txt文件,並將獲得的多級書簽寫入到文件.txt
String fileName = "D://文件.txt";
File.WriteAllText(fileName, stringbuilder.ToString());
Console.ReadLine();
}
static void GetBookmarkTitle(PdfBookmarkCollection bookmarks, StringBuilder stringbuilder)
{
if (bookmarks.Count > 0)
{
foreach (PdfBookmark parentBookmark in bookmarks)
{
stringbuilder.AppendLine(parentBookmark.Title);
//遞歸文檔多級書簽
GetBookmarkTitle(parentBookmark, stringbuilder);
}
}
}
C# 添加、修改和刪除 PDF 書簽
添加書簽
在 Spire.PDF 中,每個 PDF 文檔都有一個書簽列表(PdfBookmarkCollection)。我們可以通過 PdfDocument 對象的 Bookmarks 屬性來獲取該列表,然后通過 Add () 方法將書簽添加到列表中。
//新建PDF文檔
PdfDocument pdf = new PdfDocument();
//添加頁面
PdfPageBase page = pdf.Pages.Add();
//添加書簽
PdfBookmark bookmark = pdf.Bookmarks.Add("第一頁");
//設置書簽所指向的頁面和位置,(0,0)表示頁面的開始位置
bookmark.Destination = new PdfDestination(page);
bookmark.Destination.Location = new PointF(0, 0);
//設置書簽的文本格式和顏色
bookmark.DisplayStyle = PdfTextStyle.Bold;
bookmark.Color = Color.Black;
//保存文檔
pdf.SaveToFile("Bookmark2.pdf");
添加子書簽
//新建PDF文檔
PdfDocument pdf = new PdfDocument();
//添加頁面
PdfPageBase page = pdf.Pages.Add();
//添加書簽
PdfBookmark bookmark = pdf.Bookmarks.Add("第一章 熱傳導");
//設置書簽指向的頁面和位置
bookmark.Destination = new PdfDestination(page);
bookmark.Destination.Location = new PointF(0, 0);
//設置書簽的文本格式和顏色
bookmark.DisplayStyle = PdfTextStyle.Bold;
bookmark.Color = Color.SeaGreen;
//添加子書簽
PdfBookmark childBookmark = bookmark.Insert(0, "1.1 熱傳導基本知識");
//設置子書簽指向的頁面和位置
childBookmark.Destination = new PdfDestination(page);
childBookmark.Destination.Location = new PointF(400, 300);
//設置子書簽的文本格式和顏色
childBookmark.DisplayStyle = PdfTextStyle.Regular;
childBookmark.Color = Color.Black;
//保存文檔
pdf.SaveToFile("ChildBookmark.pdf");
添加書簽到現有文檔
除了在新建的 PDF 文檔里添加書簽,我們還可以給現有的 PDF 文檔添加書簽。加載 PDF 文檔的方法除 LoadFromFile 以外,還有 LoadFromStream (從流加載),LoadFromHTML(從 HTML 加載)等,可根據自己的需求選擇相應的加載方式。
//加載文檔
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile("示例.pdf");
for (int i = 0; i < pdf.Pages.Count; i++)
{
//添加書簽
PdfBookmark bookmark = pdf.Bookmarks.Add(string.Format("第{0}章", i+1));
//設置書簽指向的頁面和位置
bookmark.Destination = new PdfDestination(pdf.Pages[i]);
bookmark.Destination.Location = new PointF(0, 0);
//設置書簽的文本格式和顏色
bookmark.DisplayStyle = PdfTextStyle.Bold;
bookmark.Color = Color.Black;
}
//保存文檔
pdf.SaveToFile("Bookmark2.pdf");
修改書簽
Spire.PDF 支持多種書簽修改方式,例如修改現有書簽的內容,插入新書簽到現有書簽列表,插入子書簽到現有書簽等。這里我們選取修改書簽內容和插入新書簽到現有書簽列表進行介紹。
修改現有書簽內容
//加載文檔
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile("Bookmark2.pdf");
//獲取書簽列表
PdfBookmarkCollection bookmarks = pdf.Bookmarks;
//獲取第一個書簽
PdfBookmark bookmark = bookmarks[0];
//修改書簽指向的頁面
bookmark.Destination = new PdfDestination(document.Pages[1]);
//修改書簽的文本格式和顏色
bookmark.DisplayStyle = PdfTextStyle.Bold;
bookmark.Color = Color.Green;
//修改書簽的title
bookmark.Title = "修改";
//保存文檔
pdf.SaveToFile("ModifyBookmark.pdf");
插入新書簽到現有書簽列表
//加載文檔
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile("Bookmark2.pdf");
//插入新書簽到指定位置
PdfBookmark bookmark = pdf.Bookmarks.Insert(2, "新增第三章");
//設置書簽所指向的頁面和位置
bookmark.Destination = new PdfDestination(document.Pages[1]);
bookmark.Destination.Location = new PointF(0, 300);
//保存文檔
pdf.SaveToFile("InsertBookmark.pdf");
刪除書簽
刪除書簽時,可以使用書簽的序號,也可以使用書簽的名稱。這里所使用的是序號的方式。
//加載文檔
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile("Bookmark2.pdf");
//獲取所有書簽
PdfBookmarkCollection bookmarks = document.Bookmarks;
//刪除第一個書簽
bookmarks.RemoveAt(0);
//保存文檔
pdf.SaveToFile("DeleteBookmark.pdf");
2、合並PDF相關操作
使用PdfDocument.MergeFiles(string[] filePath)
使用此方法合並PDF,如文件數量過多,容易造成內存泄漏,代碼量少易理解但效率較低
using Spire.Pdf;
PdfDocumentBase doc = PdfDocument.MergeFiles(pdfFiles); //pdfFiles是PDF文件路徑組成的數組
doc.Save(_fileSavePath + "\\單線圖合訂本.pdf"); //保存文檔
使用PdfDocument.InsertPage方法插入PDF的方法合並PDF並添加書簽
使用此方法合並PDF,如文件數量過多,容易造成內存泄漏,代碼量少易理解但效率較低
using Spire.Pdf;
using Spire.Pdf.Bookmarks;
using Spire.Pdf.General;
PdfDocument[] docs = new PdfDocument[pdfFiles.Length]; //pdfFiles是PDF文件路徑組成的數組
PdfDocument doc = new PdfDocument(); //新建合訂本PDF文件
PdfPageBase page;
PdfBookmark bookmark;
for (int i = 0; i < pdfFiles.Length; i++)
{
docs[i] = new PdfDocument(pdfFiles[i]);
page = doc.InsertPage(docs[i], 0); //插入頁面,參數0代表將docs[i]的第一頁插入到doc中
//在合並PDF的過程中同時為每頁添加書簽
bookmark = doc.Bookmarks.Add(Path.GetFileNameWithoutExtension(pdfFiles[i])); //添加書簽
//設置書簽所指向的頁面和位置,(0,0)表示頁面的開始位置
bookmark.Destination = new PdfDestination(page);
bookmark.Destination.Location = new PointF(0, 0);
//設置書簽的文本格式和顏色
bookmark.DisplayStyle = PdfTextStyle.Bold;
bookmark.Color = Color.Black;
}
doc.SaveToFile(_fileSavePath + "\\單線圖合訂本.pdf"); //保存文檔
類庫 iTextSharp
1、合並PDF相關操作
效率非常高
using iTextSharp.text;
using iTextSharp.text.pdf;
using (var stream = new FileStream(_fileSavePath + "\\單線圖合訂本.pdf", FileMode.Create))
{
using (Document doc = new Document())
{
using (var pdfCopy = new PdfCopy(doc, stream))
{
doc.Open();
for (int i = 0; i < pdfFiles.Length; i++)
{
var reader = new PdfReader(pdfFiles[i]);
var page = pdfCopy.GetImportedPage(reader, 1);
pdfCopy.AddPage(page);
pdfCopy.FreeReader(reader);
reader.Close();
}
}
}
}
2、合並PDF相關並創建書簽
由於是第一次使用ITextSharp類庫,理解還很淺薄,所以代碼注釋比較簡單
using iTextSharp.text;
using iTextSharp.text.pdf;
List<Dictionary<string, object>> bookmarks = new List<Dictionary<string, object>>();
using (var stream = new FileStream(_fileSavePath + "\\單線圖合訂本.pdf", FileMode.Create))
{
using (Document doc = new Document())
{
using (var pdfCopy = new PdfCopy(doc, stream))
{
doc.Open();
for (int i = 0; i < pdfFiles.Length; i++)
{
var reader = new PdfReader(pdfFiles[i]);
var page = pdfCopy.GetImportedPage(reader, 1); //獲取第一頁
pdfCopy.AddPage(page);
var h = page.Height; //取第一頁高度
var bookmark = new Dictionary<string,object>();
bookmark.Add("Action", "GoTo");
bookmark.Add("Title", Path.GetFileNameWithoutExtension(pdfFiles[i])); //標簽名稱
//i + 1 + " XYZ 0 " + h + " 0" 定位代表第幾頁坐標
bookmark.Add("Page", i + 1 + " XYZ 0 " + h + " 0");
bookmarks.Add(test);
//pdfCopy.Outlines = (IList<Dictionary<string, object>>)bookmarks;
pdfCopy.FreeReader(reader);
reader.Close();
}
pdfCopy.Outlines = bookmarks; //為合訂本設置書簽
}
}
}
3、合並PDF(帶原PDF書簽)
下面方法是網上找到了,親測是可以使用的,除添加的備注未做任何修改,貼上來供參考理解
private void MergePdfFilesWithBookMark(string[] sourcePdfs, string outputPdf)
{
PdfReader reader = null;
Document document = new Document();
PdfImportedPage page = null;
PdfCopy pdfCpy = null;
int n = 0;
int totalPages = 0;
int page_offset = 0;
List<Dictionary<string, object>> bookmarks = new List<Dictionary<string, object>>();
IList<Dictionary<string, object>> tempBookmarks;
for (int i = 0; i <= sourcePdfs.GetUpperBound(0); i++)
{
reader = new PdfReader(sourcePdfs[i]);
reader.ConsolidateNamedDestinations();
n = reader.NumberOfPages;
tempBookmarks = SimpleBookmark.GetBookmark(reader);
//獲取原PDF的書簽並保存到bookmarks中
if (i == 0)
{
document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));
pdfCpy = new PdfCopy(document, new FileStream(outputPdf, FileMode.Create));
document.Open();
SimpleBookmark.ShiftPageNumbers(tempBookmarks, page_offset, null);
page_offset += n;
if (tempBookmarks != null)
bookmarks.AddRange(tempBookmarks);
// MessageBox.Show(n.ToString());
totalPages = n;
}
else
{
SimpleBookmark.ShiftPageNumbers(tempBookmarks, page_offset, null);
if (tempBookmarks != null)
bookmarks.AddRange(tempBookmarks);
page_offset += n;
totalPages += n;
}
//合並PDF
for (int j = 1; j <= n; j++)
{
page = pdfCpy.GetImportedPage(reader, j);
pdfCpy.AddPage(page);
}
reader.Close();
}
pdfCpy.Outlines = bookmarks; /為合訂本設置書簽
document.Close();
}