• Python 读取电子发票PDF 转成Excel


    Python 读取电子发票PDF 转成Excel

    目录

    0.前提

    1.python相关的处理PDF的库

    2.实际好用的

    3.实际代码        

    4.思考


    0.前提

            只识别普通电子发票PDF,提取其中某些关键内容到excel中。

    1.python相关的处理PDF的库

            如下4个库是经常更新维护的!

            pyPDF/pyPDF2、pdfplumber、PyMuPDF、Camelot等4个库。

    2.实际好用的

            个人推荐pdfplumber,它有extract_tables函数

    3.实际代码        

    1. import pdfplumber
    2. import re
    3. import os
    4. import pandas as pd
    5. '''
    6. 处理 普通发票电子PDF 提取关键字段内容信息写入excel中
    7. 其它类的发票 自己参考对应规律 更改代码即可
    8. 参考:pdfplumber官网、以及:https://blog.csdn.net/Burannnn/article/details/129393295
    9. '''
    10. def re_text(bt, text):
    11. # re 搜索正则匹配 包含re.compile包含的文字内容
    12. m1 = re.search(bt, text)
    13. if m1 is not None:
    14. return re_block(m1[0])
    15. return None
    16. def re_block(text):
    17. # 去掉空格、中英文小括号、中文冒号变英文冒号;去掉中文全角空格
    18. return text.replace(' ', '').replace(' ', '').replace(')', '').replace(')', '').replace(':', ':')
    19. def get_pdf(dir_path):
    20. pdf_file = []
    21. for root, sub_dirs, file_names in os.walk(dir_path):
    22. for name in file_names:
    23. if name.endswith('.pdf'):
    24. filepath = os.path.join(root, name)
    25. pdf_file.append(filepath)
    26. return pdf_file
    27. def read(xlsx_path, pdf_root):
    28. # 构建excel writer 写入器
    29. writer = pd.ExcelWriter(xlsx_path)
    30. # 如果字段不通用 则需要单独拎出来判断,这里我全部拎出来做了if判断
    31. all_fields = {
    32. "开票日期": [],
    33. "名称": [],
    34. "纳税人识别号": [],
    35. "价税合计(小写)": [],
    36. "货物或应税劳务、服务名称": [],
    37. "规格型号": [],
    38. "单位": [],
    39. "数量": [],
    40. "单价": [],
    41. "金额": [],
    42. "税率": [],
    43. "税额": [],
    44. }
    45. filenames = get_pdf(pdf_root)
    46. for filename in filenames:
    47. print(f"正在读取:{filename}")
    48. with pdfplumber.open(filename) as pdf:
    49. first_page = pdf.pages[0]
    50. pdf_text = first_page.extract_text()
    51. # print(pdf_text)
    52. kaipiao = re_text(re.compile(r'开票日期(.*)'), pdf_text)
    53. if kaipiao:
    54. all_fields["开票日期"].append(kaipiao.replace("开票日期:", ""))
    55. mingcheng = re_text(re.compile(r'名\s*称\s*[::]\s*([\u4e00-\u9fa5]+)'), pdf_text)
    56. if mingcheng:
    57. all_fields["名称"].append(mingcheng.replace("名称:", ""))
    58. # nashuiren = re_text(re.compile(r'纳税人识别号\s*[::]\s*([a-zA-Z0-9]+)'), pdf_text)
    59. # if nashuiren:
    60. # all_fields["纳税人识别号"].append(nashuiren.replace("纳税人识别号:", ""))
    61. jine = re_text(re.compile(r'小写.*(.*[0-9.]+)'), pdf_text)
    62. if jine:
    63. all_fields["价税合计(小写)"].append(jine.replace("小写¥", ""))
    64. table = first_page.extract_tables()[0]
    65. # 纳税人识别号 购买方
    66. for t in table[0]:
    67. t_ = str(t).replace(" ", "")
    68. nashuiren = re_text(re.compile(r'纳税人识别号\s*[::]\s*([a-zA-Z0-9]+)'), t_)
    69. if nashuiren:
    70. all_fields["纳税人识别号"].append(nashuiren.replace("纳税人识别号:", ""))
    71. # 这里根据pdfplumber提取table来依次输出,查看规律(适合普通发票,其它发票打印输出看规律即可)
    72. for t in table[1]:
    73. if not t:
    74. continue
    75. t_ = str(t).replace(" ", "") # 去掉空格
    76. ts = t_.split("\n")
    77. if "货物或应税劳务、服务名称" in t_:
    78. if len(ts) > 1:
    79. all_fields["货物或应税劳务、服务名称"].append(ts[1])
    80. else:
    81. all_fields["货物或应税劳务、服务名称"].append("")
    82. if "规格型号" in t_:
    83. if len(ts) > 1:
    84. all_fields["规格型号"].append(ts[1])
    85. else:
    86. all_fields["规格型号"].append("")
    87. if "单位" in t_:
    88. if len(ts) > 1:
    89. all_fields["单位"].append(ts[1])
    90. else:
    91. all_fields["单位"].append("")
    92. if "数量" in t_:
    93. if len(ts) > 1:
    94. all_fields["数量"].append(ts[1])
    95. else:
    96. all_fields["数量"].append("")
    97. if "单价" in t_:
    98. if len(ts) > 1:
    99. all_fields["单价"].append(ts[1])
    100. else:
    101. all_fields["单价"].append("")
    102. if "税率" in t_:
    103. if len(ts) > 1:
    104. all_fields["税率"].append(ts[1])
    105. else:
    106. all_fields["税率"].append("")
    107. if "金额" in t_:
    108. if len(ts) > 1:
    109. all_fields["金额"].append(ts[1])
    110. else:
    111. all_fields["金额"].append("")
    112. if "税额" in t_:
    113. if len(ts) > 1:
    114. all_fields["税额"].append(ts[1])
    115. else:
    116. all_fields["税额"].append("")
    117. # print('--------------------------------------------------------')
    118. # print(re_text(re.compile(r'[\u4e00-\u9fa5]+电子普通发票.*?'), pdf_text))
    119. # # print(re_text(re.compile(r'发票代码(.*\d+)'), pdf_text))
    120. # print(re_text(re.compile(r'发票号码(.*\d+)'), pdf_text))
    121. # print(re_text(re.compile(r'开票日期(.*)'), pdf_text))
    122. # print(re_text(re.compile(r'名\s*称\s*[::]\s*([\u4e00-\u9fa5]+)'), pdf_text))
    123. # print(re_text(re.compile(r'纳税人识别号\s*[::]\s*([a-zA-Z0-9]+)'), pdf_text))
    124. # price = re_text(re.compile(r'小写.*(.*[0-9.]+)'), pdf_text)
    125. # print(price)
    126. # company = re.findall(re.compile(r'名.*称\s*[::]\s*([\u4e00-\u9fa5]+)'), pdf_text)
    127. # if company:
    128. # print(re_block(company[len(company)-1]))
    129. # print('--------------------------------------------------------')
    130. print(all_fields)
    131. df = pd.DataFrame(all_fields)
    132. df.to_excel(writer)
    133. writer.save()
    134. return
    135. pdf_root = r"G:\PDF"
    136. xlsx_path = r"G:\PDF\all_fields.xlsx"
    137. read(xlsx_path, pdf_root)

    4.思考

            对于专用发票,找到对应的规律即可。这里最好用的是extract_tables函数,打印出来,找规律即可!

  • 相关阅读:
    【代码随想录训练营】Day52-动态规划
    5种基本类型之外的数据类型是object——对象、添加、读取
    【考研数学】概率论与数理统计 —— 第三章 | 二维随机变量及其分布(2,常见的二维随机变量及二维变量的条件分布和独立性)
    WCET学习(六)
    Ubuntu22.04如何开机重新自动运行脚本
    Android---屏幕适配的处理技巧
    STM32前言知识总结
    PyTorch多GPU训练时同步梯度是mean还是sum?
    【时间序列预测】Informer论文笔记
    linux文件组 avc: denied { dac_read_search } for capability=2
  • 原文地址:https://blog.csdn.net/LEILEI18A/article/details/134770496