拼多多订单导出表格:36 个字段的划分逻辑与 3 个格式坑,开发多多开票助手过程经验分享

2 阅读11分钟

一、先说这份 CSV表格 是什么

我自己在做一个浏览器扩展,叫多多开票助手,用来处理拼多多买家侧的订单和发票,订单导出是其中一块功能。这篇文章讲实现过程中绕不过去的几件事:CSV 这个格式本身有什么先天缺陷,36 个字段为什么这么分,以及一份语法完全正确的 CSV,为什么用 Excel 打开之后会变成错的。

字段清单和踩坑记录来自实际代码,不是抄的文档。

二、CSV 没有类型,也没有编码声明

CSV(Comma-Separated Values)是一种用纯文本存表格数据的格式,字段之间用分隔符隔开,一行一条记录。规范里没有位置可以声明数据类型,也没有位置声明字符编码。这两件事直接导致了后面所有的坑。

**所有值都是字符串。**一个 18 位的订单号、一句话、一个日期,在这份文件里地位一样,都是一串字符。至于"这是数字""这是日期",全靠打开它的软件自己猜。不同软件猜法不同,这就是问题的源头。

**文件不知道自己是什么编码。**Windows 上的 Excel 双击打开 CSV 时,会按系统 ANSI 编码解码,简体中文环境下就是 GBK。文件实际是 UTF-8 写的,中文就全乱。处理办法是在文件最前面放三个字节 EF BB BF,也就是 UTF-8 BOM,Excel 看到这个标记就按 UTF-8 处理:

const BOM = '\ufeff';
const csv = BOM + rows.join('\n');
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });

BOM 不是 CSV 标准的一部分,是 Windows 系软件的识别习惯。代价是文件开头多了三个不可见的字节,如果用脚本去解析这份 CSV,第一个表头会带上一个零宽字符,需要自己剥掉。我现在的做法是导出时一律带 BOM,因为双击打开的人远多于写脚本解析的人。

三、36 个字段,按什么分五组

字段不是拍脑袋凑的,是按"拿到这张表的人要拿它干什么"归的类。五组分别是订单主干、商品与店铺、收货信息、物流轨迹、退款与备注。

第一组:订单主干(1 至 11 列)

序号字段名说明
1拼多多账号当前绑定的买家账号昵称,多账号场景用来区分来源
2商品主图图片地址,表格里基本不看
3订单号唯一标识,和商家、客服、财务对接都靠它
4下单时间排序、按月切分用
5订单金额实付金额,对账主字段
6支付方式支付渠道
7支付时间和下单时间分开,跨天支付能看出来
8订单状态待发货、已发货、已签收这类
9发票状态有没有申请过、开没开出来
10发票下载状态电子发票有没有下载过
11发票下载时间什么时候下载的

第 10、11 列要单独说明一下:这两列不是平台返回的字段,是扩展在本机记录的下载历史。你换了电脑或者清了浏览器数据,这两列就是空的,而平台上的发票其实早开好了。导出表跟平台对不上时,先想到这个原因。

第二组:商品与店铺(12 至 21 列)

序号字段名说明
12商品名称采购明细里的品名
13商品链接按商品 ID 拼出来的,商品下架后可能失效
14商品ID比名称稳的标识,同名商品靠它区分
15规格颜色尺码这类
16规格ID规格的唯一标识
17数量采购件数
18单价金额除以数量算出来的,不是平台给的字段
19拼单链接带规格和数量的下单直达地址
20店铺名称按店铺归类的主字段
21店铺链接按店铺路径拼出来的地址

第 13、19、21 列都是拼出来的,不是平台原样返回的。所以它们的格式是扩展定死的,页面改版后可能失效。真正需要长期留存的是商品 ID 和店铺名称。

第三组:收货信息(22 至 25 列)

序号字段名说明
22收件人缺值时填「未知」
23收货电话同上
24收货地址多仓或多收货点时用来区分货发到哪
25上游系统识别码目前是空的,留给对接内部 ERP 用

第 25 列现在恒为空值。它是预留位,想着以后订单能带上内部系统编号的话就填这儿。至今没用上,但表头留着,免得以后加列的时候下游对接的表全要跟着改。这种预留列在实际业务里很常见,导出表拿到手发现有列是空的,不一定就是坏了。

第四组:物流轨迹(26 至 32 列)

序号字段名说明
26物流公司快递方
27物流单号查物流、跟售后对接
28发货时间做供应商时效评估用
29签收时间账期起算点,也用来判断补开票的窗口
30取件码驿站取件用
31最后轨迹最新一条物流状态文本
32最后轨迹时间那条状态的时间

第 31、32 列有优先级:先取平台订单接口返回的最新物流状态,取不到才退回轨迹列表的最后一条。所以这两列可能有值,而同一行的详细轨迹是空的。

第五组:退款与备注(33 至 36 列)

序号字段名说明
33退款原因有退款才有值
34申请金额售后申请的金额
35申请时间售后发起的时间
36订单备注下单时自己填的

36 列里日常真正会看的大概十来列,剩下的是备用。备用字段的价值在于事后追查:等你要做供应商评估或者退货分析的时候,重新导一遍历史订单往往已经拿不到当时的状态了。

四、坑一:订单号被 Excel 改成了科学计数法

订单号十八位左右,全是数字。Excel 把所有数字按 IEEE 754 双精度浮点处理,有效精度 15 位。所以后三位会被舍入成 0,单元格显示成 1.23457E+18 这种样子。

