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 <fstream>
#include <string>
#include <iostream>
#include <vector>
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下的截图):

  代码(name:  find_xref.cpp):

#include <fstream>
#include <string>
#include <iostream>
#include <vector>
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 <<endl;
     		cout << line<< endl;
	}     
	
        File_xref.close();
        File.clear();
        File.close();
        system("pause");
        return 0;
 }

运行结果:

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

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

 代码(name:  find_obj_by_xref.cpp):

#include <fstream>
#include <string>
#include <iostream>
#include <vector>
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 <<endl;
     		//cout << line<< endl;
	}     
	
        File_xref.close();
        //File.clear();
        //File.close();

	//---------------------------找到obj 并保存------------------------------------------
	
	std::ifstream  File_xref2("xref_data.txt", std::ios::ate |std::ios::binary);
	//将obj保存到obj_data.txt中
        ofstream File_obj("obj_data.txt",std::ios::out);


	//int xrefOfNumber = 17;
	//string temp = "";
	//string line = "" ;

     	if (!File_xref)
     	{
        	 cout << "cannot open file!";
	         return -1;
     	}

     	File_xref2.seekg(0, File_xref2.beg);
     	//string  line;
	for(int i = 0 ; i < xrefOfNumber ;i++){
	
     		getline(File_xref2, line);
		int objStart = 0;

		//交叉表的前10位表示偏移
		temp = line.substr(0,10);
		objStart = stoi(temp);
		//cout << objStart << endl;
		if(objStart == 0){
			continue;
		}

		string lineObj;
        	File.seekg(objStart,File.beg);
		//PDF文件的换行符好像是('\r\n')
		//将obj编号以及obj字典写入obj_data.txt文件
		getline(File,lineObj,'\r');
		File_obj << lineObj << endl;
		cout << lineObj << endl;

		getline(File,lineObj,'\r');
		File_obj << lineObj << endl;
		cout << lineObj << endl;
	
	}



        File_xref2.close();
        //File.clear();
        File.close();
	File_obj.close();
        system("pause");
        return 0;
 }

运行结果:

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

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

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

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: c解析office文件的开源代码有很多选择,其中比较常见的是libreoffice和Apache POI。libreoffice是一套功能强大的开源办公套件,它支持多种办公文件格式的解析和编辑,包括Microsoft Office的文件格式。libreoffice内部使用的文件格式解析代码是开源的,可以通过查看源码来理解其实现原理。 另一个常用的开源代码是Apache POI。Apache POI是一个用于操作Microsoft Office文件的开源Java库,它能够读取和写入各种Microsoft Office文件格式,如doc、docx、xls、xlsx等。POI提供了丰富的API供开发者使用,通过查看其代码可以了解如何解析和操作这些文件格式。 这些开源代码提供了对office文件格式的详细解析和操作方法,可以帮助开发者更好地理解和处理office文件的内容。通过研究这些代码,我们可以了解文件格式的结构和特性,并能够编写相关代码来实现自己的需求,如读取和修改办公文件的内容、样式、格式等。 总之,通过查看libreoffice和Apache POI等开源项目的代码,可以深入了解office文件解析和操作原理,为自己开发应用程序提供指导和帮助。 ### 回答2: C 解析 Office 文件开源代码是指通过使用开源代码,对 Microsoft Office 文件进行解析和提取其中的信息。通常情况下,Office 文件包括 Word 文档(.docx)、Excel 表格(.xlsx)和 PowerPoint 演示文稿(.pptx)等格式的文件。 目前,一些优秀的开源项目提供了解析 Office 文件的功能,并提供了相应的代码库供开发者使用。其中,最常用的几个开源项目包括 Apache POI、python-pptx、openpyxl 等。 Apache POI 是一个 Java 库,可用于读取和写入 Microsoft Office 文件。它支持解析 Word、Excel 和 PowerPoint 文件,并提供了一系列的 API 接口,便于开发者操作这些文件。通过 Apache POI,开发者可以读取 Office 文件中的文本、表格、图片及其他对象,并进行相应的操作和处理。 python-pptx 是一个用于处理 PowerPoint 文件的 Python 库。它提供了许多功能,包括读取和写入 PowerPoint 文档、创建和编辑幻灯片、添加文本和图片等。使用 python-pptx,开发者可以轻松地解析 PowerPoint 文件中的内容,并进行一系列的操作。 openpyxl 是一个处理 Excel 文件的 Python 库。使用 openpyxl,开发者可以读取和写入 Excel 表格,包括对表格的编辑、格式化、操作及数据提取等。这个开源项目提供了简单易用的 API 接口,使得通过代码解析和处理 Excel 文件变得更加便捷。 通过使用这些开源库,开发者可以灵活地对 Office 文件进行解析和提取,以满足各种需求,如数据分析、文档处理和自动化操作等。这些开源项目在社区中广泛应用,并得到了不断的更新和改进。 ### 回答3: 解析Office文件是指对Microsoft Office软件中的文件进行分析和提取信息的过程。开源代码是指可以公开查看、使用和修改的软件源代码。 要解析Office文件,可以使用一些开源的代码库和工具,例如Apache POI、LibreOffice、OpenXML SDK等。其中,Apache POI是一个流行的Java库,用于操作Microsoft Office文件。它可以读取、写入和修改Word、Excel和PowerPoint文件的内容和属性。通过POI,我们可以提取文件中的文本、表格、图表、样式等信息,并进行相应的处理和分析。 另外,LibreOffice也是一个强大的开源办公套件,可以处理各种Office文件格式。它提供了Python、Java和C++等不同语言的API,使得解析和操作Office文件变得更加灵活和方便。通过LibreOffice,我们可以提取和转换Office文件的内容,例如将Word文件转换为PDF或HTML格式,或者提取Excel文件中的数据进行统计分析。 OpenXML SDK是微软提供的一个.NET开源库,用于读取和写入Office Open XML(docx、xlsx和pptx)文件。它提供了一组强大的API,可以解析和操作Office文件的内容和结构。我们可以通过OpenXML SDK读取并分析文件的各种属性、段落、样式以及嵌入的对象等信息。 综上所述,解析Office文件的开源代码有很多选择,包括Apache POI、LibreOffice和OpenXML SDK等。使用这些代码库,我们可以方便地读取、分析和处理Office文件中的各种内容和属性。无论是从文本提取数据,还是对表格进行统计分析,都可以借助这些开源代码来实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值