【问题标题】:Python: Extract text from multiple pdf and paste on excelPython:从多个pdf中提取文本并粘贴到excel上
【发布时间】:2023-01-17 15:09:58
【问题描述】:

我是 python 的新手,你能帮我更正这段代码吗?

我想补充两件事:

  1. 对多个 pdf 进行操作,而不仅仅是一个并将内容粘贴到 A2、A3 A4 等
  2. 如果可能,请在另一行 (B2,B3,B4) 中写入 pdf 文件的名称。

    提前谢谢你,这是我正在使用的代码

    import PyPDF2
    import openpyxl
    pdfFileObj = open("file.pdf", 'rb')
    pdfReader = PyPDF2.PdfFileReader(pdfFileObj)
    pdfReader.numPages
    
    pageObj = pdfReader.getPage(0)
    mytext = pageObj.extractText()
    wb = openpyxl.load_workbook('excel.xlsx')
    sheet = wb.active
    sheet.title = 'MyPDF'
    sheet['A1'] = mytext
    
    wb.save('excel.xlsx')
    print('DONE!!')
    
    

    我已经按照建议修改了代码,循环似乎得到了所有页面!但也许我必须使用 "sheet[f'A{row}'].value = '\n'.join(output)" 因为它似乎打印了很多空格

    
    import PyPDF2
    import openpyxl
    import os
    import glob
    root_dir = "your directory"
    
    filenames = []
    # root_dir needs a trailing slash (i.e. /root/dir/)
    for filename in glob.iglob(root_dir + '**/**', recursive=True):
        if filename.lower().endswith('.pdf'):
            filenames.append(os.path.join(directory, filename))
            
    
    wb = openpyxl.load_workbook('excel.xlsx')#your file excel
    sheet = wb.active
    sheet.title = 'MyPDF'
    
    for row, filename in enumerate(filenames, start=1):
        with open(filename, 'rb') as f:
            pdfReader = PyPDF2.PdfFileReader(f)
            count=pdfReader.numPages
            pageObj = pdfReader.getPage(0)
            mytext = pageObj.extractText()
            for i in range(count): 
                page = pdfReader.getPage(i)
                output = []
                output = page.extractText() 
                print(output)
    
        sheet[f'A{row}'].value = '\n'.join(output)
        sheet[f'B{row}'].value = filename
    
    wb.save('excel.xlsx') #your file excel
    print('DONE!!')
    

