C++ 解析PDF文件(含代码)

在本文中主要实现了以下功能:

本代码是在linux下运行的。三个代码是叠加的,可以直接用第三个代码。

1、找到startxref 的值。

2、根据startxref 的值找到 交叉引用表(xref),并将其条目保存在文件xref_data.txt文件中。

3、根据找到的交叉引用表(xref)条目,找到obj,并将其字典保存在obj_data.txt文件中。

1、找到startxref 的值:

实现该步骤,我们的思路是,先定位到文件末尾,再回退3行,即可找到startxref,下一行便是startxref 的值。(这里对源文件进行了处理,因为在linux下我导入的PDF文件是乱码的,换行符有时检测不到,导致多行在一行显示。故在最后的几行我手动进行换行)

下图是我随便生成的一个PDF文件,用记事本打开后的文件尾部截图:

 代码(name:lastline.cpp):

#include 
#include 
#include 
#include 
using namespace std;
int main()
{
    std::ifstream  File("p11.pdf", std::ios::ate |std::ios::binary);
    //std::ifstream  fin("/var/log/test.log", std::ios::ate);
    if (!File)
    {
        cout << "cannot open file!";
        return -1;
    }
    // 先倒回文件末尾两个字符
    File.seekg(0, File.cur);
    // 假定反向读第3行的记录
    int lineCount = 3;
    for (int i = 0; i < lineCount; i++)
    {
        // 查看前一个字符是否为回车符
        while (File.peek() != File.widen('\n'))
        {
            File.seekg(-1, File.cur);
        }
        // 走到这里表示跳过一行了,所以继续向前跳直到到3行
        File.seekg(-1, File.cur);
    }
 
    File.seekg(0, File.cur);
    std::string  line;
    //如果想将倒数lineCount行都输出,咋加入循环while
    getline(File, line);//输出为‘\n’
    //while (getline(File, line))
    //{
    	getline(File,line);
        cout << line << endl;
	
	//startxref 用于保存xref的偏移量
	int startxref = stoi(line);
	cout << startxref << endl;
	//printf("%02");
    //}
    File.clear();
    File.close();
    system("pause");
    return 0;
}

运行结果:

2、找到xref 并将其条目保存在文件xref_data.txt文件中

根据上文1中找到的startxref的值(其值表示xref 的偏移),找到xref的位置。在其后一行是条目的数量,我们需要将该值提取出来,并转换为int类型。如何for()将条目数据保存到xref_data.txt文件中。

下图为交叉引用表(windows下的截图):

C++ 解析PDF文件(含代码)_第1张图片

  代码(name:  find_xref.cpp):

#include 
#include 
#include 
#include 
using namespace std;
int main()
 {

	 //找到startxref
	std::ifstream  File("p11.pdf", std::ios::ate |std::ios::binary);
     	if (!File)
     	{
        	 cout << "cannot open file!";
	         return -1;
     	}
     	// 先倒回文件末尾两个字符
	     File.seekg(0, File.cur);
     	// 假定反向读第3行的记录
	int lineCount = 3;
	for (int i = 0; i < lineCount; i++)
     	{
 	        // 查看前一个字符是否为回车符
        	while (File.peek() != File.widen('\n'))
         	{
             		File.seekg(-1, File.cur);
	        }
         	// 走到这里表示跳过一行了,所以继续向前跳直到到3行
         	File.seekg(-1, File.cur);
        }
     	File.seekg(0, File.cur);
     	std::string  line;
     	//如果想将倒数lineCount行都输出,咋加入循环while
     	getline(File, line);//输出为‘\n’
     
         getline(File,line);
         //cout << line << endl;
         //startxref 用于保存xref的偏移量
         int startxref = stoi(line);
         cout << startxref << endl;
    
	//---------------------------保存xref的条目数据------------------------------------------
         //std::ifstream  File("p11.pdf", std::ios::ate |std::ios::binary);
         ofstream File_xref("xref_data.txt",std::ios::out);

        if (!File_xref)
        {
            cout << "cannot open file!";
            return -1;
        }
        //string line;
        //找到xref的位置
        File.seekg(startxref,File.beg);
        getline(File,line);
        cout << line<< endl;
        //找到条目数量
        getline(File,line);	
        cout << line<< endl;
        string temp;
        for(int i = 0 ; i < 100;i++){
       		if(line[i] == ' '){
			temp = line.substr(i+1);
			break;
		}
        }
        //xrefOfNumber 用于保存xref的条目数
        int xrefOfNumber = stoi(temp);
        cout << xrefOfNumber << endl;
	for(int i = 0 ; i < xrefOfNumber ;i++){
		
     		getline(File,line);
		File_xref << line <

运行结果:

C++ 解析PDF文件(含代码)_第2张图片

3、根据找到的交叉引用表(xref)条目,找到obj,并将其字典保存在obj_data.txt文件中。

xref 的条目前10位表示的是obj 的偏移(任然需要将其转换为 int 类型),可以根据其找到 obj 的位置。再将obj 字典保存到文件obj_data.txt文件中。

 代码(name:  find_obj_by_xref.cpp):

#include 
#include 
#include 
#include 
using namespace std;
int main()
 {

	//---------------------------找到startxref的值------------------------------------------
	 //找到startxref
	std::ifstream  File("p11.pdf", std::ios::ate |std::ios::binary);
     	if (!File)
     	{
        	 cout << "cannot open file!";
	         return -1;
     	}
     	
	// 先倒回文件末尾两个字符
	     File.seekg(0, File.cur);
     	// 假定反向读第3行的记录
	int lineCount = 3;
	for (int i = 0; i < lineCount; i++)
     	{
 	        // 查看前一个字符是否为回车符
        	while (File.peek() != File.widen('\n'))
         	{
             		File.seekg(-1, File.cur);
	        }
         	// 走到这里表示跳过一行了,所以继续向前跳直到到3行
         	File.seekg(-1, File.cur);
        }
     	File.seekg(0, File.cur);
     	std::string  line;
     	//如果想将倒数lineCount行都输出,咋加入循环while
     	getline(File, line);//输出为‘\n’
     
         getline(File,line);
         //cout << line << endl;
         //startxref 用于保存xref的偏移量
         int startxref = stoi(line);
         //cout << startxref << endl;
    
	//---------------------------保存xref的条目数据------------------------------------------
         ofstream File_xref("xref_data.txt",std::ios::out);

        if (!File_xref)
        {
            cout << "cannot open file!";
            return -1;
        }
        //找到xref的位置
        File.seekg(startxref,File.beg);
        getline(File,line);
        //cout << line<< endl;
        //找到条目数量
        getline(File,line);	
        //cout << line<< endl;
        string temp;
        for(int i = 0 ; i < 100;i++){
       		if(line[i] == ' '){
			temp = line.substr(i+1);
			break;
		}
        }
        //xrefOfNumber 用于保存xref的条目数
        int xrefOfNumber = stoi(temp);
        //cout << xrefOfNumber << endl;
	for(int i = 0 ; i < xrefOfNumber ;i++){
		
     		getline(File,line);
		File_xref << line <

运行结果:

C++ 解析PDF文件(含代码)_第3张图片

gitee代码地址:C++学习: C++的学习记录 - Gitee.com

 代码在文件:  找到xref以及 obj 中

以上三个代码可独立运行。

C++ 解析PDF文件(含代码)_第4张图片

你可能感兴趣的:(pdf,c++,开发语言)