基于Python实现PDF区域文本提取工具

IT技术 稻草人 4个月前 (10-12) 71次浏览 已收录 0个评论 扫描二维码

pre{overflow-x: auto}功能简介

打开软件后界面如下:

点击打开文件按钮打开之前的PDF文件后效果如下:

框选区域后,标题栏会自动显示当前框选的区域提取到的文字,还可以左右按钮切换:

实际我们需要提取文字的区域可能不止这一个,所以程序支持多区域框选:

完成区域框选后就可以点击保存文件,将PDF每页提取到的文本保存到一个csv文件中,当前选区的保存结果如下:

可以看到已经按框选顺序依次保存了每一个区域的字符串。

如果选择区域时发现提取结果不准确,可以撤销后重新选择:

保存图片则会将PDF的每页的整体保存为一张图片,未选择区域时,以页码为文件名保存图片:

选择区域时,会自动提取最后一个区域提取的文本作为当前页的文件名:

开发代码

当然这个项目由于本人是一次使用wxpython,功能非常简约,现在将完整代码开源出来期待各位大佬的改进。

源码和已编译工具下载地址:

https://codechina.csdn.net/as604049322/python_gui

完整代码:

"""小小明的代码CSDN主页:https://blog.csdn.net/as604049322"""__author__ = '小小明'__time__ = '2021/11/24'import csvimport wximport osimport fitzclass MyCanvas(wx.Panel):    def __init__(self, parent):        wx.Panel.__init__(self, parent)        self.parent = parent        self.rects = []        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftButtonEvent)        self.Bind(wx.EVT_LEFT_UP, self.OnLeftButtonEvent)        self.Bind(wx.EVT_MOTION, self.OnLeftButtonEvent)        self.Bind(wx.EVT_PAINT, self.DoDrawing)        b = wx.Button(self, -1, "打开文件", (0, 0))        self.Bind(wx.EVT_BUTTON, self.OnButton, b)        b = wx.Button(self, -1, "保存文件", (75, 0))        self.Bind(wx.EVT_BUTTON, self.save_file, b)        b = wx.Button(self, -1, "保存图片", (150, 0))        self.Bind(wx.EVT_BUTTON, self.save_img, b)        b = wx.Button(self, -1, "撤销选区", (225, 0))        self.Bind(wx.EVT_BUTTON, self.back_select, b)        b = wx.Button(self, -1, "《", (300, 0), size=(25, 25))        self.Bind(wx.EVT_BUTTON, self.previous, b)        b = wx.Button(self, -1, "》", (325, 0), size=(25, 25))        self.Bind(wx.EVT_BUTTON, self.next, b)        self.g1 = wx.Gauge(self, -1, 100, (0, 30), (-1, 100), wx.GA_VERTICAL)    def previous(self, evt):        if not hasattr(self, "pdfDoc"):            return        if self.i > 0:            self.i -= 1            self.change_pdf_page(self.i, False)            self.DoDrawing(-1)            if self.rects:                self.parent.SetTitle(self.path + "|" + self.extract_pdf_text())    def next(self, evt):        if not hasattr(self, "pdfDoc"):            return        if self.i 3d}"                pix.save(f"{path}/{name}.png")                self.g1.SetValue((i + 1) * 100 // self.pdfDoc.pageCount)        dlg.Destroy()        os.system(f"explorer {path}")    def save_file(self, evt):        if not hasattr(self, "pdfDoc"):            return        path = self.save_FileDialog()        if path is None:            return        data = []        for i in range(self.pdfDoc.pageCount):            page = self.pdfDoc[i]            row = [self.extract_pdf_text(page, rect)                   for i, rect in enumerate(self.rects)]            data.append(row)        with open(path, "w") as f:            writer = csv.writer(f, lineterminator="\n")            row = [f"区域{i}" for i in range(1, len(row) + 1)]            writer.writerow(row)            for row in data:                writer.writerow(row)        os.system(f"cmd /c start {path}")    def extract_pdf_text(self, page=None, rect=None):        if page is None:            page = self.pdfDoc[self.i]        if rect is None:            rect = self.rects[-1]        a, b, c, d = rect        clip = fitz.Rect(a, b, a + c, b + d)        text = page.get_text(clip=clip).strip()        return text    def change_img(self, img_path, move=True):        self.bmp = wx.Bitmap(img_path)        self.SetSize(self.bmp.GetSize())        self.parent.SetSize(self.parent.GetBestSize())        if move:            self.parent.Center()    def DoDrawing(self, evt):        if not hasattr(self, "bmp"):            return        dc = wx.ClientDC(self)        dc.DrawBitmap(self.bmp, 0, 0, True)        dc.SetPen(wx.Pen('blue'))        dc.SetBrush(wx.Brush('white', wx.BRUSHSTYLE_TRANSPARENT))        dc.DrawRectangleList(self.rects)    def OnLeftButtonEvent(self, event):        if event.LeftDown():            self.x, self.y = event.GetPosition()            self.rects.append([self.x, self.y, 0, 0])        elif event.Dragging():            x, y = event.GetPosition()            self.rects[-1][2] = x - self.x            self.rects[-1][3] = y - self.y            self.DoDrawing(-1)        elif event.LeftUp():            print(self.rects)            if self.rects[-1][2] < 5 or self.rects[-1][3] < 5:                self.rects.pop()            else:                self.parent.SetTitle(self.path + "|" + self.extract_pdf_text())app = wx.App()frm = wx.Frame(None)pnl = MyCanvas(frm)frm.Center()frm.Show()frm.SetTitle("PDF文本提取器")app.MainLoop()

喜欢 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址