【问题讨论】:

    标签: python excel pdf


    【解决方案1】:

    您基本上想将您编写的读取 pdf 文件的代码放入 for 循环中,该循环遍历文件名(在这种情况下,文件名存储为 tuple)。

    使用enumeraterow 循环的每次迭代递增,并从 1 开始。因此文本和文件名将被放入 A1 和 B1,然后是 A2 和 B2,依此类推。

    import PyPDF2
    import openpyxl
    
    filenames = ("file.pdf", 
                 "file2.pdf", 
                 "file3.pdf", 
                )
    
    wb = openpyxl.load_workbook('excel.xlsx')
    sheet = wb.active
    sheet.title = 'MyPDF'
    
    for row, filename in enumerate(filenames, start=1):
        with open(filename, 'rb') as f:
            pdfReader = PyPDF2.PdfFileReader(f)
            pdfReader.numPages
            pageObj = pdfReader.getPage(0)
            mytext = pageObj.extractText()
        
        sheet[f'A{row}'].value = mytext
        sheet[f'B{row}'].value = filename
    
    wb.save('excel.xlsx')
    print('DONE!!')
    

    通过遍历目录中的所有文件并检查文件名是否以 .pdf 结尾,您可以很容易地获得以 .pdf 结尾的所有文件名的列表。如果是,请使用os.path.join 为您提供完整的文件路径,并将其附加到filenames 列表中。

    您也可以使用 glob 模块。

    import os
    
    filenames = []
    directory = r"C:StuffPDF Files"
    for filename in os.listdir(directory):
        if filename.lower().endswith(".pdf"):
            filenames.append(os.path.join(directory, filename))
    

    更新代码:

    import PyPDF2
    import openpyxl
    import os
    import glob
    import re
    import itertools
    
    # Used to strip characters that can't be written to a spreadsheet
    # See https://stackoverflow.com/a/93029/3589122
    control_chars = ''.join(map(chr, itertools.chain(range(0x00,0x20), range(0x7f,0xa0))))
    control_char_re = re.compile('[%s]' % re.escape(control_chars))
    
    def remove_control_chars(s):
        return control_char_re.sub('', s)
    
    root_dir = 'your directory' # root_dir needs a trailing slash (i.e. /root/dir/)
    
    filenames = (filename for filename in glob.iglob(root_dir + '/**/*.pdf', recursive=True))
    
    wb = openpyxl.load_workbook('excel.xlsx') # your file excel
    sheet = wb.active
    sheet.title = 'MyPDF'
    
    row = 1
    for filename in filenames:
        with open(filename, 'rb') as f:
            try:
                pdfReader = PyPDF2.PdfFileReader(f)
                count = pdfReader.numPages
                
                output = []
                for i in range(count): 
                    print(i, filename)
                    page = pdfReader.getPage(i)
                    output.append(page.extractText())
                    #print(output)
            except Exception as e:
                print(f'Error: PyPDF2 could not read {filename}. Continuing... ({e})')
                continue
        
        sheet[f'A{row}'].value = '
    '.join(remove_control_chars(output))
        sheet[f'B{row}'].value = filename
        row += 1
    
    wb.save('excel.xlsx') #your file excel
    print('DONE!!')
    

    【讨论】:

    • 感谢您的回答 GordonAitchJay,有一种方法可以“自动”获取文件夹中的所有 pdf 而无需命名它们吗?像 *pdf 这样的东西来表示所有以 pdf 结尾的东西?这就是为什么我还想在另一列中添加文件名
    • 你最好相信它!查看更新的答案。
    • 首先感谢您对我的帮助!但是脚本返回一个空文件,如果我打印 mytext 中的内容,我会看到复制文本的一部分,所以问题可能出在尝试将其写下来到 excel 时?
    • 那很奇怪。我现在刚刚尝试过,它对我有用。尝试将 .value 附加到 sheet[f'A{row}']sheet[f'B{row}'],就像 sheet[f'A{row}'].value。请参阅我编辑的答案。
    • 遗憾的是不,它没有粘贴任何东西我不明白为什么我粘贴的代码有效以及为什么你的更好的代码不粘贴任何东西!
    【解决方案2】:

    您是否尝试过超过 6/7 个文件?我在 7 pdf 时收到此错误

    
    TypeError                                 Traceback (most recent call last)
    <ipython-input-14-07fb0aa603b8> in <module>
         23         for i in range(count):
         24             page = pdfReader.getPage(i)
    ---> 25             output.append(page.extractText())
         26             print(output)
         27 
    
    ~naconda3libsite-packagesPyPDF2_page.py in extractText(self, Tj_sep, TJ_sep)
       1283         """
       1284         deprecate_with_replacement("extractText", "extract_text")
    -> 1285         return self.extract_text(Tj_sep=Tj_sep, TJ_sep=TJ_sep)
       1286 
       1287     mediabox = _create_rectangle_accessor(PG.MEDIABOX, ())
    
    ~naconda3libsite-packagesPyPDF2_page.py in extract_text(self, Tj_sep, TJ_sep, space_width)
       1261         :return: a string object.
       1262         """
    -> 1263         return self._extract_text(self, self.pdf, space_width, PG.CONTENTS)
       1264 
       1265     def extract_xform_text(
    
    ~naconda3libsite-packagesPyPDF2_page.py in _extract_text(self, obj, pdf, space_width, content_key)
       1243                     text = ""
       1244             else:
    -> 1245                 process_operation(operator, operands)
       1246         output += text  # just in case of
       1247         return output
    
    ~naconda3libsite-packagesPyPDF2_page.py in process_operation(operator, operands)
       1195                 tm_matrix[5] -= TL
       1196             elif operator == b"Tj":
    -> 1197                 text += operands[0].translate(cmap)
       1198             else:
       1199                 return None
    
    TypeError: a bytes-like object is required, not 'dict'
    
    

    【讨论】:

    • 这是由特定文件(即第 6 个文件)引起的。 PyPDF2 无法提取文本,可能是因为 pdf 文件已损坏,或者因为 PyPDF2 中存在错误。也许尝试更新PyPDF2,或尝试另一个 pdf 库,例如 PyMuPDF - pymupdf.readthedocs.io/en/latest/…
    • 如果做不到这一点,您可以使用 try-except 语句忽略错误。
    • 我按照建议插入了 try-except 语句,但它只是在第一个 6-7 文件之后停止(尝试:for row, filename in enumerate(filenames, start=1): with open(filename, 'rb') as f: pdfReader = PyPDF2.PdfFileReader(f) count = pdfReader.numPages output = [] for i in range(count): page = pdfReader.getPage(i) output.append(page.extractText()) print(output) 除了异常:通过所以我会尝试使用 PyMuPDF 但语法似乎非常不同
    • 所以 PyPDF2 无法读取第 6 个或第 7 个文件。这个文件损坏了吗?您可以在其他应用程序中查看 pdf 吗?然而,因为整个循环都在 try 块中,所以当出现异常时,它会完全退出循环。这就是它在第 6 个或第 7 个文件之后停止的原因。您应该只在 try 块中包含引发异常的代码行。我已经编辑了我的答案,试试看。请注意,我必须删除enumerate 并手动设置和更新row,否则每次 PyPDF2 无法读取文件时,电子表格中都会出现空白。
    • 感谢您一如既往的帮助。我已经尝试删除第 5 个或第 6 个或第 7 个文件,但即使使用 try except (TypeError: a bytes-like object is required, not 'dict') 仍然出现相同的错误。也许当它达到一定程度的文字或 停了吗?
    【解决方案3】:

    我们可以通过浏览 xlsx 文件来总结 pdf 中的数据吗..在 python 中没有任何导入数据.... 我需要从详细信息可用的 excel 数据中制作一个摘要页面......例如每月每季度每年......多年来的变化等......月月,,,

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-11
      • 2016-01-25
      • 1970-01-01
      • 2021-03-31
      • 2015-12-02
      • 2020-04-24
      • 1970-01-01
      • 2021-01-07
      相关资源
      最近更新 更多