在许多情况下,可能需要从PDF文件中提取文本内容,例如将PDF文档中的数据导入到Excel中进行进一步处理。虽然Adobe提供了PDF文件的文本提取服务,但有时需要在应用程序内部进行文本提取,或者需要对提取的文本进行特殊格式化(例如添加制表符),以便更容易地导入到Excel中。本文将介绍一个简单的C语言程序,用于从PDF文件中提取纯文本。
尽管Adobe提供了PDF文件的文本提取服务,但在某些情况下,可能需要自己提取文本,或者需要在应用程序内部进行文本提取。此外,可能希望对提取的文本进行特殊格式化(例如添加制表符),以便更容易地导入到Excel中。本文介绍的C语言程序可以帮助实现这一目标。
PDF文件是一种复杂的文件格式,每个PDF文件包含多个对象,每个对象可能需要一个或多个过滤器进行解压缩,并可能提供数据流。文本流通常使用FlateDecode过滤器进行压缩,可以使用ZLIB库进行解压缩。可以通过阅读PDF参考文档(例如PDFReference15_v5.pdf)来了解PDF文件的内部结构。
本文提供的C语言程序非常简单,它首先将整个PDF文件读入一个缓冲区,然后反复扫描"stream"和"endstream"部分。程序假设所有数据流都使用FlateDecode过滤器进行压缩(如果判断错误,通常不会生成该部分文件的输出,因此问题不大)。数据流解压缩后,程序会对其进行处理,搜索BT和ET标记,这些标记表示文本对象。程序会处理每个文本对象的内容,提取文本,并猜测是否需要添加制表符或换行符。
本文提供的C语言程序非常简单,但它是完全功能性的。当它应用于PDF文档时,通常可以很好地提取文本。程序已经在多个PDF文件上进行了测试。需要注意的是,这个程序是作为一个示例提供的,不提供任何保证,使用时请自行承担风险。
要使用这个C语言程序,首先需要创建一个简单的Windows 32位控制台项目,并将pdf.c文件添加到项目中。然后需要下载并添加ZLIB库(http://www.zlib.org/),将zdll.lib添加到项目目录并将其作为项目依赖项(链接它),同时将zlib1.dll、zconf.h和zlib.h添加到项目目录并将其添加到项目中。
以下是程序中的关键代码片段:
size_t streamstart = FindStringInBuffer(buffer, "stream", filelen);
size_t streamend = FindStringInBuffer(buffer, "endstream", filelen);
z_stream zstrm; ZeroMemory(&zstrm, sizeof(zstrm));
zstrm.avail_in = streamend - streamstart + 1;
zstrm.avail_out = outsize;
zstrm.next_in = (Bytef*)(buffer + streamstart);
zstrm.next_out = (Bytef*)output;
int rsti = inflateInit(&zstrm);
if (rsti == Z_OK) {
int rst2 = inflate(&zstrm, Z_FINISH);
if (rst2 >= 0) {
size_t totout = zstrm.total_out;
ProcessOutput(fileo, output, totout);
}
}
ProcessOutput函数负责处理解压缩的数据流,提取文本对象的文本部分。