刚刚结束的一个事情,仅限于完成了任务。 一、任务描述 有一个超巨型的资料性的文件,是网页上查询之后的结果,有几百页、几百笔资料,需要把里面的资料一条一条的列在一个单独立的文件里面,并且,文件用“组序号-标识-名称.pdf”来命名。 组序号由另一份Excel文件给出,每组之中有标识和名称域与超巨pdf中的相应域对应。 难点: 1、不能手工操作。不易一一对应,且不产生马虎和疏忽的错误。 2、没有长期时间。大致实测,一笔资料从信息提取、标识对应、生成新文件、按规则命名大约3分钟左右时间,1000笔资料大约50小时,每天8小时不动,大约6天,一周。一周下来,估计人也就废了。我相信这事儿没有两周干不下来。 3、不易协同作业。Excel文件规格不尽相同,且超巨pdf不便扩散,所以最好是一下子over。 二、任务分解 1、根据标识号拆分超巨pdf。这一步可以在python里用PyPDF2包完成。 2、规范Excel格式和内容。这一步在Excel里面用排序、函数和VBA足够,之后导出为csv,便于最终Delphi处理它们。 3、根据标识和名称对应并拼接资料,按标识生成单个pdf文件。由于所有资料都没有放置在数据库里,因此统一按字段当成格式文本来搜索是否有匹配。无匹配时,再巡回一次,避免标识不在指定的位置上。 三、功能片断 1、拆分超巨pdf。 部分代码: ''' 分拆一个多页大pdf文件为指定页数的小pdf子文件 以下代码在py3Anaconda 4.3.30、pypdf2-1.26.0 生成的子文件保存在本脚本文件所在的目录下 ''' from PyPDF2 import PdfFileReader, PdfFileWriter def pdf_splitter(path,start,end): pdf = PdfFileReader(path) pdf_writer =PdfFileWriter() output_filename ='page_{}.pdf'.format(end+300) for page inrange(start,end): pdf_writer.addPage(pdf.getPage(page)) print(page) withopen(output_filename,'wb') as out: pdf_writer.write(out) print('Created:{}'.format(output_filename)) path = 'F:/a/301368.pdf' pageNum=68#文件的尾页页数 for i in range(pageNum): pdf_splitter(path,i,i+1) 2、pdf能否正常被搜索。若能,pyPDF2可通过PdfFileReader正常导出文本,否则可以OCR,或者pdf转word,再从word转到txt,进入Delphi查询。 from PyPDF2 import PdfFileReader filename = 'F:/a/PT/page_2.pdf' pdf = PdfFileReader(open(filename, "rb")) pageNum=pdf.getNumPages() text='' for i in range(0, pageNum): text+=pdf.getPage(i).extractText() print(text) 3、Excel重复行、重复列的判断。排序,上或下错开1行,或错开1列,if。略。 4、Delphi拼接每笔资料,并生成pdf文件。 先python生成pdf文件,留出来标识,Delphi通过标识,读取csv,重命名文件。 uses FileCtrl; procedure TForm1.Button1Click(Sender: TObject); var txtFile: TextFile; s: string; begin AssignFile(txtFile, 'F:\a\XLS_idname.txt'); Reset(txtFile); while not eof(txtFile) do begin readln(txtFile, s); //读取一行保存到字符串s中 //if pos('标识号',s)<>0then Memo1.Lines.Add(s); //在Memo1中显示 end; end; procedure TForm1.Button2Click(Sender: TObject); begin FileListBox1.Directory :='F:\a\b'; end; procedure TForm1.Button3Click(Sender: TObject); var myf, Newf: string; i, j: integer; begin //重命名开始 for i := 0 toFileListBox1.Items.Count - 1 do begin myf :=FileListBox1.Items[i]; //找组名和名称 for j := 0 tomemo1.Lines.Count - 1 do begin if pos(LeftStr(myf, 8),memo1.Lines[j]) <> 0 then break; end; Newf :=StringReplace(memo1.Lines[j], ',', '-', [rfReplaceAll]); ReNameFile('F:\a\b\' +myf, 'F:\a\c\' + Newf + '.pdf'); sleep(50);//给点儿写磁盘时间 end; showmessage('OK!'); end; 四、几点讨论 1、非图片版的pdf就一定能提取其中的文本吗?感觉是不一定!尽管中英文各种网络中介绍各种方法处理pdf的文字提取问题,但是,确实是碰到了提取不了的情况。提取出来的文字,不是特殊编码,也并非全是乱码,查询N久,没解决,挺困惑。 2、不是一定图片版的pdf才需要OCR,这个不用解释了。 3、为什么不用python一撸到底?在python语言大行其道的今天,python几乎无所不能了,但还存在一个熟悉程度的问题。Delphi太熟悉了,同等工作量,当然熟悉的工具最快了。而且,python写GUI在一个老Delphier面前,弱爆了。 |
|
来自: 新用户5228KeDY > 《待分类》