C# 操作PDF大全
这里分享的两个类库,各有特色。
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();
}
作者:dsmilely
出处:https://www.cnblogs.com/dsmilely/p/15689379.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
声明:转载请注明出处!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)