这个错误不可逆。就算你事后把单元格格式改成文本,丢掉的那几位也回不来,因为存进去的时候就已经是另一个数了。重新导一份是唯一的办法。

两条路可以走:一是用「数据」菜单里的「从文本/CSV」导入,在向导里把订单号那一列手动指定成文本类型;二是在导出的时候就把它写成文本形式,也就是 ="123456789012345678" 这种写法。

我选了第二条,理由是双击打开 CSV 的人占绝大多数,指望每个人每次走导入向导不现实。代价也很明确:="..." 是 Excel 的公式语法,不是通用写法。WPS 表格和 Google Sheets 对它支持不一致,用 pandas 读的时候拿到的是字面量 ="123456789012345678",得自己剥掉外层。

// 纯数字且长度 >= 10 的字段,按 Excel 文本写入
if (/^\d+$/.test(s) && s.length >= 10) return `="${s}"`;

如果你的下游流程是脚本解析而不是人眼看,那这个处理反而给你添了麻烦,可以在导出后统一处理一遍。

五、坑二:字段里的逗号和换行

CSV 用逗号分隔字段。商品名本身带逗号的话,比如「收纳盒,中号,两只装」,一个名称就占掉了三个字段的位置,后面所有列整体右移,整行错位。

RFC 4180 规定的标准做法是用双引号把字段包起来,字段内部的双引号写成两个。我的实现在这个基础上多做了一步:把字段内部的半角逗号替换成全角逗号,再整体包引号。

const escaped = s.replace(/"/g, '""').replace(/,/g, ',');
return `"${escaped}"`;

这么做的问题是它改了原始数据。导出表里的商品名和平台上显示的不是同一个字符串,你在 Excel 里按商品名做匹配的时候,得按全角逗号写才匹配得上。现在回头看,这一步是多余且有害的,只用引号包裹就够了,字符替换完全可以不做。当时加它是因为遇到过某个表格软件对引号内逗号处理不好,用替换绕过去了,后来发现那是旧版本的问题。

引号包裹还解决另一个情况:字段内部有换行。物流详细轨迹是多行文本,包在引号里就是合法的单字段,不包的换行会被当成记录结束。

六、坑三:行尾用了 LF 而不是 CRLF

RFC 4180 规定行尾是 \r\n,我的实现是 rows.join('\n'),只有 LF。

主流的表格软件和编辑器都能容忍,Excel、WPS、LibreOffice 打开都正常。但极老的 Windows 工具会把整份文件当成一行显示,部分工业软件和老的 ERP 导入模块也会挑这个。如果导出文件要喂给这类系统,得在生成的时候换成 CRLF。

这是我知道但没有改的地方,因为改了对现有使用者没有任何收益,反而多一次回归测试。写出来是给有对接需求的人提个醒。

七、另外一件事:导出的是快照

导出的表是导出那一刻的数据,之后订单状态变化不会同步进去。刚发的货、刚退的款,这份文件里都还是旧值。

所以别把导出文件当数据源反复用。要做长期归档的话,我的习惯是每月导一次,文件名带月份,原始 CSV 留一份不删。等发现哪一列有问题,还能回去查当时到底是什么值。

八、这份表能拿来做什么

三个我自己在用的。

**给财务的对账表。**财务要的核心是三样:订单号、金额、发票状态。按发票状态筛一遍,已开的和没开的分成两块,没开的那块就是要催的清单。

**供应商发货时效。**用发货时间减去下单时间得到每笔的发货时长,再按店铺名称求平均。这个数据不精确,因为发货时间取的是平台记录的时间点,但横向比较不同供应商的相对快慢是够用的。

**退货集中度。**按退款原因分组,看退货是集中在某个商品还是某个规格上。一年看一次就够了。

九、常见问题

导出的文件和平台上的数据会不一致吗?

会。导出的是导出那一刻的快照,之后的状态变化不会同步。要最新的就重新导一份。另外「发票下载状态」和「发票下载时间」是本机记录,换电脑后会丢。

订单号已经变成科学计数法了,能恢复吗?

不能。Excel 存进去的时候就已经是另一个数了,改格式也找不回来。只能重新导,并且这次用导入向导指定文本,或者改用带 ="..." 标记的写法。

能直接导出成 xlsx 吗?

目前导出的是 CSV,用 Excel 打开另存一次就成 xlsx 了。直接生成 xlsx 需要在扩展里打包一个表格库,体积会涨不少,为了省一次另存不划算。

商品名里的逗号为什么变成全角了?

是导出时的替换处理。见第五节,现在看这一步做得不必要,但已经这样发了,改的话会让老用户的匹配规则失效,所以留着。

这个字段清单会变吗?

会。平台加字段或改字段含义的时候,导出的表会跟着变。以你实际导出文件里的表头为准。

十、小结

订单导出这件事,动作本身没什么可讲的,难点全在数据离开页面之后:编码靠约定、类型靠猜、精度靠软件的习惯、字段含义靠上游接口给什么。CSV 是个四十多年前的格式,它的简单既让它到处都能打开,也让它什么都不能保证。

我做的这个扩展叫多多开票助手,订单同步、发票申请、发票下载和导出是一套流程,导出只是其中一块。如果只需要导出这一个功能,也可以自己用脚本读接口数据生成 CSV,把上面几个坑按各自的场景处理掉就行。


关键词:拼多多订单导出,CSV 字段说明,订单数据导出,Excel 打开 CSV 乱码,浏览器扩展