PDF 页数计数器





5.00/5 (7投票s)
快速计算 PDF 文档集合中的页面数量
- 下载 RedCell.App.Graphics.PdfPageCounter-noexe.zip - 5.5 MB
- 下载 RedCell.App.Graphics.PdfPageCounter.zip - 5.5 MB
引言
我的公司 Red Cell Innovation Inc. 提供文档扫描服务。我们经常需要统计一批 PDF 文件的页数,用于计费、质量控制、排程和估算。
这是我快速编写的一个应用程序,以方便完成这项工作。该应用程序使用过程化风格,在单个简单的代码后台类中用大约 200 行代码(包括 XAML 和注释)实现此功能。
特点
- 简单:将一个目录拖放到应用程序中。
- 快速:扫描了 20GB 的 PDF 文件,并在 7 秒内(在网络驱动器上为 270 秒)统计了 499 个文件中的 53877 页,使用 SSD。
工作原理
语言 | C# 5.0 |
.NET Framework | 4.5 |
UI 框架 | WPF |
库 | iTextSharp |
模式 | 代码后台过程化 |
当应用程序启动时,会提示用户将文件和/或文件夹拖放到应用程序窗口中。
当拖放文件或文件夹时,会调用 Start
方法,更改 UI 元素的可见性以显示计数屏幕。
调用 async Analyze
方法以创建一个新线程,递归地遍历文件系统。将从线程池请求一个新线程,用于枚举每个目录及其文件计数。
private async Task Analyze (IEnumerable<string> filenames)
{
await Task.Run(async () =>
{
foreach (string filename in filenames)
{
if (this._cancel)
break;
Dispatcher.Invoke(Update);
if (Directory.Exists(filename))
{
string[] nestedFilenames = Directory.GetFiles(filename, "*.pdf", SearchOption.AllDirectories);
await Analyze(nestedFilenames);
}
this._files++;
if (new FileInfo(filename).Extension.ToLower() != ".pdf")
continue;
this._filesPdf++;
int pages = Count(filename);
this._pages += pages;
}
Dispatcher.Invoke(Update);
});
}
private int Count (string filename)
{
using (var reader = new PdfReader(filename))
{
int pages = reader.NumberOfPages;
reader.Close();
return pages;
}
}
Count
方法使用了 iTextSharp 库来读取 PDF 文件。由于 PDF 文件内部已建立索引,因此无需扫描文档(请参阅 PDF 语法)。相反,实例化一个 PdfReader
对象并读取其 NumberOfPages
属性。
使用的系统资源可以忽略不计。
PDF 语法
通过创建简单的 PDF 解析器,可以很容易地完成此操作;但是,这将增加开发应用程序所需的时间,而我已经熟悉 iTextSharp,并且开发时间约为一小时。
为了不使用 iTextSharp 完成此操作,我们将读取 PDF 并跟踪引用。
这是一个语法正确且完整的 PDF 文件。要找到该部分,我们首先检查 Trailer
,它将引用 1
指定为 Root
。我们可以看到部分 1
包含 Catalog
,它将引用 3
指向 Pages
部分。请注意,Pages
资源描述了一个页面,该页面在部分 4
中描述。
%PDF-1. 4
1 0 obj
<< /Type /Catalog
/Outlines 2 0 R
/Pages 3 0 R
>>
endobj
2 0 obj
<< /Type Outlines
/Count 0
>>
endobj
3 0 obj
<< /Type /Pages
/Kids [ 4 0 R ]
/Count 1
>>
endobj
4 0 obj
<< /Type /Page
/Parent 3 0 R
/MediaBox [ 0 0 612 792 ]
/Contents 5 0 R
/Resources << /ProcSet 6 0 R >>
>>
endobj
5 0 obj
<< /Length 35 >>
stream
<-- Page-marking operators -->
endstream
endobj
6 0 obj
[ /PDF ]
endobj
xref
0 7
0000000000 65535 f
0000000009 00000 n
0000000074 00000 n
0000000120 00000 n
0000000179 00000 n
0000000300 00000 n
0000000384 00000 n
trailer
<< /Size 7
/Root 1 0 R
>>
startxref
408
%%EOF
致谢
iTextSharp 是 Paulo Soares、Bruce Lowagie 等人的作品。
PDF 文件语法示例来自 PDF 参考,第六版。© 2006 Adobe®Systems Incorporated。
历史
2014 年 1 月 18 日 | 应用程序编写完成 |
2014 年 10 月 24 日 | 文章编写完成 |