You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python提取PDF订单仅捕获首个产品及CSV导出乱码问题求解

PDF订单解析问题解决方案

问题1:仅能提取每页首个产品的修复

根本原因

  • 原代码的公共字段(PO、交货日期、PO日期、收货地址)和产品字段的存储逻辑错误:遍历完一页所有行后才生成1条记录,只会保留最后匹配到的产品信息,多条产品数据被覆盖
  • PODate的判断分支和PO的匹配条件完全一致,永远不会触发,无法正确提取PO日期

修复方案

  • 每页遍历前初始化公共字段变量,匹配到对应内容时赋值
  • 每匹配到一条产品行,立即用当前已赋值的公共字段+当前产品字段生成记录,追加到结果列表
  • 修正PODate的匹配规则,避免和PO的匹配条件冲突

问题2:CSV导出非英文字符乱码/空格异常修复

根本原因

  • 默认导出CSV使用的编码不支持越南语字符,普通UTF-8编码在Windows平台的Excel中打开会出现乱码
  • 提取的文本未做空白字符清理,保留了PDF解析出来的多余不可见空白

修复方案

  • 导出CSV时指定encoding='utf-8-sig',带BOM的UTF-8编码可被绝大多数表格工具正确识别
  • 提取每个字段后调用strip()清理前后空白,必要时用正则替换连续空白为单个空格

修正后完整代码

import re
import pdfplumber
import pandas as pd
from collections import namedtuple

path = "/Users/mymacbook/Downloads/onefolder/123.pdf"
Line = namedtuple('Line', 'PO DeliveryDate PODate ShipTo Barcode Description SMCode Quantity Price')

# 正则规则可根据实际PDF文本内容微调
PO_re = re.compile(r'(\d+\.\d+).+(\d{2}\.\d{2}\.\d{4})')
ord_re = re.compile(r'(\d+) (.*) (\d{5,6}) (\d+\,\d+) (\d+\,\d+)')
ShipTo_re = re.compile(r'(\w+) (Company Name MM) (.*)')
PODate_re = re.compile(r'PO Date.*?(\d{1,2}\.\d{1,2}\.\d{4})') # 调整为匹配PO Date开头的行,避免和第一个正则冲突

lines = []

with pdfplumber.open(path) as pdf:
    for page in pdf.pages:
        text = page.extract_text()
        # 每页初始化公共字段
        PO = DeliveryDate = PODate = ShipTo = None
        for line in text.split('\n'):
            line = line.strip()
            if not line:
                continue
            # 匹配PO和交货日期
            po_match = PO_re.search(line)
            if po_match and not PO: # 避免同页重复匹配
                PO = po_match.group(1).strip()
                DeliveryDate = po_match.group(2).strip()
                continue
            # 匹配PO日期
            podate_match = PODate_re.search(line)
            if podate_match and not PODate:
                PODate = podate_match.group(1).strip()
                continue
            # 匹配收货地址
            if line.startswith('Name', 30) and not ShipTo:
                ShipTo = line.split(' Name ')[-1].strip()
                continue
            # 匹配产品行,匹配到就生成记录
            ord_match = ord_re.search(line)
            if ord_match:
                haha = ord_match.group(1).strip()
                Barcode = haha[-13:]
                Description = ord_match.group(2).strip()
                # 清理描述里的多余空格
                Description = re.sub(r'\s+', ' ', Description)
                SMCode = ord_match.group(3).strip()
                Quantity = ord_match.group(4).strip()
                Price = ord_match.group(5).strip()
                # 公共字段都匹配到再生成记录,避免空值
                if all([PO, DeliveryDate, PODate, ShipTo]):
                    lines.append(Line(PO, DeliveryDate, PODate, ShipTo, Barcode, Description, SMCode, Quantity, Price))

# 生成DataFrame
df = pd.DataFrame(lines)

# 导出CSV,指定编码解决乱码
df.to_csv('订单汇总.csv', index=False, encoding='utf-8-sig')

内容的提问来源于stack exchange,提问作者mng2109

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 14:36:02