Loading

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);            
        }
      }
}

image-20211214174049580

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");

image-20211214174122971

添加子书签
//新建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");

image-20211214174142719

添加书签到现有文档

除了在新建的 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");

image-20211214174209292

修改书签

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");

image-20211214174234256

插入新书签到现有书签列表
//加载文档
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");

image-20211214174252894

删除书签

删除书签时,可以使用书签的序号,也可以使用书签的名称。这里所使用的是序号的方式。

//加载文档
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile("Bookmark2.pdf");

//获取所有书签
PdfBookmarkCollection bookmarks = document.Bookmarks;

//删除第一个书签
bookmarks.RemoveAt(0);

//保存文档
pdf.SaveToFile("DeleteBookmark.pdf");

image-20211214174306430

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类库,理解还很浅薄,所以代码注释比较简单

当有不理解的地方时,可参考这里这里,下面的代码也是整合了这两个链接的内容和第一部分合并PDF相关操作的内容

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();
}
posted @ 2021-12-14 18:37  dsmilely  阅读(7791)  评论(0编辑  收藏  举报