最近有这样一个需求,即为PDF加入带有超链接的Bookmark。PDF的开发有个特点,就是虽然相关的开发工具很多,但大都是收费的,PDFOne就是这么一个PDF开发组件,接口调用很简单,但是需要收费,而且价格不菲。
所以我还是使用了免费组件:iTextSharp,作为此次工作的重头戏。
首先先看看实体类:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
BookMarkWithURL
1
using System;
2
using System.Collections.Generic;
3![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
4
namespace MorningStar.PDFBookMarkAction.Maker
5![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
6
public class BookMarkWithURL
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
8
public BookMarkWithURL(string title, string url)
9![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
10
Title = title;
11
URL = url;
12
}
13
public BookMarkWithURL()
14![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
15
;
16
}
17![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
19
/// Title of BookMark
20
/// </summary>
21![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public string Title
{ get; set; }
22![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
24
/// Action URL of BookMark
25
/// </summary>
26![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public string URL
{ get; set; }
27
}
28
}
29![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
PDFBookMarkInfo
1
using System;
2
using System.Collections.Generic;
3![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
4
namespace MorningStar.PDFBookMarkAction.Maker
5![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
6
public class PDFBookMarkInfo
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
8
public PDFBookMarkInfo(string inputFilePath, string outputFilePath, List<BookMarkWithURL> bookMarkList)
9
: this()
10![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
11
InputFilePath = inputFilePath;
12
OutputFilePath = outputFilePath;
13
BookMarkList = bookMarkList;
14
}
15![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
public PDFBookMarkInfo()
17![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
18
BookMarkList = new List<BookMarkWithURL>();
19
}
20
21![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
22
/// Input PDF File Full Path
23
/// </summary>
24![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public string InputFilePath
{ get; set; }
25![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
26![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
27
/// Output PDF File Full Path
28
/// </summary>
29![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public string OutputFilePath
{ get; set; }
30![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
31![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
32
/// The List of BookMark with URL
33
/// </summary>
34![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public IList<BookMarkWithURL> BookMarkList
{get;set;}
35
}
36
}
之后是书签生成类:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
PDFBookMarkUrlActionMaker
1
using System;
2
using iTextSharp.text.pdf;
3
using iTextSharp.text;
4
using System.IO;
5![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
6
namespace MorningStar.PDFBookMarkAction.Maker
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
8
public class PDFBookMarkUrlActionMaker
9![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
10![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
11
/// Create BookMark With Url Action of PDF
12
/// </summary>
13
/// <param name="info">BookMark Info.</param>
14
public static void CreateBookMarkWithUrl(PDFBookMarkInfo info)
15![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
16
if (info == null)
17![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
18
throw new ArgumentNullException("info", "BookMark Info is null.");
19
}
20![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
Document document = new Document(PageSize.A4);
22![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
PdfWriter pw = PdfWriter.getInstance(document, new FileStream(info.OutputFilePath, FileMode.Create));
24
document.Open();
25![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
26
PdfContentByte cb = pw.DirectContent;
27![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
28
CopyOriginalContent(info, document, pw, cb);
29![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
30
CreateBookMarkWithURL(info, cb);
31![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
32
document.Close();
33
pw.Close();
34
}
35![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
36![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
37
/// Create BookMark With URL
38
/// </summary>
39
/// <param name="info"></param>
40
/// <param name="cb"></param>
41
private static void CreateBookMarkWithURL(PDFBookMarkInfo info, PdfContentByte cb)
42![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
43
PdfOutline root = cb.RootOutline;
44
foreach (BookMarkWithURL bookMark in info.BookMarkList)
45![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
46
PdfAction action = new PdfAction(bookMark.URL);
47
PdfOutline outLine = new PdfOutline(root, action, bookMark.Title);
48
}
49
}
50![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
51![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
52
/// Copy Original PDF Content to New PDF File
53
/// </summary>
54
/// <param name="info"></param>
55
/// <param name="document"></param>
56
/// <param name="pw"></param>
57
/// <param name="cb"></param>
58
private static void CopyOriginalContent(PDFBookMarkInfo info, Document document, PdfWriter pw, PdfContentByte cb)
59![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
60
string fileName = info.InputFilePath;
61
PdfReader reader = new PdfReader(fileName);
62
int iPageNum = reader.NumberOfPages;
63
PdfImportedPage newPage;
64
for (int j = 1; j <= iPageNum; j++)
65![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
66
Rectangle r = reader.getPageSize(j);
67
document.setPageSize(r);
68
newPage = pw.getImportedPage(reader, j);
69
document.newPage();
70
cb.addTemplate(newPage, 0, 0);
71
}
72
}
73
}
74
}
75![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
大家需要关注下,这两条语句:
PdfAction action = new PdfAction(bookMark.URL);
PdfOutline outLine = new PdfOutline(root, action, bookMark.Title);
没错,PdfOutline就是做书签的事。
如下代码,是调用该类,从而创建带有链接的书签:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
PDFModify
1
using System;
2
using iTextSharp.text.pdf;
3
using System.Windows.Forms;
4
using MorningStar.PDFBookMarkAction.Maker;
5![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
6
namespace MorningStar.Blade.PDFDemo
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
8
public class PDFModify
9![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
10
public static void AddBookMarkWithURL()
11![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
12
try
13![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
14
PDFBookMarkInfo pdfInfo = new PDFBookMarkInfo
15![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
16
InputFilePath = String.Format("{0}\\{1}", Application.StartupPath, "50975.pdf"),
17
OutputFilePath = String.Format("{0}\\{1}", Application.StartupPath, "50975_1.pdf")
18
};
19
pdfInfo.BookMarkList.Add(new BookMarkWithURL("清风飘雨的新浪博客", "http://blog.sina.com.cn/heblade"));
20
pdfInfo.BookMarkList.Add(new BookMarkWithURL("清风飘雨的博客园", "http://www.cnblogs.com/heblade/"));
21![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
22
PDFBookMarkUrlActionMaker.CreateBookMarkWithUrl(pdfInfo);
23
}
24
catch (PdfException exPDF)
25![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
26
Console.WriteLine(exPDF.Message);
27
}
28
catch (Exception ex)
29![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
30
Console.WriteLine(ex.Message);
31
}
32
}
33
}
34
}
35![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
Attention:iTextSharp在复制PDF的过程中,会将原有PDF的书签等附加信息都给清除,在使用此类之前,应对源文件有较为清楚的认知,以免造成不必要的问题。